Beispiel #1
0
    def setUp(self):
        # Restore current working directory.
        # Executor._create_testrun_folder changes it in some tests.
        self._original_cwd = os.getcwd()

        from ots.worker.conductor.executor import Executor as Executor
        from ots.worker.conductor.executor import TestRunData as TestRunData
        self.workdir = tempfile.mkdtemp("_test_conductor")
        self.testrun = TestRunData(Options(),
                                   config=_conductor_config_simple())
        self.testrun.workdir = self.workdir  #inject our temp folder
        responseclient = None
        stand_alone = True
        self.executor = Mock_Executor(self.testrun,
                                      stand_alone,
                                      responseclient,
                                      hostname="hostname",
                                      testrun_timeout=60)
        #NOTE!! STUBBED OUT so far:
        #_test_execution_error_handler
        #_store_test_definition
        #_get_command_for_testrunner

        responseclient = Stub_ResponseClient("", "", 0)
        self.real_executor = Executor(self.testrun, stand_alone,
                                      responseclient, "hostname")
Beispiel #2
0
    def setUp(self):
        from ots.worker.conductor.executor import TestRunData
        from ots.worker.conductor.executor import Executor
        from ots.worker.conductor.conductor import ExecutorSignalHandler
        from StringIO import StringIO

        testrun = TestRunData(Options(), config=_conductor_config_simple())
        self.workdir = tempfile.mkdtemp("_test_conductor")
        testrun.base_dir = self.workdir
        responseclient = Stub_ResponseClient("", "", 0)
        self.executor = Executor(testrun=testrun,
                                 stand_alone=True,
                                 responseclient=responseclient,
                                 hostname="hostname")
        self.executor.set_target()

        self.executor_signal_handler = ExecutorSignalHandler(self.executor)
        self.process_listed_info_commands_called = False

        self.logger = logging.getLogger('conductor')
        self.log_stream = StringIO()

        self.logger.setLevel(logging.WARNING)
        self.logger.addHandler(logging.StreamHandler(self.log_stream))

        self.flash_logger = logging.getLogger('default_flasher')
        self.flash_log_stream = StringIO()
        self.flash_logger.setLevel(logging.DEBUG)
        self.flash_logger.addHandler(
            logging.StreamHandler(self.flash_log_stream))
Beispiel #3
0
    def setUp(self):
        from ots.worker.conductor.executor import TestRunData
        from ots.worker.conductor.executor import Executor
        from ots.worker.conductor.conductor import ExecutorSignalHandler
        from StringIO import StringIO

        testrun = TestRunData(Options(), config=_conductor_config_simple())
        self.workdir = tempfile.mkdtemp("_test_conductor")
        testrun.base_dir = self.workdir
        responseclient = Stub_ResponseClient("", "", 0)
        self.executor = Executor(testrun=testrun, stand_alone=True, responseclient=responseclient, hostname="hostname")
        self.executor.set_target()

        self.executor_signal_handler = ExecutorSignalHandler(self.executor)
        self.process_listed_info_commands_called = False

        self.logger = logging.getLogger("conductor")
        self.log_stream = StringIO()

        self.logger.setLevel(logging.WARNING)
        self.logger.addHandler(logging.StreamHandler(self.log_stream))

        self.flash_logger = logging.getLogger("default_flasher")
        self.flash_log_stream = StringIO()
        self.flash_logger.setLevel(logging.DEBUG)
        self.flash_logger.addHandler(logging.StreamHandler(self.flash_log_stream))
Beispiel #4
0
def main():
    """ Main function """

    (options, parser) = _parse_command_line(sys.argv[1:])
    if not _check_command_line_options(options):
        parser.print_help()
        sys.exit(1)

    stand_alone = not options.testrun_id and not options.otsserver

    device_n = 0
    if options.device_n:
        device_n = options.device_n
    _setup_logging(options.verbose, device_n)

    responseclient = None

    if not stand_alone:
        responseclient = _initialize_remote_connections(options.otsserver,
                                                        options.testrun_id,
                                                        device_n)
        if not responseclient:
            sys.exit(1)

    LOG.debug(70*"=") #for log file
    LOG.info("Starting conductor at %s" % gethostname())
    LOG.info("Incoming command line parameters: %s" \
                % " ".join([arg for arg in sys.argv[1:]]))
    LOG.debug("os.getenv('USERNAME') = %s" % os.getenv('USERNAME'))
    LOG.debug("os.environ.get('HOME') = %s" % os.environ.get("HOME"))
    LOG.debug("os.getcwd() = %s" % os.getcwd())

    LOG.debug("Reading configuration file")

    config = _read_configuration_files(options.config_file, device_n)

    try:
        timeout = float(options.timeout)
        testrun = TestRunData(options, config)
        executor = Executor(testrun, stand_alone, responseclient, \
                            gethostname(), timeout)
        executor.set_target()
    except ValueError, err:
        LOG.error("Error: %s" % err)
        sys.exit(1)
