| Steve Baker | f6c8f12 | 2015-02-10 13:54:46 +1300 | [diff] [blame] | 1 | #    Licensed under the Apache License, Version 2.0 (the "License"); you may | 
|  | 2 | #    not use this file except in compliance with the License. You may obtain | 
|  | 3 | #    a copy of the License at | 
|  | 4 | # | 
|  | 5 | #         http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 6 | # | 
|  | 7 | #    Unless required by applicable law or agreed to in writing, software | 
|  | 8 | #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | 
|  | 9 | #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | 
|  | 10 | #    License for the specific language governing permissions and limitations | 
|  | 11 | #    under the License. | 
|  | 12 |  | 
|  | 13 | import six | 
|  | 14 |  | 
|  | 15 | from heat_integrationtests.common import exceptions | 
| Anastasia Kuznetsova | e45bfff | 2015-02-25 12:50:34 +0400 | [diff] [blame] | 16 | from heat_integrationtests.scenario import scenario_base | 
| Steve Baker | f6c8f12 | 2015-02-10 13:54:46 +1300 | [diff] [blame] | 17 |  | 
|  | 18 | CFG1_SH = '''#!/bin/sh | 
|  | 19 | echo "Writing to /tmp/$bar" | 
|  | 20 | echo $foo > /tmp/$bar | 
|  | 21 | echo -n "The file /tmp/$bar contains `cat /tmp/$bar` for server \ | 
|  | 22 | $deploy_server_id during $deploy_action" > $heat_outputs_path.result | 
|  | 23 | echo "Written to /tmp/$bar" | 
|  | 24 | echo "Output to stderr" 1>&2 | 
|  | 25 | ''' | 
|  | 26 |  | 
|  | 27 | CFG3_PP = '''file {'barfile': | 
|  | 28 | ensure  => file, | 
|  | 29 | mode    => 0644, | 
|  | 30 | path    => "/tmp/$::bar", | 
|  | 31 | content => "$::foo", | 
|  | 32 | } | 
|  | 33 | file {'output_result': | 
|  | 34 | ensure  => file, | 
|  | 35 | path    => "$::heat_outputs_path.result", | 
|  | 36 | mode    => 0644, | 
|  | 37 | content => "The file /tmp/$::bar contains $::foo for server \ | 
|  | 38 | $::deploy_server_id during $::deploy_action", | 
|  | 39 | }''' | 
|  | 40 |  | 
|  | 41 |  | 
| Anastasia Kuznetsova | e45bfff | 2015-02-25 12:50:34 +0400 | [diff] [blame] | 42 | class SoftwareConfigIntegrationTest(scenario_base.ScenarioTestsBase): | 
| Steve Baker | f6c8f12 | 2015-02-10 13:54:46 +1300 | [diff] [blame] | 43 |  | 
|  | 44 | def setUp(self): | 
|  | 45 | super(SoftwareConfigIntegrationTest, self).setUp() | 
|  | 46 | if self.conf.skip_software_config_tests: | 
|  | 47 | self.skipTest('Testing software config disabled in conf, ' | 
|  | 48 | 'skipping') | 
| Steve Baker | f6c8f12 | 2015-02-10 13:54:46 +1300 | [diff] [blame] | 49 | self.stack_name = self._stack_rand_name() | 
| Steve Baker | f6c8f12 | 2015-02-10 13:54:46 +1300 | [diff] [blame] | 50 |  | 
| Steve Baker | 8c9aee1 | 2015-03-10 16:17:45 +1300 | [diff] [blame^] | 51 | def check_stack(self): | 
|  | 52 | sid = self.stack_identifier | 
| Anastasia Kuznetsova | e45bfff | 2015-02-25 12:50:34 +0400 | [diff] [blame] | 53 | # Check that all stack resources were created | 
| Steve Baker | f6c8f12 | 2015-02-10 13:54:46 +1300 | [diff] [blame] | 54 | for res in ('cfg2a', 'cfg2b', 'cfg1', 'cfg3', 'server'): | 
|  | 55 | self._wait_for_resource_status( | 
|  | 56 | sid, res, 'CREATE_COMPLETE') | 
|  | 57 |  | 
|  | 58 | server_resource = self.client.resources.get(sid, 'server') | 
|  | 59 | server_id = server_resource.physical_resource_id | 
|  | 60 | server = self.compute_client.servers.get(server_id) | 
|  | 61 |  | 
| Anastasia Kuznetsova | e45bfff | 2015-02-25 12:50:34 +0400 | [diff] [blame] | 62 | # Waiting for each deployment to contribute their | 
|  | 63 | # config to resource | 
| Steve Baker | f6c8f12 | 2015-02-10 13:54:46 +1300 | [diff] [blame] | 64 | try: | 
| Steve Baker | f6c8f12 | 2015-02-10 13:54:46 +1300 | [diff] [blame] | 65 | for res in ('dep2b', 'dep1', 'dep3'): | 
|  | 66 | self._wait_for_resource_status( | 
|  | 67 | sid, res, 'CREATE_IN_PROGRESS') | 
|  | 68 |  | 
| Anastasia Kuznetsova | e45bfff | 2015-02-25 12:50:34 +0400 | [diff] [blame] | 69 | server_metadata = self.client.resources.metadata( | 
|  | 70 | sid, 'server') | 
| Steve Baker | f6c8f12 | 2015-02-10 13:54:46 +1300 | [diff] [blame] | 71 | deployments = dict((d['name'], d) for d in | 
|  | 72 | server_metadata['deployments']) | 
|  | 73 |  | 
|  | 74 | for res in ('dep2a', 'dep2b', 'dep1', 'dep3'): | 
|  | 75 | self._wait_for_resource_status( | 
|  | 76 | sid, res, 'CREATE_COMPLETE') | 
|  | 77 | except (exceptions.StackResourceBuildErrorException, | 
|  | 78 | exceptions.TimeoutException) as e: | 
|  | 79 | self._log_console_output(servers=[server]) | 
|  | 80 | raise e | 
|  | 81 |  | 
| Anastasia Kuznetsova | e45bfff | 2015-02-25 12:50:34 +0400 | [diff] [blame] | 82 | # Check that stack was fully created | 
| Steve Baker | f6c8f12 | 2015-02-10 13:54:46 +1300 | [diff] [blame] | 83 | self._wait_for_stack_status(sid, 'CREATE_COMPLETE') | 
|  | 84 |  | 
|  | 85 | complete_server_metadata = self.client.resources.metadata( | 
|  | 86 | sid, 'server') | 
| Anastasia Kuznetsova | e45bfff | 2015-02-25 12:50:34 +0400 | [diff] [blame] | 87 |  | 
|  | 88 | # Ensure any previously available deployments haven't changed so | 
| Steve Baker | f6c8f12 | 2015-02-10 13:54:46 +1300 | [diff] [blame] | 89 | # config isn't re-triggered | 
|  | 90 | complete_deployments = dict((d['name'], d) for d in | 
|  | 91 | complete_server_metadata['deployments']) | 
|  | 92 | for k, v in six.iteritems(deployments): | 
|  | 93 | self.assertEqual(v, complete_deployments[k]) | 
|  | 94 |  | 
|  | 95 | stack = self.client.stacks.get(sid) | 
|  | 96 |  | 
|  | 97 | res1 = self._stack_output(stack, 'res1') | 
|  | 98 | self.assertEqual( | 
|  | 99 | 'The file %s contains %s for server %s during %s' % ( | 
|  | 100 | '/tmp/baaaaa', 'fooooo', server_id, 'CREATE'), | 
|  | 101 | res1['result']) | 
|  | 102 | self.assertEqual(0, res1['status_code']) | 
|  | 103 | self.assertEqual('Output to stderr\n', res1['stderr']) | 
|  | 104 | self.assertTrue(len(res1['stdout']) > 0) | 
|  | 105 |  | 
|  | 106 | res2 = self._stack_output(stack, 'res2') | 
|  | 107 | self.assertEqual( | 
|  | 108 | 'The file %s contains %s for server %s during %s' % ( | 
|  | 109 | '/tmp/cfn-init-foo', 'barrr', server_id, 'CREATE'), | 
|  | 110 | res2['result']) | 
|  | 111 | self.assertEqual(0, res2['status_code']) | 
|  | 112 | self.assertEqual('', res2['stderr']) | 
|  | 113 | self.assertEqual('', res2['stdout']) | 
|  | 114 |  | 
|  | 115 | res3 = self._stack_output(stack, 'res3') | 
|  | 116 | self.assertEqual( | 
|  | 117 | 'The file %s contains %s for server %s during %s' % ( | 
|  | 118 | '/tmp/ba', 'fo', server_id, 'CREATE'), | 
|  | 119 | res3['result']) | 
|  | 120 | self.assertEqual(0, res3['status_code']) | 
|  | 121 | self.assertEqual('', res3['stderr']) | 
|  | 122 | self.assertTrue(len(res1['stdout']) > 0) | 
|  | 123 |  | 
|  | 124 | dep1_resource = self.client.resources.get(sid, 'dep1') | 
|  | 125 | dep1_id = dep1_resource.physical_resource_id | 
|  | 126 | dep1_dep = self.client.software_deployments.get(dep1_id) | 
| Steve Baker | 8c9aee1 | 2015-03-10 16:17:45 +1300 | [diff] [blame^] | 127 | if hasattr(dep1_dep, 'updated_time'): | 
|  | 128 | # Only check updated_time if the attribute exists. | 
|  | 129 | # This allows latest heat agent code to be tested with | 
|  | 130 | # Juno heat (which doesn't expose updated_time) | 
|  | 131 | self.assertIsNotNone(dep1_dep.updated_time) | 
|  | 132 | self.assertNotEqual( | 
|  | 133 | dep1_dep.updated_time, | 
|  | 134 | dep1_dep.creation_time) | 
| Steve Baker | f6c8f12 | 2015-02-10 13:54:46 +1300 | [diff] [blame] | 135 |  | 
|  | 136 | def test_server_software_config(self): | 
| Anastasia Kuznetsova | e45bfff | 2015-02-25 12:50:34 +0400 | [diff] [blame] | 137 | """ | 
|  | 138 | Check that passed files with scripts are executed on created server. | 
|  | 139 |  | 
|  | 140 | The alternative scenario is the following: | 
|  | 141 | 1. Create a stack and pass files with scripts. | 
|  | 142 | 2. Check that all stack resources are created successfully. | 
|  | 143 | 3. Wait for all deployments. | 
|  | 144 | 4. Check that stack was created. | 
|  | 145 | 5. Check stack outputs. | 
|  | 146 | """ | 
|  | 147 |  | 
|  | 148 | parameters = { | 
|  | 149 | 'key_name': self.keypair_name, | 
|  | 150 | 'flavor': self.conf.instance_type, | 
|  | 151 | 'image': self.conf.image_ref, | 
|  | 152 | 'network': self.net['id'] | 
|  | 153 | } | 
|  | 154 |  | 
|  | 155 | files = { | 
|  | 156 | 'cfg1.sh': CFG1_SH, | 
|  | 157 | 'cfg3.pp': CFG3_PP | 
|  | 158 | } | 
|  | 159 |  | 
|  | 160 | # Launch stack | 
| Steve Baker | 8c9aee1 | 2015-03-10 16:17:45 +1300 | [diff] [blame^] | 161 | self.stack_identifier = self.launch_stack( | 
| Anastasia Kuznetsova | e45bfff | 2015-02-25 12:50:34 +0400 | [diff] [blame] | 162 | stack_name=self.stack_name, | 
|  | 163 | template_name='test_server_software_config.yaml', | 
|  | 164 | parameters=parameters, | 
|  | 165 | files=files, | 
|  | 166 | expected_status=None | 
|  | 167 | ) | 
|  | 168 |  | 
| Anastasia Kuznetsova | e45bfff | 2015-02-25 12:50:34 +0400 | [diff] [blame] | 169 | # Check stack | 
| Steve Baker | 8c9aee1 | 2015-03-10 16:17:45 +1300 | [diff] [blame^] | 170 | self.check_stack() |