def test_activity_is_not_logged_when_leaving_power_settings_empty(self): # The bug was that we were recording a change to power_user or # power_passwd because it changed from NULL to ''. with session.begin(): self.system.power.power_type = PowerType.lazy_create(name=u'ilo') self.system.power.power_user = None self.system.power.power_passwd = None self.system.power.power_id = None PowerType.lazy_create(name=u'drac') self.assertEquals(len(self.system.activity), 0) b = self.browser login(b) self.go_to_system_view(tab='Power Settings') tab = b.find_element_by_id('power-settings') # change power type but leave the other fields empty BootstrapSelect(tab.find_element_by_name('power_type'))\ .select_by_visible_text('drac') tab.find_element_by_tag_name('form').submit() tab.find_element_by_xpath('.//span[@class="sync-status" and not(text())]') with session.begin(): session.refresh(self.system) self.assertEquals(len(self.system.activity), 1, 'Expecting only one activity row for power_type but found: %r' % self.system.activity) self.assertEquals(self.system.activity[0].field_name, u'power_type')
def test_activity_is_not_logged_when_leaving_power_settings_empty(self): # The bug was that we were recording a change to power_user or # power_passwd because it changed from NULL to ''. with session.begin(): self.system.power.power_type = PowerType.lazy_create(name=u'ilo') self.system.power.power_user = None self.system.power.power_passwd = None self.system.power.power_id = None PowerType.lazy_create(name=u'drac') self.assertEquals(len(self.system.activity), 0) b = self.browser login(b) self.go_to_system_view(tab='Power Settings') tab = b.find_element_by_id('power-settings') # change power type but leave the other fields empty BootstrapSelect(tab.find_element_by_name('power_type'))\ .select_by_visible_text('drac') tab.find_element_by_tag_name('form').submit() tab.find_element_by_xpath('.//button[text()="Save Changes"]') with session.begin(): session.refresh(self.system) self.assertEquals( len(self.system.activity), 1, 'Expecting only one activity row for power_type but found: %r' % self.system.activity) self.assertEquals(self.system.activity[0].field_name, u'power_type')
def test_power_quiescent_period_statefulness_not_elapsed(self): if daemons_running_externally(): raise SkipTest('cannot examine logs of remote beaker-provision') provision_process, = [p for p in processes if p.name == \ 'beaker-provision'] # Initial lookup of this system will reveal no state, so will delay # for the whole quiescent period try: provision_process.start_output_capture() with session.begin(): system = data_setup.create_system(lab_controller=self.get_lc()) system.power.power_type = PowerType.lazy_create(name=u'dummy') system.power.power_quiescent_period = 1 system.power.power_id = u'' # make power script not sleep system.power.delay_until = None system.action_power(action=u'off', service=u'testdata') wait_for_commands_to_finish(system, timeout=10) finally: provision_output = provision_process.finish_output_capture() self.assertIn('Entering quiescent period, delaying 1 seconds for ' 'command %s' % system.command_queue[0].id, provision_output) # Increase the quiescent period, to ensure we enter it try: provision_process.start_output_capture() with session.begin(): system = System.by_id(system.id, User.by_user_name('admin')) system.power.power_quiescent_period = 10 system.action_power(action=u'on', service=u'testdata') wait_for_commands_to_finish(system, timeout=15) finally: provision_output = provision_process.finish_output_capture() self.assertIn('Entering quiescent period', provision_output)
def test_power_commands_are_not_run_twice(self): # We will make the dummy power script sleep for this long: power_sleep = 4 # To reproduce this bug, we need to queue up three commands for the # same system (so they are run in sequence by beaker-provision), where # the commands take enough time that the second one will still be # running on the next iteration of the polling loop. The third command # will be run twice. assert power_sleep < get_conf().get('SLEEP_TIME') assert 2 * power_sleep > get_conf().get('SLEEP_TIME') with session.begin(): system = data_setup.create_system(lab_controller=self.get_lc()) system.power.power_type = PowerType.lazy_create(name=u'dummy') system.power.power_id = power_sleep # make power script sleep system.action_power(action=u'off', service=u'testdata') system.action_power(action=u'off', service=u'testdata') system.action_power(action=u'off', service=u'testdata') wait_for_commands_to_finish(system, timeout=5 * power_sleep) with session.begin(): session.expire_all() self.assertEquals(system.command_queue[0].status, CommandStatus.completed) self.assertEquals(system.command_queue[1].status, CommandStatus.completed) self.assertEquals(system.command_queue[2].status, CommandStatus.completed) # The bug manifests as two "Completed" records for the power # command which ran twice self.assertEquals(system.dyn_activity .filter_by(field_name=u'Power', new_value=u'Completed') .count(), 3)
def test_power_quiescent_period(self): # Test that we do in fact wait for the quiescent period to pass # before running a command if daemons_running_externally(): raise SkipTest('cannot examine logs of remote beaker-provision') provision_process, = [p for p in processes if p.name == \ 'beaker-provision'] # These times are needed to guarantee that we are actually waiting for # the quiescent period and not waiting for another poll loop quiescent_period = get_conf().get('SLEEP_TIME') * 3 timeout = get_conf().get('SLEEP_TIME') * 2 try: provision_process.start_output_capture() with session.begin(): system = data_setup.create_system(lab_controller=self.get_lc()) system.power.power_type = PowerType.lazy_create(name=u'dummy') system.power.power_quiescent_period = quiescent_period system.power.power_id = u'' # make power script not sleep system.power.delay_until = None system.action_power(action=u'off', service=u'testdata') wait_for_commands_completed(system, timeout=timeout) self.fail('The quiescent period is not being respected') except AssertionError: # wait_for_commands() should timeout if the quiescent period is #respected pass finally: provision_output = provision_process.finish_output_capture() # The initial command seen for a system will always wait for the full # quiescent period self.assertIn('Entering quiescent period, delaying %s seconds for ' 'command %s' % (quiescent_period, system.command_queue[0].id), provision_output)
def test_power_passwords_are_not_logged(self): if daemons_running_externally(): raise SkipTest('cannot examine logs of remote beaker-provision') provision_process, = [ p for p in processes if p.name == 'beaker-provision' ] try: provision_process.start_output_capture() with session.begin(): system = data_setup.create_system(lab_controller=self.get_lc()) self.addCleanup(self.cleanup_system, system) system.power.power_type = PowerType.lazy_create(name=u'dummy') system.power.power_id = u'' # make power script not sleep system.power.power_passwd = u'dontleakmebro' system.action_power(action=u'off', service=u'testdata') wait_for_commands_to_finish(system, timeout=2 * get_conf().get('SLEEP_TIME')) finally: provision_output = provision_process.finish_output_capture() self.assert_('Handling command' in provision_output, provision_output) self.assert_('Launching power script' in provision_output, provision_output) self.assert_(system.power.power_passwd not in provision_output, provision_output)
def test_quiescent_period_only_applies_between_power_commands(self): # The purpose of the quiescent period is for power supplies with # peculiar characteristics that need time to discharge or similar. # But the quiescent period should not count any other commands like # clear_logs or configure_netboot, because those are not touching the # power supply. loop_interval = get_conf().get('SLEEP_TIME') quiescent_period = loop_interval * 3.0 with session.begin(): system = data_setup.create_system(lab_controller=self.get_lc()) self.addCleanup(self.cleanup_system, system) system.power.power_type = PowerType.lazy_create(name=u'dummy') system.power.power_quiescent_period = quiescent_period system.power.power_id = u'' # make power script not sleep system.action_power(action=u'off', service=u'testdata') system.enqueue_command(action=u'clear_netboot', service=u'testdata') commands = system.command_queue[:2] assert_command_is_delayed(commands[1], quiescent_period - 0.5, timeout=2 * loop_interval) wait_for_command_to_finish(commands[0], timeout=2 * loop_interval) time.sleep(quiescent_period) # Now there should be no delays because the quiescent period has # already elapsed since the 'off' command above. with session.begin(): system.enqueue_command(action=u'clear_logs', service=u'testdata') system.action_power(action=u'on', service=u'testdata') commands = system.command_queue[:2] wait_for_command_to_finish(commands[1], timeout=2 * loop_interval) wait_for_command_to_finish(commands[0], timeout=2 * loop_interval)
def test_quiescent_period_only_applies_between_power_commands(self): # The purpose of the quiescent period is for power supplies with # peculiar characteristics that need time to discharge or similar. # But the quiescent period should not count any other commands like # clear_logs or configure_netboot, because those are not touching the # power supply. quiescent_period = get_conf().get('SLEEP_TIME') * 2.0 with session.begin(): system = data_setup.create_system(lab_controller=self.get_lc()) system.power.power_type = PowerType.lazy_create(name=u'dummy') system.power.power_quiescent_period = quiescent_period system.power.power_id = u'' # make power script not sleep system.action_power(action=u'off', service=u'testdata') system.enqueue_command(action=u'clear_netboot', service=u'testdata') commands = system.command_queue[:2] assert_command_is_delayed(commands[1], quiescent_period - 0.5, timeout=quiescent_period / 2) wait_for_command_to_finish(commands[0], timeout=quiescent_period / 2) time.sleep(quiescent_period) # Now there should be no delays because the quiescent period has # already elapsed since the 'off' command above. with session.begin(): system.enqueue_command(action=u'clear_logs', service=u'testdata') system.action_power(action=u'on', service=u'testdata') commands = system.command_queue[:2] wait_for_command_to_finish(commands[1], timeout=quiescent_period / 2) wait_for_command_to_finish(commands[0], timeout=quiescent_period / 2)
def test_power_quiescent_period(self): # Test that we do in fact wait for the quiescent period to pass # before running a command. # This time is needed to guarantee that we are actually waiting for # the quiescent period and not waiting for another poll loop: quiescent_period = get_conf().get('SLEEP_TIME') * 3 with session.begin(): system = data_setup.create_system(lab_controller=self.get_lc()) system.power.power_type = PowerType.lazy_create(name=u'dummy') system.power.power_quiescent_period = quiescent_period system.power.power_id = u'' # make power script not sleep system.power.delay_until = None system.action_power(action=u'off', service=u'testdata') command = system.command_queue[0] assert_command_is_delayed(command, quiescent_period - 0.5, 10)
def test_quiescent_period_is_obeyed_for_consecutive_commands(self): quiescent_period = 3 with session.begin(): system = data_setup.create_system(lab_controller=self.get_lc()) system.power.power_type = PowerType.lazy_create(name=u'dummy') system.power.power_quiescent_period = quiescent_period system.power.power_id = u'' # make power script not sleep system.power.delay_until = None system.action_power(action=u'on', service=u'testdata') system.action_power(action=u'on', service=u'testdata') system.action_power(action=u'on', service=u'testdata') commands = system.command_queue[:3] assert_command_is_delayed(commands[2], quiescent_period - 0.5, 10) assert_command_is_delayed(commands[1], quiescent_period - 0.5, 10) assert_command_is_delayed(commands[0], quiescent_period - 0.5, 10)
def test_power_passwords_are_not_reported_in_failure_message(self): with session.begin(): system = data_setup.create_system(lab_controller=self.get_lc()) self.addCleanup(self.cleanup_system, system) system.power.power_type = PowerType.lazy_create( name=u'testing-bz1358063') system.power.power_passwd = u'dontleakmebro' system.power.quiescent_period = 0 system.action_power(action=u'off', service=u'testdata') timeout = (2 * get_conf().get('SLEEP_TIME') + get_conf().get('POWER_ATTEMPTS') * 2**get_conf().get('POWER_ATTEMPTS')) wait_for_commands_to_finish(system, timeout=timeout) self.assertEqual(system.command_queue[0].status, CommandStatus.failed) self.assertIn( u'failed after 2 attempts with exit status 1:\npassword is ********', system.command_queue[0].error_message)
def test_power_passwords_are_not_logged(self): if daemons_running_externally(): raise SkipTest('cannot examine logs of remote beaker-provision') provision_process, = [p for p in processes if p.name == 'beaker-provision'] try: provision_process.start_output_capture() with session.begin(): system = data_setup.create_system(lab_controller=self.get_lc()) system.power.power_type = PowerType.lazy_create(name=u'dummy') system.power.power_id = u'' # make power script not sleep system.power.power_passwd = u'dontleakmebro' system.action_power(action=u'off', service=u'testdata') wait_for_commands_to_finish(system, timeout=2 * get_conf().get('SLEEP_TIME')) finally: provision_output = provision_process.finish_output_capture() self.assert_('Handling command' in provision_output, provision_output) self.assert_('Launching power script' in provision_output, provision_output) self.assert_(system.power.power_passwd not in provision_output, provision_output)
def test_blank_power_passwords(self): if daemons_running_externally(): raise SkipTest('cannot examine logs of remote beaker-provision') provision_process, = [p for p in processes if p.name == 'beaker-provision'] try: provision_process.start_output_capture() with session.begin(): system = data_setup.create_system(lab_controller=self.get_lc()) system.power.address = None system.power.power_type = PowerType.lazy_create(name=u'dummy') system.power.power_id = u'' # make power script not sleep system.power.power_passwd = None system.action_power(action=u'off', service=u'testdata') wait_for_commands_to_finish(system, timeout=2 * get_conf().get('SLEEP_TIME')) finally: provision_output = provision_process.finish_output_capture() # The None type is passed in from the db. Later in the code it is converted # to the empty string, as it should be. self.assertIn("'passwd': None", provision_output, provision_output)