Beispiel #5
0
def main():
    """ Main function """

    (options, parser) = _parse_command_line(sys.argv[1:])
    if not _check_command_line_options(options):
        parser.print_help()
        sys.exit(1)

    stand_alone = not options.testrun_id and not options.otsserver

    device_n = 0
    if options.device_n:
        device_n = options.device_n
    _setup_logging(options.verbose, device_n)

    responseclient = None

    if not stand_alone:
        responseclient = _initialize_remote_connections(
            options.otsserver, options.testrun_id, device_n)
        if not responseclient:
            sys.exit(1)

    LOG.debug(70 * "=")  #for log file
    LOG.info("Starting conductor at %s" % gethostname())
    LOG.info("Incoming command line parameters: %s" \
                % " ".join([arg for arg in sys.argv[1:]]))
    LOG.debug("os.getenv('USERNAME') = %s" % os.getenv('USERNAME'))
    LOG.debug("os.environ.get('HOME') = %s" % os.environ.get("HOME"))
    LOG.debug("os.getcwd() = %s" % os.getcwd())

    LOG.debug("Reading configuration file")

    config = _read_configuration_files(options.config_file, device_n)

    try:
        timeout = float(options.timeout)
        testrun = TestRunData(options, config)
        executor = Executor(testrun, stand_alone, responseclient, \
                            gethostname(), timeout)
        executor.set_target()
    except ValueError, err:
        LOG.error("Error: %s" % err)
        sys.exit(1)
Beispiel #6
0
    def setUp(self):
        # Restore current working directory.
        # Executor._create_testrun_folder changes it in some tests.
        self._original_cwd = os.getcwd()

        from ots.worker.conductor.executor import Executor as Executor
        from ots.worker.conductor.executor import TestRunData as TestRunData

        self.workdir = tempfile.mkdtemp("_test_conductor")
        self.testrun = TestRunData(Options(), config=_conductor_config_simple())
        self.testrun.workdir = self.workdir  # inject our temp folder
        responseclient = None
        stand_alone = True
        self.executor = Mock_Executor(
            self.testrun, stand_alone, responseclient, hostname="hostname", testrun_timeout=60
        )
        # NOTE!! STUBBED OUT so far:
        # _test_execution_error_handler
        # _store_test_definition
        # _get_command_for_testrunner

        responseclient = Stub_ResponseClient("", "", 0)
        self.real_executor = Executor(self.testrun, stand_alone, responseclient, "hostname")
Beispiel #7
0
class TestExecutorSignalHandler(unittest.TestCase):
    """Tests for ExecutorSignalHandler"""

    def setUp(self):
        from ots.worker.conductor.executor import TestRunData
        from ots.worker.conductor.executor import Executor
        from ots.worker.conductor.conductor import ExecutorSignalHandler
        from StringIO import StringIO

        testrun = TestRunData(Options(), config=_conductor_config_simple())
        self.workdir = tempfile.mkdtemp("_test_conductor")
        testrun.base_dir = self.workdir
        responseclient = Stub_ResponseClient("", "", 0)
        self.executor = Executor(testrun=testrun, stand_alone=True, responseclient=responseclient, hostname="hostname")
        self.executor.set_target()

        self.executor_signal_handler = ExecutorSignalHandler(self.executor)
        self.process_listed_info_commands_called = False

        self.logger = logging.getLogger("conductor")
        self.log_stream = StringIO()

        self.logger.setLevel(logging.WARNING)
        self.logger.addHandler(logging.StreamHandler(self.log_stream))

        self.flash_logger = logging.getLogger("default_flasher")
        self.flash_log_stream = StringIO()
        self.flash_logger.setLevel(logging.DEBUG)
        self.flash_logger.addHandler(logging.StreamHandler(self.flash_log_stream))

    #
    # Tests
    #

    def test_skips_reboot_if_no_testrunner_lite_running(self):
        self._send_sigusr1()
        self.assertTrue(self.log_stream.getvalue().find("SIGUSR1 caught but no testrunner-lite running") >= 0)

    def test_reboots_device(self):
        self._prepare_executor_mocks()
        self._send_sigusr1()
        self.assertTrue(self.executor.testrun.flasher_module.device_rebooted)
        self.assertEquals(self.executor.trlite_command.signal_sent, signal.SIGUSR1)

    def test_sends_sigterm_on_connection_test_failed(self):
        self._prepare_executor_mocks()
        self.executor.testrun.flasher_module = Mock_Flasher(FlashFailed("Testing"))
        self.executor.target._flasher = self.executor.testrun.flasher_module
        self._send_sigusr1()
        self.assertTrue(self.executor.testrun.flasher_module.device_rebooted)
        self.assertEquals(self.executor.trlite_command.signal_sent, signal.SIGTERM)

    def test_save_environment_details_after_reboot(self):
        self._prepare_executor_mocks()
        self._send_sigusr1()
        self.assertTrue(self.save_environment_details)
        pass

    #
    # Private methods
    #

    def _send_sigusr1(self):
        self.executor_signal_handler.reboot_device(sig_num=signal.SIGUSR1, frame=None)

    def _prepare_executor_mocks(self):
        self.executor.trlite_command = Mock_Command("#echo Mocked Command")
        self.executor.testrun.flasher_module = Mock_Flasher()
        self.executor.target._flasher = self.executor.testrun.flasher_module
        self.executor.save_environment_details = self._save_env_details_mock

    def _save_env_details_mock(self):
        self.save_environment_details = True
