+ heat_template.add_flavor(name="flavor1", vcpus=1, ram=2048, disk=1,extra_specs={"cat": 1, "dog": 2})
+ heat_template.add_flavor(name=None, vcpus=1, ram=2048)
+ heat_template.add_server(name="server1",
+ image="image1",
+ flavor="flavor1",
+ flavors=[],
+ ports=["port1", "port2"],
+ networks=["network1", "network2"],
+ scheduler_hints="hints1",
+ user="user1",
+ key_name="foo-key",
+ user_data="user",
+ metadata={"cat": 1, "doc": 2},
+ additional_properties= {"prop1": 1, "prop2": 2} )
+ heat_template.add_network("network1")
+
+ heat_template.add_flavor("test")
+ self.assertEqual(heat_template.resources['test']['type'], 'OS::Nova::Flavor')
+
+ @mock_patch_target_module('op_utils')
+ @mock_patch_target_module('heatclient')
+ def test_create_negative(self, mock_heat_client_class, mock_op_utils):
+ self.template.HEAT_WAIT_LOOP_INTERVAL = 0
+ mock_heat_client = mock_heat_client_class() # get the constructed mock
+
+ # populate attributes of the constructed mock
+ mock_heat_client.stacks.get().stack_status_reason = 'the reason'
+
+ expected_status_calls = 0
+ expected_constructor_calls = 1 # above, to get the instance
+ expected_create_calls = 0
+ expected_op_utils_usage = 0
+
+ with mock.patch.object(self.template, 'status', return_value=None) as mock_status:
+ # block with timeout hit
+ timeout = 0
+ with self.assertRaises(RuntimeError) as raised, timer() as time_data:
+ self.template.create(block=True, timeout=timeout)
+
+ # ensure op_utils was used
+ expected_op_utils_usage += 1
+ self.assertEqual(mock_op_utils.get_session.call_count, expected_op_utils_usage)
+ self.assertEqual(mock_op_utils.get_endpoint.call_count, expected_op_utils_usage)
+ self.assertEqual(mock_op_utils.get_heat_api_version.call_count, expected_op_utils_usage)
+
+ # ensure the constructor and instance were used
+ self.assertEqual(mock_heat_client_class.call_count, expected_constructor_calls)
+ self.assertEqual(mock_heat_client.stacks.create.call_count, expected_create_calls)
+
+ # ensure that the status was used
+ self.assertGreater(mock_status.call_count, expected_status_calls)
+ expected_status_calls = mock_status.call_count # synchronize the value
+
+ # ensure the expected exception was raised
+ error_message = get_error_message(raised.exception)
+ self.assertIn('timeout', error_message)
+ self.assertNotIn('the reason', error_message)
+
+ # block with create failed
+ timeout = 10
+ mock_status.side_effect = iter([None, None, u'CREATE_FAILED'])
+ with self.assertRaises(RuntimeError) as raised, timer() as time_data:
+ self.template.create(block=True, timeout=timeout)
+
+ # ensure the existing heat_client was used and op_utils was used again
+ self.assertEqual(mock_op_utils.get_session.call_count, expected_op_utils_usage)
+ self.assertEqual(mock_op_utils.get_endpoint.call_count, expected_op_utils_usage)
+ self.assertEqual(mock_op_utils.get_heat_api_version.call_count, expected_op_utils_usage)
+
+ # ensure the constructor was not used but the instance was used
+ self.assertEqual(mock_heat_client_class.call_count, expected_constructor_calls)
+ self.assertEqual(mock_heat_client.stacks.create.call_count, expected_create_calls)
+
+ # ensure that the status was used three times
+ expected_status_calls += 3
+ self.assertEqual(mock_status.call_count, expected_status_calls)
+
+ @mock_patch_target_module('op_utils')
+ @mock_patch_target_module('heatclient')
+ def test_create(self, mock_heat_client_class, mock_op_utils):
+ self.template.HEAT_WAIT_LOOP_INTERVAL = 0.2
+ mock_heat_client = mock_heat_client_class()
+
+ # populate attributes of the constructed mock
+ mock_heat_client.stacks.get().outputs = [
+ {'output_key': 'key1', 'output_value': 'value1'},
+ {'output_key': 'key2', 'output_value': 'value2'},
+ {'output_key': 'key3', 'output_value': 'value3'},
+ ]
+ expected_outputs = {
+ 'key1': 'value1',
+ 'key2': 'value2',
+ 'key3': 'value3',
+ }
+
+ expected_status_calls = 0
+ expected_constructor_calls = 1 # above, to get the instance
+ expected_create_calls = 0
+ expected_op_utils_usage = 0
+
+ with mock.patch.object(self.template, 'status') as mock_status:
+ self.template.name = 'no block test'
+ mock_status.return_value = None
+
+ # no block
+ self.assertIsInstance(self.template.create(block=False, timeout=2), heat.HeatStack)
+
+ # ensure op_utils was used
+ expected_op_utils_usage += 1
+ self.assertEqual(mock_op_utils.get_session.call_count, expected_op_utils_usage)
+ self.assertEqual(mock_op_utils.get_endpoint.call_count, expected_op_utils_usage)
+ self.assertEqual(mock_op_utils.get_heat_api_version.call_count, expected_op_utils_usage)
+
+ # ensure the constructor and instance were used
+ self.assertEqual(mock_heat_client_class.call_count, expected_constructor_calls)
+ self.assertEqual(mock_heat_client.stacks.create.call_count, expected_create_calls)
+
+ # ensure that the status was not used
+ self.assertEqual(mock_status.call_count, expected_status_calls)
+
+ # ensure no outputs because this requires blocking
+ self.assertEqual(self.template.outputs, {})
+
+ # block with immediate complete
+ self.template.name = 'block, immediate complete test'
+
+ mock_status.return_value = self.template.HEAT_CREATE_COMPLETE_STATUS
+ self.assertIsInstance(self.template.create(block=True, timeout=2), heat.HeatStack)
+
+ # ensure existing instance was re-used and op_utils was not used
+ self.assertEqual(mock_heat_client_class.call_count, expected_constructor_calls)
+ self.assertEqual(mock_heat_client.stacks.create.call_count, expected_create_calls)
+
+ # ensure status was checked once
+ expected_status_calls += 1
+ self.assertEqual(mock_status.call_count, expected_status_calls)
+
+ # reset template outputs
+ self.template.outputs = None
+
+ # block with delayed complete
+ self.template.name = 'block, delayed complete test'
+
+ success_index = 2
+ mock_status.side_effect = index_value_iter(success_index,
+ self.template.HEAT_CREATE_COMPLETE_STATUS)
+ self.assertIsInstance(self.template.create(block=True, timeout=2), heat.HeatStack)
+
+ # ensure existing instance was re-used and op_utils was not used
+ self.assertEqual(mock_heat_client_class.call_count, expected_constructor_calls)
+ self.assertEqual(mock_heat_client.stacks.create.call_count, expected_create_calls)
+
+ # ensure status was checked three more times
+ expected_status_calls += 1 + success_index
+ self.assertEqual(mock_status.call_count, expected_status_calls)