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