Beispiel #8
0
class TestExecutor(unittest.TestCase):
    """
    Tests for Executor class and executor file.
    responseclient = None, stand_alone = True
    """

    def setUp(self):
        # Restore current working directory.
        # Executor._create_testrun_folder changes it in some tests.
        self._original_cwd = os.getcwd()

        from ots.worker.conductor.executor import Executor as Executor
        from ots.worker.conductor.executor import TestRunData as TestRunData

        self.workdir = tempfile.mkdtemp("_test_conductor")
        self.testrun = TestRunData(Options(), config=_conductor_config_simple())
        self.testrun.workdir = self.workdir  # inject our temp folder
        responseclient = None
        stand_alone = True
        self.executor = Mock_Executor(
            self.testrun, stand_alone, responseclient, hostname="hostname", testrun_timeout=60
        )
        # NOTE!! STUBBED OUT so far:
        # _test_execution_error_handler
        # _store_test_definition
        # _get_command_for_testrunner

        responseclient = Stub_ResponseClient("", "", 0)
        self.real_executor = Executor(self.testrun, stand_alone, responseclient, "hostname")

    def tearDown(self):
        subprocess.call("rm -rf " + self.workdir, shell=True)  # created in setUp
        os.chdir(self._original_cwd)

    def test_run_tests_returns_true(self):
        """Test for _run_tests method when testrunner command succeeds"""
        self.testrun.base_dir = self.workdir  # inject our temp folder
        path = self.workdir
        test_package = "my-tests"
        executor = Mock_Executor(self.testrun, True, None, hostname="hostname", testrun_timeout=60)
        expected_stdout_file = os.path.join(path, "%s_testrunner_stdout.txt" % test_package)
        expected_stderr_file = os.path.join(path, "%s_testrunner_stderr.txt" % test_package)
        # check that files do not exist yet
        self.assertFalse(os.path.isfile(expected_stdout_file))
        self.assertFalse(os.path.isfile(expected_stderr_file))
        status = executor._run_tests(test_package, time.time(), time.time() + 1)
        # check that _run_tests returned True
        self.assertTrue(status is True)
        # check that files were created
        self.assertTrue(os.path.isfile(expected_stdout_file))
        self.assertTrue(os.path.isfile(expected_stderr_file))

    def test_run_tests_returns_false(self):
        """Test for _run_tests method when testrunner command succeeds"""
        self.testrun.base_dir = self.workdir  # inject our temp folder
        path = self.workdir
        test_package = "my-tests"
        executor = Mock_Executor(self.testrun, True, None, hostname="hostname", testrun_timeout=60)
        status = executor._run_tests(test_package, 0, 60)
        expected_stdout_file = os.path.join(path, "%s_testrunner_stdout.txt" % test_package)
        expected_stderr_file = os.path.join(path, "%s_testrunner_stderr.txt" % test_package)
        # check that _run_tests returned False
        self.assertTrue(status is False)

    def test_run_tests_returns_false_with_timeout(self):
        """Test for _run_tests method when testrunner command succeeds"""
        self.testrun.base_dir = self.workdir  # inject our temp folder
        path = self.workdir
        test_package = "my-tests"
        executor = Mock_Executor_with_cmd(self.testrun, True, None, hostname="hostname", testrun_timeout=1)
        expected_stdout_file = os.path.join(path, "%s_testrunner_stdout.txt" % test_package)
        expected_stderr_file = os.path.join(path, "%s_testrunner_stderr.txt" % test_package)
        timer = time.time()
        status = executor._run_tests(test_package, timer, timer)
        # check that _run_tests returned True
        self.assertTrue(status is False)

    def _test_run_tests_2(self):  # TODO TEST DISABLED until testrunner_command can be injected to Mock_Executor
        """Test for _run_tests method when testrunner command fails"""
        testrunner_command = 'sh -c "exit 1"'
        executor = Mock_Executor(self.testrun, self.stand_alone, self.responseclient, "hostname", testrunner_command)
        executor.target = Stub_Hardware()
        self.testrun.base_dir = self.workdir
        # self.assertFalse(os.path.exists(...)) #files do not exist yet
        test_package = "my-tests"
        self.assertRaises(ConductorError, executor._run_tests, test_package)
        # TODO check that files were created

    def test_set_target_when_debian(self):
        from ots.worker.conductor.hardware import Hardware as Hardware

        self.executor.set_target()
        self.assertTrue(isinstance(self.executor.target, Hardware))
        self.assertEquals(str(self.executor.target), "Hardware")
        self.assertEquals(self.executor.env, "Hardware")

    def test_set_target_when_rpm(self):
        from ots.worker.conductor.hardware import RPMHardware as RPMHardware

        self.testrun.config["device_packaging"] = "rpm"
        self.executor.set_target()
        self.assertTrue(isinstance(self.executor.target, RPMHardware))
        self.assertEquals(str(self.executor.target), "Hardware")
        self.assertEquals(self.executor.env, "Hardware")

    def test_set_target_when_hostbased(self):
        self.executor.testrun.is_host_based = True
        self.executor.set_target()
        self.assertEquals(str(self.executor.target), "Hardware")
        self.assertEquals(self.executor.env, "Host_Hardware")

    def test_execute_tests(self):
        # NOTE: This test goes through lots of code by calling many private methods.
        # But this test does not check which code was actually executed.
        self.testrun.id = "1"
        self.executor.env = "testenvironment"
        self.executor.target = Stub_Hardware()
        self.executor.chroot = Chroot(self.testrun)

        timestamp = time.strftime("%y%m%d-%H%M%S")

        # test_package must match to string in Stub_Hardware
        test_package = "mypackage-test"

        path = os.path.join(self.workdir, "conductor", self.testrun.id + "_%s" % (timestamp), self.executor.env)
        expected_stdout_file = os.path.join(path, "%s_testrunner_stdout.txt" % test_package)
        expected_stderr_file = os.path.join(path, "%s_testrunner_stderr.txt" % test_package)
        expected_env_info_file = os.path.join(path, "%s_environment_before_testing.txt" % self.executor.target)

        # Check that files do not exist yet
        self.assertFalse(os.path.isfile(expected_stdout_file))
        self.assertFalse(os.path.isfile(expected_stderr_file))
        self.assertFalse(os.path.isfile(expected_env_info_file))

        errors = self.executor.execute_tests()  # Here's the code to be tested.

        self.assertEquals(errors, 0)

        # Check that files were created.
        self.assertTrue(os.path.isfile(expected_stdout_file))
        self.assertTrue(os.path.isfile(expected_stderr_file))
        self.assertTrue(os.path.isfile(expected_env_info_file))

    def test_default_ssh_command_executor(self):
        # Successful command, should not raise exception
        cmd = self.executor._default_ssh_command_executor("ls", "my task")
        self.assertTrue(isinstance(cmd, Command))
        self.assertEquals(cmd.return_value, 0)

        # Commands raising ConductorError (Note: error_code is not checked!)
        self.assertRaises(ConductorError, self.executor._default_ssh_command_executor, "nonexistingcommand", "")
        self.assertRaises(ConductorError, self.executor._default_ssh_command_executor, "sleep 2", "", 1)  # test timeout
        self.assertRaises(ConductorError, self.executor._default_ssh_command_executor, 'sh -c "exit 1"', "")
        self.assertRaises(ConductorError, self.executor._default_ssh_command_executor, 'sh -c "exit 127"', "")
        self.assertRaises(ConductorError, self.executor._default_ssh_command_executor, 'sh -c "exit 128"', "")
        self.assertRaises(ConductorError, self.executor._default_ssh_command_executor, 'sh -c "exit 129"', "")
        self.assertRaises(ConductorError, self.executor._default_ssh_command_executor, 'sh -c "exit 255"', "")

    def test_ssh_command_exception_handler(self):
        # Tests for CommandFailed
        exc = CommandFailed()
        cmd = Stub_Command("", return_value=1)
        self.assertRaises(ConductorError, self.executor._ssh_command_exception_handler, exc, cmd, "")
        cmd = Stub_Command("", return_value=127)
        self.assertRaises(ConductorError, self.executor._ssh_command_exception_handler, exc, cmd, "")
        cmd = Stub_Command("", return_value=128)
        self.assertRaises(ConductorError, self.executor._ssh_command_exception_handler, exc, cmd, "")
        cmd = Stub_Command("", return_value=129)
        self.assertRaises(ConductorError, self.executor._ssh_command_exception_handler, exc, cmd, "")
        cmd = Stub_Command("", return_value=255)
        self.assertRaises(ConductorError, self.executor._ssh_command_exception_handler, exc, cmd, "")

        # Tests for not to raise exception with exit code other than 129-255
        cmd = Stub_Command("", return_value=1)
        self.executor._ssh_command_exception_handler(exc, cmd, "", ignore_normal_CommandFailed=True)
        cmd = Stub_Command("", return_value=127)
        self.executor._ssh_command_exception_handler(exc, cmd, "", ignore_normal_CommandFailed=True)
        cmd = Stub_Command("", return_value=128)
        self.executor._ssh_command_exception_handler(exc, cmd, "", ignore_normal_CommandFailed=True)

        # Tests for ignore_normal_CommandFailed flag not to have effect with exit codes 129-255
        cmd = Stub_Command("", return_value=129)
        self.assertRaises(
            ConductorError, self.executor._ssh_command_exception_handler, exc, cmd, "", ignore_normal_CommandFailed=True
        )
        cmd = Stub_Command("", return_value=255)
        self.assertRaises(
            ConductorError, self.executor._ssh_command_exception_handler, exc, cmd, "", ignore_normal_CommandFailed=True
        )

        # Tests for SoftTimeoutException and HardTimeOutException
        exc = SoftTimeoutException()
        cmd = Stub_Command("")
        self.assertRaises(ConductorError, self.executor._ssh_command_exception_handler, exc, cmd, "")
        exc = HardTimeoutException()
        cmd = Stub_Command("")
        self.assertRaises(ConductorError, self.executor._ssh_command_exception_handler, exc, cmd, "")

    def test_get_command_for_testrunner_normal_ssh(self):
        """Test for method when we should execute tests over ssh at device"""
        executor = self.real_executor
        executor.stand_alone = False
        command = executor._get_command_for_testrunner()
        self._assertCommandContains(command, "testrunner-lite")
        self._assertCommandContains(command, "[email protected]")
        self._assertCommandContains(command, "logger")

    def test_get_command_for_testrunner_libssh2(self):
        """Test for method when we should execute tests over ssh at device
        using libssh2"""
        executor = self.real_executor
        executor.stand_alone = False
        self.testrun.use_libssh2 = True
        command = executor._get_command_for_testrunner()
        self._assertCommandContains(command, "testrunner-lite")
        self._assertCommandContains(command, "logger")
        self._assertCommandContains(command, "-n [email protected] -k /var/opt/eat/sshkey-host/id_eat_dsa")
        self._assertCommandDoesNotContain(command, "-t [email protected]")

    def test_get_command_for_testrunner_resume_continue(self):
        """Test for method when we should execute tests over ssh at device
        using resume functionality"""
        executor = self.real_executor
        executor.stand_alone = False
        self.testrun.resume = True
        command = executor._get_command_for_testrunner()
        self._assertCommandContains(command, "testrunner-lite")
        self._assertCommandContains(command, "logger")
        self._assertCommandContains(command, "--resume=continue")
        self._assertCommandDoesNotContain(command, "--resume=exit")

    def test_get_command_for_testrunner_resume_exit(self):
        """Test for method when we should execute tests over ssh at device
        using resume functionality"""
        executor = self.real_executor
        executor.stand_alone = False
        command = executor._get_command_for_testrunner()
        self._assertCommandContains(command, "testrunner-lite")
        self._assertCommandContains(command, "logger")
        self._assertCommandContains(command, "--resume=exit")
        self._assertCommandDoesNotContain(command, "--resume=continue")

    def test_get_command_for_testrunner_2(self):
        """Test for method when we should execute tests at device, standalone."""
        executor = self.real_executor
        command = executor._get_command_for_testrunner()
        self._assertCommandContains(command, "testrunner-lite")
        self._assertCommandContains(command, "[email protected]")
        self._assertCommandDoesNotContain(command, "logger")  # should not be found

    def test_get_command_for_testrunner_host_based_1(self):
        """Test for method when we should execute tests at host"""
        executor = self.real_executor
        executor.stand_alone = False
        self.testrun.is_host_based = True  # expose more code for testing
        command = executor._get_command_for_testrunner()
        self._assertCommandContains(command, "testrunner-lite")
        self._assertCommandDoesNotContain(command, "[email protected]")  # should not be found
        self._assertCommandContains(command, "logger")

    def test_get_command_for_testrunner_host_based_2(self):
        """Test for method when we should execute tests at host, standalone"""
        executor = self.real_executor
        self.testrun.is_host_based = True  # expose more code for testing
        command = executor._get_command_for_testrunner()
        self._assertCommandContains(command, "testrunner-lite")
        self._assertCommandDoesNotContain(command, "[email protected]")  # should not be found
        self._assertCommandDoesNotContain(command, "logger")  # should not be found

    def test_testrunner_lite_error_handler(self):
        self.assertRaises(ConductorError, self.executor._testrunner_lite_error_handler, "", 1)
        self.assertRaises(ConductorError, self.executor._testrunner_lite_error_handler, "", 2)
        self.assertRaises(ConductorError, self.executor._testrunner_lite_error_handler, "", 3)
        self.assertRaises(ConductorError, self.executor._testrunner_lite_error_handler, "", 4)
        self.assertRaises(ConductorError, self.executor._testrunner_lite_error_handler, "", 5)
        self.assertRaises(ConductorError, self.executor._testrunner_lite_error_handler, "", 6)
        self.assertRaises(ConductorError, self.executor._testrunner_lite_error_handler, "", 7)

    def test_items_missing_from_all_items(self):
        from ots.worker.conductor.executor import items_missing_from_all_items

        missing = items_missing_from_all_items(["z"], ["x", "y"])
        self.assertEquals(missing, ["z"])
        missing = items_missing_from_all_items([], ["x", "y"])
        self.assertEquals(missing, [])
        missing = items_missing_from_all_items([], [])
        self.assertEquals(missing, [])
        missing = items_missing_from_all_items(["x", "y"], [])
        self.assertEquals(missing, ["x", "y"])

    def test_include_testrun_log_file(self):
        self.assertTrue(self.real_executor._include_testrun_log_file() in [0, 1])

    def test_load_flasher_plugin_default(self):

        self.testrun.target_flasher = ""
        executor = Mock_Executor(self.testrun, True, None, hostname="hostname", testrun_timeout=60)
        executor._load_flasher_module()
        flasher = executor.testrun.flasher_module()
        self.assertTrue(isinstance(flasher, FlasherPluginBase))

    def _assertCommandContains(self, command, text):
        self.assertTrue(command.find(text) != -1, "Did not find '%s' in '%s'" % (text, command))

    def _assertCommandDoesNotContain(self, command, text):
        self.assertTrue(command.find(text) == -1, "Found '%s' in '%s'" % (text, command))
