Source code for ironic_python_agent.tests.functional.test_commands

# Copyright 2015 Rackspace, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from ironic_python_agent.tests.functional import base


[docs]class TestCommands(base.FunctionalBase): """Tests the commands API. These tests are structured monolithically as one test with multiple steps to preserve ordering and ensure IPA state remains consistent across different test runs. """
[docs] def step_1_get_empty_commands(self): response = self.request('get', 'commands') self.assertEqual({'commands': []}, response)
[docs] def step_2_run_command(self): # NOTE(mariojv): get_clean_steps always returns the default # HardwareManager clean steps if there's not a more specific HWM. So, # this command succeeds even with an empty node and port. This test's # success is required for steps 3 and 4 to succeed. command = {'name': 'clean.get_clean_steps', 'params': {'node': {}, 'ports': {}}} response = self.request('post', 'commands', json=command, headers={'Content-Type': 'application/json'}) self.assertIsNone(response['command_error'])
[docs] def step_3_get_commands(self): # This test relies on step 2 to succeed since step 2 runs the command # we're checking for response = self.request('get', 'commands') self.assertEqual(1, len(response['commands'])) self.assertEqual( 'get_clean_steps', response['commands'][0]['command_name'])
[docs] def step_4_get_command_by_id(self): # First, we have to query the commands API to retrieve the ID. Make # sure this API call succeeds again, just in case it fails for some # reason after the last test. This test relies on step 2 to succeed # since step 2 runs the command we're checking for. response = self.request('get', 'commands') command_id = response['commands'][0]['id'] command_from_id = self.request( 'get', 'commands/%s' % command_id) self.assertEqual('get_clean_steps', command_from_id['command_name'])
[docs] def step_5_run_non_existent_command(self): fake_command = {'name': 'bad_extension.fake_command', 'params': {}} self.request('post', 'commands', expect_error=404, json=fake_command)
[docs] def positive_get_post_command_steps(self): """Returns generator with test steps sorted by step number.""" steps_unsorted = [step for step in dir(self) if step.startswith('step_')] # The lambda retrieves the step number from the function name and casts # it to an integer. This is necessary, otherwise a lexicographic sort # would return ['step_1', 'step_12', 'step_3'] after sorting instead of # ['step_1', 'step_3', 'step_12']. steps = sorted(steps_unsorted, key=lambda s: int(s.split('_', 2)[1])) for name in steps: yield getattr(self, name)
[docs] def test_positive_get_post_commands(self): for step in self.positive_get_post_command_steps(): step()