Add yardstick.benchmark.contexts.heat.HeatContext._delete_key_file()
[yardstick.git] / yardstick / tests / unit / benchmark / contexts / test_heat.py
1 #!/usr/bin/env python
2
3 ##############################################################################
4 # Copyright (c) 2015 Ericsson AB and others.
5 #
6 # All rights reserved. This program and the accompanying materials
7 # are made available under the terms of the Apache License, Version 2.0
8 # which accompanies this distribution, and is available at
9 # http://www.apache.org/licenses/LICENSE-2.0
10 ##############################################################################
11
12 from collections import OrderedDict
13 from itertools import count
14 import logging
15
16 import mock
17 import unittest
18
19 import shade
20
21 from yardstick.benchmark.contexts import base
22 from yardstick.benchmark.contexts import heat
23 from yardstick.benchmark.contexts import model
24 from yardstick.common import exceptions as y_exc
25 from yardstick.orchestrator import heat as orch_heat
26 from yardstick import ssh
27
28
29 LOG = logging.getLogger(__name__)
30
31
32 class HeatContextTestCase(unittest.TestCase):
33
34     def __init__(self, *args, **kwargs):
35         super(HeatContextTestCase, self).__init__(*args, **kwargs)
36         self.name_iter = ('vnf{:03}'.format(x) for x in count(0, step=3))
37
38     def setUp(self):
39         self.test_context = heat.HeatContext()
40         self.addCleanup(self._remove_contexts)
41         self.mock_context = mock.Mock(spec=heat.HeatContext())
42
43     def _remove_contexts(self):
44         if self.test_context in self.test_context.list:
45             self.test_context._delete_context()
46
47     def test___init__(self):
48         self.assertIsNone(self.test_context._name)
49         self.assertIsNone(self.test_context._task_id)
50         self.assertFalse(self.test_context._flags.no_setup)
51         self.assertFalse(self.test_context._flags.no_teardown)
52         self.assertIsNone(self.test_context.stack)
53         self.assertEqual(self.test_context.networks, OrderedDict())
54         self.assertEqual(self.test_context.servers, [])
55         self.assertEqual(self.test_context.placement_groups, [])
56         self.assertEqual(self.test_context.server_groups, [])
57         self.assertIsNone(self.test_context.keypair_name)
58         self.assertIsNone(self.test_context.secgroup_name)
59         self.assertEqual(self.test_context._server_map, {})
60         self.assertIsNone(self.test_context._image)
61         self.assertIsNone(self.test_context._flavor)
62         self.assertIsNone(self.test_context._user)
63         self.assertIsNone(self.test_context.template_file)
64         self.assertIsNone(self.test_context.heat_parameters)
65         self.assertIsNone(self.test_context.key_filename)
66
67     @mock.patch.object(ssh.SSH, 'gen_keys')
68     @mock.patch('yardstick.benchmark.contexts.heat.PlacementGroup')
69     @mock.patch('yardstick.benchmark.contexts.heat.ServerGroup')
70     @mock.patch('yardstick.benchmark.contexts.heat.Network')
71     @mock.patch('yardstick.benchmark.contexts.heat.Server')
72     def test_init(self, mock_server, mock_network, mock_sg, mock_pg, mock_ssh_gen_keys):
73
74         pgs = {'pgrp1': {'policy': 'availability'}}
75         sgs = {'servergroup1': {'policy': 'affinity'}}
76         networks = {'bar': {'cidr': '10.0.1.0/24'}}
77         servers = {'baz': {'floating_ip': True, 'placement': 'pgrp1'}}
78         attrs = {'name': 'foo',
79                  'task_id': '1234567890',
80                  'placement_groups': pgs,
81                  'server_groups': sgs,
82                  'networks': networks,
83                  'servers': servers}
84
85         self.test_context.init(attrs)
86
87         self.assertFalse(self.test_context._flags.no_setup)
88         self.assertFalse(self.test_context._flags.no_teardown)
89         self.assertEqual(self.test_context._name, "foo")
90         self.assertEqual(self.test_context._task_id, '1234567890')
91         self.assertEqual(self.test_context.name, "foo-12345678")
92         self.assertEqual(self.test_context.keypair_name, "foo-12345678-key")
93         self.assertEqual(self.test_context.secgroup_name, "foo-12345678-secgroup")
94
95         mock_pg.assert_called_with('pgrp1', self.test_context,
96                                    pgs['pgrp1']['policy'])
97         mock_sg.assert_called_with('servergroup1', self.test_context,
98                                    sgs['servergroup1']['policy'])
99         self.assertEqual(len(self.test_context.placement_groups), 1)
100         self.assertEqual(len(self.test_context.server_groups), 1)
101
102         mock_network.assert_called_with(
103             'bar', self.test_context, networks['bar'])
104         self.assertEqual(len(self.test_context.networks), 1)
105
106         mock_server.assert_called_with('baz', self.test_context,
107                                        servers['baz'])
108         self.assertEqual(len(self.test_context.servers), 1)
109
110         mock_ssh_gen_keys.assert_called()
111
112     def test_init_no_name_or_task_id(self):
113         attrs = {}
114         self.assertRaises(KeyError, self.test_context.init, attrs)
115
116     def test_name(self):
117         self.test_context._name = 'foo'
118         self.test_context._task_id = '1234567890'
119         self.test_context._name_task_id = '{}-{}'.format(
120             self.test_context._name, self.test_context._task_id[:8])
121         self.assertEqual(self.test_context.name, 'foo-12345678')
122         self.assertEqual(self.test_context.assigned_name, 'foo')
123
124     def test_name_flags(self):
125         self.test_context._flags = base.Flags(
126             **{"no_setup": True, "no_teardown": True})
127         self.test_context._name = 'foo'
128         self.test_context._task_id = '1234567890'
129
130         self.assertEqual(self.test_context.name, 'foo')
131         self.assertEqual(self.test_context.assigned_name, 'foo')
132
133     @mock.patch('yardstick.ssh.SSH.gen_keys')
134     def test_init_no_setup_no_teardown(self, *args):
135
136         attrs = {'name': 'foo',
137                  'task_id': '1234567890',
138                  'placement_groups': {},
139                  'server_groups': {},
140                  'networks': {},
141                  'servers': {},
142                  'flags': {
143                      'no_setup': True,
144                      'no_teardown': True,
145                      },
146                 }
147
148         self.test_context.init(attrs)
149         self.assertTrue(self.test_context._flags.no_setup)
150         self.assertTrue(self.test_context._flags.no_teardown)
151
152     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
153     def test__add_resources_to_template_no_servers(self, mock_template):
154         self.test_context._name = 'ctx'
155         self.test_context._task_id = '1234567890'
156         self.test_context._name_task_id = '{}-{}'.format(
157             self.test_context._name, self.test_context._task_id[:8])
158         self.test_context.keypair_name = "ctx-key"
159         self.test_context.secgroup_name = "ctx-secgroup"
160         self.test_context.key_uuid = "2f2e4997-0a8e-4eb7-9fa4-f3f8fbbc393b"
161         netattrs = {'cidr': '10.0.0.0/24', 'provider': None,
162                     'external_network': 'ext_net'}
163
164         self.test_context.networks = OrderedDict(
165             {"mynet": model.Network("mynet", self.test_context,
166                                            netattrs)})
167
168         self.test_context._add_resources_to_template(mock_template)
169         mock_template.add_keypair.assert_called_with(
170             "ctx-key",
171             "ctx-12345678")
172         mock_template.add_security_group.assert_called_with("ctx-secgroup")
173         mock_template.add_network.assert_called_with(
174             "ctx-12345678-mynet", 'physnet1', None, None, None, None)
175         mock_template.add_router.assert_called_with(
176             "ctx-12345678-mynet-router",
177             netattrs["external_network"],
178             "ctx-12345678-mynet-subnet")
179         mock_template.add_router_interface.assert_called_with(
180             "ctx-12345678-mynet-router-if0",
181             "ctx-12345678-mynet-router",
182             "ctx-12345678-mynet-subnet")
183
184     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
185     def test_attrs_get(self, *args):
186         image, flavor, user = expected_tuple = 'foo1', 'foo2', 'foo3'
187         self.assertNotEqual(self.test_context.image, image)
188         self.assertNotEqual(self.test_context.flavor, flavor)
189         self.assertNotEqual(self.test_context.user, user)
190         self.test_context._image = image
191         self.test_context._flavor = flavor
192         self.test_context._user = user
193         attr_tuple = self.test_context.image, self.test_context.flavor, self.test_context.user
194         self.assertEqual(attr_tuple, expected_tuple)
195
196     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
197     def test_attrs_set_negative(self, *args):
198         with self.assertRaises(AttributeError):
199             self.test_context.image = 'foo'
200
201         with self.assertRaises(AttributeError):
202             self.test_context.flavor = 'foo'
203
204         with self.assertRaises(AttributeError):
205             self.test_context.user = 'foo'
206
207     def test__create_new_stack(self):
208         template = mock.Mock()
209         self.test_context._create_new_stack(template)
210         template.create.assert_called_once()
211
212     def test__create_new_stack_stack_create_failed(self):
213         template = mock.Mock()
214         template.create.side_effect = y_exc.HeatTemplateError
215
216         self.assertRaises(y_exc.HeatTemplateError,
217                           self.test_context._create_new_stack,
218                           template)
219
220     def test__create_new_stack_keyboard_interrupt(self):
221         template = mock.Mock()
222         template.create.side_effect = KeyboardInterrupt
223         self.assertRaises(y_exc.StackCreationInterrupt,
224                           self.test_context._create_new_stack,
225                           template)
226
227     @mock.patch.object(orch_heat.HeatTemplate, 'add_keypair')
228     @mock.patch.object(heat.HeatContext, '_create_new_stack')
229     def test_deploy_stack_creation_failed(self, mock_create, *args):
230         self.test_context._name = 'foo'
231         self.test_context._task_id = '1234567890'
232         self.test_context._name_task_id = 'foo-12345678'
233         mock_create.side_effect = y_exc.HeatTemplateError
234         self.assertRaises(y_exc.HeatTemplateError,
235                           self.test_context.deploy)
236
237     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
238     def test_deploy(self, mock_template):
239         self.test_context._name = 'foo'
240         self.test_context._task_id = '1234567890'
241         self.test_context._name_task_id = '{}-{}'.format(
242             self.test_context._name, self.test_context._task_id[:8])
243         self.test_context.template_file = '/bar/baz/some-heat-file'
244         self.test_context.heat_parameters = {'image': 'cirros'}
245         self.test_context.get_neutron_info = mock.MagicMock()
246         self.test_context.deploy()
247
248         mock_template.assert_called_with('foo-12345678',
249                                          '/bar/baz/some-heat-file',
250                                          {'image': 'cirros'})
251         self.assertIsNotNone(self.test_context.stack)
252
253     # TODO: patch objects
254     @mock.patch.object(heat, 'HeatTemplate')
255     @mock.patch.object(heat.HeatContext, '_retrieve_existing_stack')
256     @mock.patch.object(heat.HeatContext, '_create_new_stack')
257     def test_deploy_no_setup(self, mock_create_new_stack, mock_retrieve_existing_stack, *args):
258         self.test_context._name = 'foo'
259         self.test_context._task_id = '1234567890'
260         # Might be able to get rid of these
261         self.test_context.template_file = '/bar/baz/some-heat-file'
262         self.test_context.heat_parameters = {'image': 'cirros'}
263         self.test_context.get_neutron_info = mock.MagicMock()
264         self.test_context._flags.no_setup = True
265         self.test_context.deploy()
266
267         # check that heat client is called...
268         mock_create_new_stack.assert_not_called()
269         mock_retrieve_existing_stack.assert_called_with(self.test_context.name)
270         self.assertIsNotNone(self.test_context.stack)
271
272     @mock.patch.object(shade, 'openstack_cloud')
273     @mock.patch.object(heat.HeatTemplate, 'add_keypair')
274     @mock.patch.object(heat.HeatContext, '_create_new_stack')
275     @mock.patch.object(heat.HeatStack, 'get')
276     def test_deploy_try_retrieve_context_does_not_exist(self,
277                                                         mock_get_stack,
278                                                         mock_create_new_stack,
279                                                         *args):
280         self.test_context._name = 'demo'
281         self.test_context._task_id = '1234567890'
282         self.test_context._flags.no_setup = True
283         self.test_context.get_neutron_info = mock.MagicMock()
284
285         # TODo: Check is this the right value to return, should it be None instead?
286         mock_get_stack.return_value = []
287
288         self.test_context.deploy()
289
290         mock_get_stack.assert_called()
291         mock_create_new_stack.assert_called()
292
293     def test_check_for_context(self):
294         pass
295         # check that the context exists
296
297     def test_add_server_port(self):
298         network1 = mock.MagicMock()
299         network2 = mock.MagicMock()
300         self.test_context._name = 'foo'
301         self.test_context._task_id = '1234567890'
302         self.test_context._name_task_id = '{}-{}'.format(
303             self.test_context._name, self.test_context._task_id[:8])
304         self.test_context.stack = mock.MagicMock()
305         self.test_context.networks = {
306             'a': network1,
307             'c': network2,
308         }
309         self.test_context.stack.outputs = {
310             u'b': u'10.20.30.45',
311             u'b-subnet_id': 1,
312             u'foo-12345678-a-subnet-cidr': u'10.20.0.0/15',
313             u'foo-12345678-a-subnet-gateway_ip': u'10.20.30.1',
314             u'b-mac_address': u'00:01',
315             u'b-device_id': u'dev21',
316             u'b-network_id': u'net789',
317             u'd': u'40.30.20.15',
318             u'd-subnet_id': 2,
319             u'foo-12345678-c-subnet-cidr': u'40.30.0.0/18',
320             u'foo-12345678-c-subnet-gateway_ip': u'40.30.20.254',
321             u'd-mac_address': u'00:10',
322             u'd-device_id': u'dev43',
323             u'd-network_id': u'net987',
324             u'e': u'40.30.20.15',
325             u'e-subnet_id': 2,
326             u'e-mac_address': u'00:10',
327             u'e-device_id': u'dev43',
328             u'e-network_id': u'net987',
329         }
330         server = mock.MagicMock()
331         server.ports = OrderedDict([
332             ('a', [{'stack_name': 'b', 'port': 'port_a'}]),
333             ('c', [{'stack_name': 'd', 'port': 'port_c'},
334                    {'stack_name': 'e', 'port': 'port_f'}]),
335         ])
336
337         expected = {
338             "private_ip": '10.20.30.45',
339             "subnet_id": 1,
340             "subnet_cidr": '10.20.0.0/15',
341             "network": '10.20.0.0',
342             "netmask": '255.254.0.0',
343             "name": "port_a",
344             "gateway_ip": '10.20.30.1',
345             "mac_address": '00:01',
346             "device_id": 'dev21',
347             "network_id": 'net789',
348             "network_name": 'a',
349             "local_mac": '00:01',
350             "local_ip": '10.20.30.45',
351         }
352         self.test_context.add_server_port(server)
353         self.assertEqual(server.private_ip, '10.20.30.45')
354         self.assertEqual(len(server.interfaces), 3)
355         self.assertDictEqual(server.interfaces['port_a'], expected)
356
357     @mock.patch('yardstick.benchmark.contexts.heat.os')
358     @mock.patch.object(heat.HeatContext, '_delete_key_file')
359     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
360     def test_undeploy(self, mock_template, mock_delete_key, *args):
361         self.test_context.stack = mock_template
362         self.test_context._name = 'foo'
363         self.test_context._task_id = '1234567890'
364         self.test_context._name_task_id = '{}-{}'.format(
365             self.test_context._name, self.test_context._task_id[:8])
366         # mock_os.path.exists.return_value = True
367         self.test_context.key_filename = 'foo/bar/foobar'
368         self.test_context.undeploy()
369         mock_delete_key.assert_called()
370         self.assertTrue(mock_template.delete.called)
371
372     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
373     def test_undeploy_no_teardown(self, mock_template):
374         self.test_context.stack = mock_template
375         self.test_context._name = 'foo'
376         self.test_context._task_id = '1234567890'
377         self.test_context._flags.no_teardown = True
378         self.test_context.undeploy()
379
380         mock_template.delete.assert_not_called()
381
382     @mock.patch('yardstick.benchmark.contexts.heat.HeatTemplate')
383     @mock.patch('yardstick.benchmark.contexts.heat.os')
384     def test_undeploy_key_filename(self, mock_os, mock_template):
385         self.test_context.stack = mock_template
386         self.test_context._name = 'foo'
387         self.test_context._task_id = '1234567890'
388         self.test_context._name_task_id = '{}-{}'.format(
389             self.test_context._name, self.test_context._task_id)
390         mock_os.path.exists.return_value = True
391         self.test_context.key_filename = 'foo/bar/foobar'
392         self.assertIsNone(self.test_context.undeploy())
393
394     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
395     def test__get_server_found_dict(self, *args):
396         """
397         Use HeatContext._get_server to get a server that matches
398         based on a dictionary input.
399         """
400         foo2_server = mock.Mock()
401         foo2_server.key_filename = None
402         foo2_server.private_ip = '10.0.0.2'
403         foo2_server.public_ip = '127.0.0.2'
404         foo2_server.context.user = 'oof'
405
406         baz3_server = mock.Mock()
407         baz3_server.key_filename = None
408         baz3_server.private_ip = '10.0.0.3'
409         baz3_server.public_ip = '127.0.0.3'
410         baz3_server.context.user = 'zab'
411
412         self.test_context._name = 'bar'
413         self.test_context._task_id = '1234567890'
414         self.test_context._name_task_id = '{}-{}'.format(
415             self.test_context._name, self.test_context._task_id[:8])
416         self.test_context._user = 'bot'
417         self.test_context.stack = mock.Mock()
418         self.test_context.stack.outputs = {
419             'private_ip': '10.0.0.1',
420             'public_ip': '127.0.0.1',
421         }
422         self.test_context._server_map = {
423             'baz3': baz3_server,
424             'foo2': foo2_server,
425         }
426
427         attr_name = {
428             'name': 'foo.bar-12345678',
429             'private_ip_attr': 'private_ip',
430             'public_ip_attr': 'public_ip',
431         }
432         self.test_context.key_uuid = 'foo-42'
433         result = self.test_context._get_server(attr_name)
434         self.assertEqual(result['user'], 'bot')
435         self.assertEqual(result['ip'], '127.0.0.1')
436         self.assertEqual(result['private_ip'], '10.0.0.1')
437
438     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
439     def test__get_server_found_dict_no_attrs(self, *args):
440         """
441         Use HeatContext._get_server to get a server that matches
442         based on a dictionary input.
443         """
444         foo2_server = mock.Mock()
445         foo2_server.private_ip = '10.0.0.2'
446         foo2_server.public_ip = '127.0.0.2'
447         foo2_server.context.user = 'oof'
448
449         baz3_server = mock.Mock()
450         baz3_server.private_ip = '10.0.0.3'
451         baz3_server.public_ip = '127.0.0.3'
452         baz3_server.context.user = 'zab'
453
454         self.test_context._name = 'bar'
455         self.test_context._task_id = '1234567890'
456         self.test_context._name_task_id = '{}-{}'.format(
457             self.test_context._name, self.test_context._task_id[:8])
458         self.test_context._user = 'bot'
459         self.test_context.stack = mock.Mock()
460         self.test_context.stack.outputs = {
461             'private_ip': '10.0.0.1',
462             'public_ip': '127.0.0.1',
463         }
464         self.test_context._server_map = {
465             'baz3': baz3_server,
466             'foo2': foo2_server,
467         }
468
469         attr_name = {
470             'name': 'foo.bar-12345678',
471         }
472
473         self.test_context.key_uuid = 'foo-42'
474         result = self.test_context._get_server(attr_name)
475         self.assertEqual(result['user'], 'bot')
476         # no private ip attr mapping in the map results in None value in the result
477         self.assertIsNone(result['private_ip'])
478         # no public ip attr mapping in the map results in no value in the result
479         self.assertNotIn('ip', result)
480
481     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
482     def test__get_server_found_not_dict(self, *args):
483         """
484         Use HeatContext._get_server to get a server that matches
485         based on a non-dictionary input
486         """
487         foo2_server = mock.Mock()
488         foo2_server.private_ip = '10.0.0.2'
489         foo2_server.public_ip = '127.0.0.2'
490         foo2_server.context.user = 'oof'
491
492         baz3_server = mock.Mock()
493         baz3_server.private_ip = '10.0.0.3'
494         baz3_server.public_ip = None
495         baz3_server.context.user = 'zab'
496
497         self.test_context._name = 'bar1'
498         self.test_context._task_id = '1234567890'
499         self.test_context._name_task_id = 'bar1-12345678'
500         self.test_context.stack = mock.Mock()
501         self.test_context.stack.outputs = {
502             'private_ip': '10.0.0.1',
503             'public_ip': '127.0.0.1',
504         }
505         self.test_context.generate_routing_table = mock.MagicMock(return_value=[])
506
507         self.test_context._server_map = {
508             'baz3': baz3_server,
509             'foo2': foo2_server,
510         }
511
512         attr_name = 'baz3'
513         result = self.test_context._get_server(attr_name)
514         self.assertEqual(result['user'], 'zab')
515         self.assertEqual(result['private_ip'], '10.0.0.3')
516         # no public_ip on the server results in no value in the result
517         self.assertNotIn('public_ip', result)
518
519     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
520     def test__get_server_none_found_not_dict(self, *args):
521         """
522         Use HeatContext._get_server to not get a server due to
523         None value associated with the match to a non-dictionary
524         input
525         """
526         foo2_server = mock.Mock()
527         foo2_server.private_ip = '10.0.0.2'
528         foo2_server.public_ip = '127.0.0.2'
529         foo2_server.context.user = 'oof'
530
531         baz3_server = mock.Mock()
532         baz3_server.private_ip = '10.0.0.3'
533         baz3_server.public_ip = None
534         baz3_server.context.user = 'zab'
535
536         self.test_context._name = 'bar1'
537         self.test_context.stack = mock.Mock()
538         self.test_context.stack.outputs = {
539             'private_ip': '10.0.0.1',
540             'public_ip': '127.0.0.1',
541         }
542         self.test_context._server_map = {
543             'baz3': baz3_server,
544             'foo2': foo2_server,
545             'wow4': None,
546         }
547
548         self.test_context.key_uuid = 'foo-42'
549         attr_name = 'wow4'
550         result = self.test_context._get_server(attr_name)
551         self.assertIsNone(result)
552
553     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
554     def test__get_server_not_found_dict(self, *args):
555         """
556         Use HeatContext._get_server to not get a server for lack
557         of a match to a dictionary input
558         """
559         foo2_server = mock.Mock()
560         foo2_server.private_ip = '10.0.0.2'
561         foo2_server.public_ip = '127.0.0.2'
562         foo2_server.context.user = 'oof'
563
564         baz3_server = mock.Mock()
565         baz3_server.private_ip = '10.0.0.3'
566         baz3_server.public_ip = None
567         baz3_server.context.user = 'zab'
568
569         self.test_context._name = 'bar1'
570         self.test_context._task_id = '1235467890'
571         self.test_context._name_task_id = '{}-{}'.format(
572             self.test_context._name, self.test_context._task_id[:8])
573         self.test_context.stack = mock.Mock()
574         self.test_context.stack.outputs = {
575             'private_ip': '10.0.0.1',
576             'public_ip': '127.0.0.1',
577         }
578         self.test_context._server_map = {
579             'baz3': baz3_server,
580             'foo2': foo2_server,
581         }
582
583         self.test_context.key_uuid = 'foo-42'
584         attr_name = {
585             'name': 'foo.wow4',
586             'private_ip_attr': 'private_ip',
587             'public_ip_attr': 'public_ip',
588         }
589         result = self.test_context._get_server(attr_name)
590         self.assertIsNone(result)
591
592     @mock.patch("yardstick.benchmark.contexts.heat.pkg_resources")
593     def test__get_server_not_found_not_dict(self, *args):
594         """
595         Use HeatContext._get_server to not get a server for lack
596         of a match to a non-dictionary input
597         """
598         foo2_server = mock.Mock()
599         foo2_server.private_ip = '10.0.0.2'
600         foo2_server.public_ip = '127.0.0.2'
601         foo2_server.context.user = 'oof'
602
603         baz3_server = mock.Mock()
604         baz3_server.private_ip = '10.0.0.3'
605         baz3_server.public_ip = None
606         baz3_server.context.user = 'zab'
607
608         self.mock_context._name = 'bar1'
609         self.test_context.stack = mock.Mock()
610         self.mock_context.stack.outputs = {
611             'private_ip': '10.0.0.1',
612             'public_ip': '127.0.0.1',
613         }
614         self.mock_context._server_map = {
615             'baz3': baz3_server,
616             'foo2': foo2_server,
617         }
618
619         self.test_context.key_uuid = 'foo-42'
620         attr_name = 'foo.wow4'
621         result = self.test_context._get_server(attr_name)
622         self.assertIsNone(result)
623
624     # TODO: Split this into more granular tests
625     def test__get_network(self):
626         network1 = mock.MagicMock()
627         network1.name = 'net_1'
628         network1.vld_id = 'vld111'
629         network1.segmentation_id = 'seg54'
630         network1.network_type = 'type_a'
631         network1.physical_network = 'phys'
632
633         network2 = mock.MagicMock()
634         network2.name = 'net_2'
635         network2.segmentation_id = 'seg45'
636         network2.network_type = 'type_b'
637         network2.physical_network = 'virt'
638
639         self.test_context.networks = {
640             'a': network1,
641             'b': network2,
642         }
643
644         attr_name = None
645         self.assertIsNone(self.test_context._get_network(attr_name))
646
647         attr_name = {}
648         self.assertIsNone(self.test_context._get_network(attr_name))
649
650         attr_name = {'network_type': 'nosuch'}
651         self.assertIsNone(self.test_context._get_network(attr_name))
652
653         attr_name = 'vld777'
654         self.assertIsNone(self.test_context._get_network(attr_name))
655
656         attr_name = {'segmentation_id': 'seg45'}
657         expected = {
658             "name": 'net_2',
659             "segmentation_id": 'seg45',
660             "network_type": 'type_b',
661             "physical_network": 'virt',
662         }
663         result = self.test_context._get_network(attr_name)
664         self.assertDictEqual(result, expected)
665
666         attr_name = 'a'
667         expected = {
668             "name": 'net_1',
669             "segmentation_id": 'seg54',
670             "network_type": 'type_a',
671             "physical_network": 'phys',
672         }
673         result = self.test_context._get_network(attr_name)
674         self.assertDictEqual(result, expected)