Beispiel #9
0
class TestExecutor(unittest.TestCase):
    """
    Tests for Executor class and executor file.
    responseclient = None, stand_alone = True
    """
    def setUp(self):
        # Restore current working directory.
        # Executor._create_testrun_folder changes it in some tests.
        self._original_cwd = os.getcwd()

        from ots.worker.conductor.executor import Executor as Executor
        from ots.worker.conductor.executor import TestRunData as TestRunData
        self.workdir = tempfile.mkdtemp("_test_conductor")
        self.testrun = TestRunData(Options(),
                                   config=_conductor_config_simple())
        self.testrun.workdir = self.workdir  #inject our temp folder
        responseclient = None
        stand_alone = True
        self.executor = Mock_Executor(self.testrun,
                                      stand_alone,
                                      responseclient,
                                      hostname="hostname",
                                      testrun_timeout=60)
        #NOTE!! STUBBED OUT so far:
        #_test_execution_error_handler
        #_store_test_definition
        #_get_command_for_testrunner

        responseclient = Stub_ResponseClient("", "", 0)
        self.real_executor = Executor(self.testrun, stand_alone,
                                      responseclient, "hostname")

    def tearDown(self):
        subprocess.call("rm -rf " + self.workdir,
                        shell=True)  #created in setUp
        os.chdir(self._original_cwd)

    def test_run_tests_returns_true(self):
        """Test for _run_tests method when testrunner command succeeds"""
        self.testrun.base_dir = self.workdir  #inject our temp folder
        path = self.workdir
        test_package = "my-tests"
        executor = Mock_Executor(self.testrun,
                                 True,
                                 None,
                                 hostname="hostname",
                                 testrun_timeout=60)
        expected_stdout_file = os.path.join(
            path, "%s_testrunner_stdout.txt" % test_package)
        expected_stderr_file = os.path.join(
            path, "%s_testrunner_stderr.txt" % test_package)
        #check that files do not exist yet
        self.assertFalse(os.path.isfile(expected_stdout_file))
        self.assertFalse(os.path.isfile(expected_stderr_file))
        status = executor._run_tests(test_package, time.time(),
                                     time.time() + 1)
        #check that _run_tests returned True
        self.assertTrue(status is True)
        #check that files were created
        self.assertTrue(os.path.isfile(expected_stdout_file))
        self.assertTrue(os.path.isfile(expected_stderr_file))

    def test_run_tests_returns_false(self):
        """Test for _run_tests method when testrunner command succeeds"""
        self.testrun.base_dir = self.workdir  #inject our temp folder
        path = self.workdir
        test_package = "my-tests"
        executor = Mock_Executor(self.testrun,
                                 True,
                                 None,
                                 hostname="hostname",
                                 testrun_timeout=60)
        status = executor._run_tests(test_package, 0, 60)
        expected_stdout_file = os.path.join(
            path, "%s_testrunner_stdout.txt" % test_package)
        expected_stderr_file = os.path.join(
            path, "%s_testrunner_stderr.txt" % test_package)
        #check that _run_tests returned False
        self.assertTrue(status is False)

    def test_run_tests_returns_false_with_timeout(self):
        """Test for _run_tests method when testrunner command succeeds"""
        self.testrun.base_dir = self.workdir  #inject our temp folder
        path = self.workdir
        test_package = "my-tests"
        executor = Mock_Executor_with_cmd(self.testrun,
                                          True,
                                          None,
                                          hostname="hostname",
                                          testrun_timeout=1)
        expected_stdout_file = os.path.join(
            path, "%s_testrunner_stdout.txt" % test_package)
        expected_stderr_file = os.path.join(
            path, "%s_testrunner_stderr.txt" % test_package)
        timer = time.time()
        status = executor._run_tests(test_package, timer, timer)
        #check that _run_tests returned True
        self.assertTrue(status is False)

    def _test_run_tests_2(
        self
    ):  #TODO TEST DISABLED until testrunner_command can be injected to Mock_Executor
        """Test for _run_tests method when testrunner command fails"""
        testrunner_command = 'sh -c "exit 1"'
        executor = Mock_Executor(self.testrun, self.stand_alone,
                                 self.responseclient, "hostname",
                                 testrunner_command)
        executor.target = Stub_Hardware()
        self.testrun.base_dir = self.workdir
        #self.assertFalse(os.path.exists(...)) #files do not exist yet
        test_package = "my-tests"
        self.assertRaises(ConductorError, executor._run_tests, test_package)
        #TODO check that files were created

    def test_set_target_when_debian(self):
        from ots.worker.conductor.hardware import Hardware as Hardware
        self.executor.set_target()
        self.assertTrue(isinstance(self.executor.target, Hardware))
        self.assertEquals(str(self.executor.target), "Hardware")
        self.assertEquals(self.executor.env, "Hardware")

    def test_set_target_when_rpm(self):
        from ots.worker.conductor.hardware import RPMHardware as RPMHardware
        self.testrun.config['device_packaging'] = 'rpm'
        self.executor.set_target()
        self.assertTrue(isinstance(self.executor.target, RPMHardware))
        self.assertEquals(str(self.executor.target), "Hardware")
        self.assertEquals(self.executor.env, "Hardware")

    def test_set_target_when_hostbased(self):
        self.executor.testrun.is_host_based = True
        self.executor.set_target()
        self.assertEquals(str(self.executor.target), "Hardware")
        self.assertEquals(self.executor.env, "Host_Hardware")

    def test_execute_tests(self):
        #NOTE: This test goes through lots of code by calling many private methods.
        #But this test does not check which code was actually executed.
        self.testrun.id = "1"
        self.executor.env = "testenvironment"
        self.executor.target = Stub_Hardware()
        self.executor.chroot = Chroot(self.testrun)

        timestamp = time.strftime("%y%m%d-%H%M%S")

        #test_package must match to string in Stub_Hardware
        test_package = "mypackage-test"

        path = os.path.join(self.workdir, "conductor",
                            self.testrun.id + "_%s" % (timestamp),
                            self.executor.env)
        expected_stdout_file = \
                os.path.join(path, "%s_testrunner_stdout.txt" % test_package)
        expected_stderr_file = \
                os.path.join(path, "%s_testrunner_stderr.txt" % test_package)
        expected_env_info_file = os.path.join(path, \
                    "%s_environment_before_testing.txt" % self.executor.target)

        #Check that files do not exist yet
        self.assertFalse(os.path.isfile(expected_stdout_file))
        self.assertFalse(os.path.isfile(expected_stderr_file))
        self.assertFalse(os.path.isfile(expected_env_info_file))

        errors = self.executor.execute_tests()  #Here's the code to be tested.

        self.assertEquals(errors, 0)

        #Check that files were created.
        self.assertTrue(os.path.isfile(expected_stdout_file))
        self.assertTrue(os.path.isfile(expected_stderr_file))
        self.assertTrue(os.path.isfile(expected_env_info_file))

    def test_default_ssh_command_executor(self):
        #Successful command, should not raise exception
        cmd = self.executor._default_ssh_command_executor("ls", "my task")
        self.assertTrue(isinstance(cmd, Command))
        self.assertEquals(cmd.return_value, 0)

        #Commands raising ConductorError (Note: error_code is not checked!)
        self.assertRaises(ConductorError,
                          self.executor._default_ssh_command_executor,
                          "nonexistingcommand", "")
        self.assertRaises(ConductorError,
                          self.executor._default_ssh_command_executor,
                          "sleep 2", "", 1)  #test timeout
        self.assertRaises(ConductorError,
                          self.executor._default_ssh_command_executor,
                          'sh -c "exit 1"', "")
        self.assertRaises(ConductorError,
                          self.executor._default_ssh_command_executor,
                          'sh -c "exit 127"', "")
        self.assertRaises(ConductorError,
                          self.executor._default_ssh_command_executor,
                          'sh -c "exit 128"', "")
        self.assertRaises(ConductorError,
                          self.executor._default_ssh_command_executor,
                          'sh -c "exit 129"', "")
        self.assertRaises(ConductorError,
                          self.executor._default_ssh_command_executor,
                          'sh -c "exit 255"', "")

    def test_ssh_command_exception_handler(self):
        #Tests for CommandFailed
        exc = CommandFailed()
        cmd = Stub_Command("", return_value=1)
        self.assertRaises(ConductorError,
                          self.executor._ssh_command_exception_handler, exc,
                          cmd, "")
        cmd = Stub_Command("", return_value=127)
        self.assertRaises(ConductorError,
                          self.executor._ssh_command_exception_handler, exc,
                          cmd, "")
        cmd = Stub_Command("", return_value=128)
        self.assertRaises(ConductorError,
                          self.executor._ssh_command_exception_handler, exc,
                          cmd, "")
        cmd = Stub_Command("", return_value=129)
        self.assertRaises(ConductorError,
                          self.executor._ssh_command_exception_handler, exc,
                          cmd, "")
        cmd = Stub_Command("", return_value=255)
        self.assertRaises(ConductorError,
                          self.executor._ssh_command_exception_handler, exc,
                          cmd, "")

        #Tests for not to raise exception with exit code other than 129-255
        cmd = Stub_Command("", return_value=1)
        self.executor._ssh_command_exception_handler(
            exc, cmd, "", ignore_normal_CommandFailed=True)
        cmd = Stub_Command("", return_value=127)
        self.executor._ssh_command_exception_handler(
            exc, cmd, "", ignore_normal_CommandFailed=True)
        cmd = Stub_Command("", return_value=128)
        self.executor._ssh_command_exception_handler(
            exc, cmd, "", ignore_normal_CommandFailed=True)

        #Tests for ignore_normal_CommandFailed flag not to have effect with exit codes 129-255
        cmd = Stub_Command("", return_value=129)
        self.assertRaises(ConductorError,
                          self.executor._ssh_command_exception_handler,
                          exc,
                          cmd,
                          "",
                          ignore_normal_CommandFailed=True)
        cmd = Stub_Command("", return_value=255)
        self.assertRaises(ConductorError,
                          self.executor._ssh_command_exception_handler,
                          exc,
                          cmd,
                          "",
                          ignore_normal_CommandFailed=True)

        #Tests for SoftTimeoutException and HardTimeOutException
        exc = SoftTimeoutException()
        cmd = Stub_Command("")
        self.assertRaises(ConductorError,
                          self.executor._ssh_command_exception_handler, exc,
                          cmd, "")
        exc = HardTimeoutException()
        cmd = Stub_Command("")
        self.assertRaises(ConductorError,
                          self.executor._ssh_command_exception_handler, exc,
                          cmd, "")

    def test_get_command_for_testrunner_normal_ssh(self):
        """Test for method when we should execute tests over ssh at device"""
        executor = self.real_executor
        executor.stand_alone = False
        command = executor._get_command_for_testrunner()
        self._assertCommandContains(command, "testrunner-lite")
        self._assertCommandContains(command, "[email protected]")
        self._assertCommandContains(command, "logger")

    def test_get_command_for_testrunner_libssh2(self):
        """Test for method when we should execute tests over ssh at device
        using libssh2"""
        executor = self.real_executor
        executor.stand_alone = False
        self.testrun.use_libssh2 = True
        command = executor._get_command_for_testrunner()
        self._assertCommandContains(command, "testrunner-lite")
        self._assertCommandContains(command, "logger")
        self._assertCommandContains(
            command,
            "-n [email protected] -k /var/opt/eat/sshkey-host/id_eat_dsa")
        self._assertCommandDoesNotContain(command, "-t [email protected]")

    def test_get_command_for_testrunner_resume_continue(self):
        """Test for method when we should execute tests over ssh at device
        using resume functionality"""
        executor = self.real_executor
        executor.stand_alone = False
        self.testrun.resume = True
        command = executor._get_command_for_testrunner()
        self._assertCommandContains(command, "testrunner-lite")
        self._assertCommandContains(command, "logger")
        self._assertCommandContains(command, "--resume=continue")
        self._assertCommandDoesNotContain(command, "--resume=exit")

    def test_get_command_for_testrunner_resume_exit(self):
        """Test for method when we should execute tests over ssh at device
        using resume functionality"""
        executor = self.real_executor
        executor.stand_alone = False
        command = executor._get_command_for_testrunner()
        self._assertCommandContains(command, "testrunner-lite")
        self._assertCommandContains(command, "logger")
        self._assertCommandContains(command, "--resume=exit")
        self._assertCommandDoesNotContain(command, "--resume=continue")

    def test_get_command_for_testrunner_2(self):
        """Test for method when we should execute tests at device, standalone."""
        executor = self.real_executor
        command = executor._get_command_for_testrunner()
        self._assertCommandContains(command, "testrunner-lite")
        self._assertCommandContains(command, "[email protected]")
        self._assertCommandDoesNotContain(command,
                                          "logger")  #should not be found

    def test_get_command_for_testrunner_host_based_1(self):
        """Test for method when we should execute tests at host"""
        executor = self.real_executor
        executor.stand_alone = False
        self.testrun.is_host_based = True  #expose more code for testing
        command = executor._get_command_for_testrunner()
        self._assertCommandContains(command, "testrunner-lite")
        self._assertCommandDoesNotContain(
            command, "[email protected]")  #should not be found
        self._assertCommandContains(command, "logger")

    def test_get_command_for_testrunner_host_based_2(self):
        """Test for method when we should execute tests at host, standalone"""
        executor = self.real_executor
        self.testrun.is_host_based = True  #expose more code for testing
        command = executor._get_command_for_testrunner()
        self._assertCommandContains(command, "testrunner-lite")
        self._assertCommandDoesNotContain(
            command, "[email protected]")  #should not be found
        self._assertCommandDoesNotContain(command,
                                          "logger")  #should not be found

    def test_testrunner_lite_error_handler(self):
        self.assertRaises(ConductorError,
                          self.executor._testrunner_lite_error_handler, "", 1)
        self.assertRaises(ConductorError,
                          self.executor._testrunner_lite_error_handler, "", 2)
        self.assertRaises(ConductorError,
                          self.executor._testrunner_lite_error_handler, "", 3)
        self.assertRaises(ConductorError,
                          self.executor._testrunner_lite_error_handler, "", 4)
        self.assertRaises(ConductorError,
                          self.executor._testrunner_lite_error_handler, "", 5)
        self.assertRaises(ConductorError,
                          self.executor._testrunner_lite_error_handler, "", 6)
        self.assertRaises(ConductorError,
                          self.executor._testrunner_lite_error_handler, "", 7)

    def test_items_missing_from_all_items(self):
        from ots.worker.conductor.executor import items_missing_from_all_items
        missing = items_missing_from_all_items(["z"], ["x", "y"])
        self.assertEquals(missing, ["z"])
        missing = items_missing_from_all_items([], ["x", "y"])
        self.assertEquals(missing, [])
        missing = items_missing_from_all_items([], [])
        self.assertEquals(missing, [])
        missing = items_missing_from_all_items(["x", "y"], [])
        self.assertEquals(missing, ["x", "y"])

    def test_include_testrun_log_file(self):
        self.assertTrue(
            self.real_executor._include_testrun_log_file() in [0, 1])

    def test_load_flasher_plugin_default(self):

        self.testrun.target_flasher = ""
        executor = Mock_Executor(self.testrun,
                                 True,
                                 None,
                                 hostname="hostname",
                                 testrun_timeout=60)
        executor._load_flasher_module()
        flasher = executor.testrun.flasher_module()
        self.assertTrue(isinstance(flasher, FlasherPluginBase))

    def _assertCommandContains(self, command, text):
        self.assertTrue(
            command.find(text) != -1,
            "Did not find '%s' in '%s'" % (text, command))

    def _assertCommandDoesNotContain(self, command, text):
        self.assertTrue(
            command.find(text) == -1, "Found '%s' in '%s'" % (text, command))
Beispiel #10
0
class TestExecutorSignalHandler(unittest.TestCase):
    """Tests for ExecutorSignalHandler"""
    def setUp(self):
        from ots.worker.conductor.executor import TestRunData
        from ots.worker.conductor.executor import Executor
        from ots.worker.conductor.conductor import ExecutorSignalHandler
        from StringIO import StringIO

        testrun = TestRunData(Options(), config=_conductor_config_simple())
        self.workdir = tempfile.mkdtemp("_test_conductor")
        testrun.base_dir = self.workdir
        responseclient = Stub_ResponseClient("", "", 0)
        self.executor = Executor(testrun=testrun,
                                 stand_alone=True,
                                 responseclient=responseclient,
                                 hostname="hostname")
        self.executor.set_target()

        self.executor_signal_handler = ExecutorSignalHandler(self.executor)
        self.process_listed_info_commands_called = False

        self.logger = logging.getLogger('conductor')
        self.log_stream = StringIO()

        self.logger.setLevel(logging.WARNING)
        self.logger.addHandler(logging.StreamHandler(self.log_stream))

        self.flash_logger = logging.getLogger('default_flasher')
        self.flash_log_stream = StringIO()
        self.flash_logger.setLevel(logging.DEBUG)
        self.flash_logger.addHandler(
            logging.StreamHandler(self.flash_log_stream))

    #
    # Tests
    #

    def test_skips_reboot_if_no_testrunner_lite_running(self):
        self._send_sigusr1()
        self.assertTrue(self.log_stream.getvalue().find( \
                "SIGUSR1 caught but no testrunner-lite running") >= 0)

    def test_reboots_device(self):
        self._prepare_executor_mocks()
        self._send_sigusr1()
        self.assertTrue(self.executor.testrun.flasher_module.device_rebooted)
        self.assertEquals(self.executor.trlite_command.signal_sent,
                          signal.SIGUSR1)

    def test_sends_sigterm_on_connection_test_failed(self):
        self._prepare_executor_mocks()
        self.executor.testrun.flasher_module = \
                            Mock_Flasher(FlashFailed("Testing"))
        self.executor.target._flasher = self.executor.testrun.flasher_module
        self._send_sigusr1()
        self.assertTrue(self.executor.testrun.flasher_module.device_rebooted)
        self.assertEquals(self.executor.trlite_command.signal_sent,
                          signal.SIGTERM)

    def test_save_environment_details_after_reboot(self):
        self._prepare_executor_mocks()
        self._send_sigusr1()
        self.assertTrue(self.save_environment_details)
        pass

    #
    # Private methods
    #

    def _send_sigusr1(self):
        self.executor_signal_handler.reboot_device(sig_num=signal.SIGUSR1,
                                                   frame=None)

    def _prepare_executor_mocks(self):
        self.executor.trlite_command = Mock_Command("#echo Mocked Command")
        self.executor.testrun.flasher_module = Mock_Flasher()
        self.executor.target._flasher = self.executor.testrun.flasher_module
        self.executor.save_environment_details = self._save_env_details_mock

    def _save_env_details_mock(self):
        self.save_environment_details = True