示例#1
0
    def test_query_all_nodes_swallows_Exception(self):
        node1, node2 = self.make_nodes(2)
        error_message = factory.make_name("error")
        error_type = factory.make_exception_type()
        new_state_2 = self.pick_alternate_state(node2["power_state"])
        get_power_state = self.patch(power, "get_power_state")
        get_power_state.side_effect = [
            fail(error_type(error_message)),
            succeed(new_state_2),
        ]
        suppress_reporting(self)

        maaslog = FakeLogger("maas.power", level=logging.DEBUG)
        twistlog = TwistedLoggerFixture()

        with maaslog, twistlog:
            yield power.query_all_nodes([node1, node2])

        self.assertDocTestMatches(
            """\
            hostname-...: Failed to refresh power state: %s
            hostname-...: Power state has changed from ... to ...
            """
            % error_message,
            maaslog.output,
        )
示例#2
0
 def test_upgrade_does_not_change_other_errors(self):
     error_type = factory.make_exception_type()
     error = error_type()
     self.expectThat(error, Not(IsInstance(ExternalProcessError)))
     ExternalProcessError.upgrade(error)
     self.expectThat(error, Not(IsInstance(ExternalProcessError)))
     self.expectThat(error.__class__, Is(error_type))
示例#3
0
    def test_secure_erase_sets_security_password_hdparm(self):
        tmp_dir = self.make_dir()
        dev_path = (tmp_dir + "/%s").encode("ascii")
        self.patch(maas_wipe, "DEV_PATH", dev_path)
        dev_name = factory.make_name("disk").encode("ascii")
        file_path = dev_path % dev_name
        self.make_empty_file(file_path)

        mock_check_output = self.patch(subprocess, "check_output")

        # Fail to get disk info just to exit early.
        exception_type = factory.make_exception_type()
        self.patch(
            maas_wipe, "get_hdparm_security_info"
        ).side_effect = exception_type()

        self.assertRaises(exception_type, secure_erase_hdparm, dev_name)
        self.assertThat(
            mock_check_output,
            MockCalledOnceWith(
                [
                    b"hdparm",
                    b"--user-master",
                    b"u",
                    b"--security-set-pass",
                    b"maas",
                    file_path,
                ]
            ),
        )
示例#4
0
    def test_refresh_clears_up_temporary_directory(self):

        ScriptsBroken = factory.make_exception_type()

        def find_temporary_directories():
            with tempfile.TemporaryDirectory() as tmpdir:
                tmpdir = Path(tmpdir).absolute()
                return {
                    str(entry)
                    for entry in tmpdir.parent.iterdir()
                    if entry.is_dir() and entry != tmpdir
                }

        tmpdirs_during = set()
        tmpdir_during = None

        def runscripts(*args, tmpdir):
            self.assertThat(tmpdir, DirExists())
            nonlocal tmpdirs_during, tmpdir_during
            tmpdirs_during |= find_temporary_directories()
            tmpdir_during = tmpdir
            raise ScriptsBroken("Foom")

        self.patch(refresh, "runscripts", runscripts)

        tmpdirs_before = find_temporary_directories()
        self.assertRaises(ScriptsBroken, refresh.refresh, sentinel.system_id,
                          sentinel.consumer_key, sentinel.token_key,
                          sentinel.token_secret)
        tmpdirs_after = find_temporary_directories()

        self.assertThat(tmpdirs_before, Not(Contains(tmpdir_during)))
        self.assertThat(tmpdirs_during, Contains(tmpdir_during))
        self.assertThat(tmpdirs_after, Not(Contains(tmpdir_during)))
示例#5
0
 def test_raises_last_exception_after_all_retries_fail(self):
     wait_time = [random.randrange(1, 10) for _ in range(3)]
     driver = make_power_driver(wait_time=wait_time)
     exception_types = list(
         factory.make_exception_type((PowerError, )) for _ in wait_time)
     self.patch(driver, "power_query").side_effect = exception_types
     with ExpectedException(exception_types[-1]):
         yield driver.query(sentinel.system_id, sentinel.context)
示例#6
0
 def test_upgrade_does_not_change_CalledProcessError_subclasses(self):
     error_type = factory.make_exception_type(bases=(CalledProcessError,))
     error = factory.make_CalledProcessError()
     error.__class__ = error_type  # Change the class.
     self.expectThat(error, Not(IsInstance(ExternalProcessError)))
     ExternalProcessError.upgrade(error)
     self.expectThat(error, Not(IsInstance(ExternalProcessError)))
     self.expectThat(error.__class__, Is(error_type))
示例#7
0
 def test_handles_driver_raising_any_Exception(self):
     fake_driver = MagicMock()
     fake_driver.name = factory.make_name("pod")
     fake_exception_type = factory.make_exception_type()
     fake_exception_msg = factory.make_name("error")
     fake_exception = fake_exception_type(fake_exception_msg)
     fake_driver.discover.return_value = fail(fake_exception)
     self.patch(PodDriverRegistry, "get_item").return_value = fake_driver
     with ExpectedException(
             exceptions.PodActionFail,
             re.escape("Failed talking to pod: " + fake_exception_msg)):
         yield pods.discover_pod(fake_driver.name, {})
示例#8
0
 def test_opened_configuration_file_does_not_save_on_unclean_exit(self):
     config_file = os.path.join(self.make_dir(), "config")
     config_key = factory.make_name("key")
     config_value = factory.make_name("value")
     exception_type = factory.make_exception_type()
     # Set a configuration option, then crash.
     with ExpectedException(exception_type):
         with ConfigurationFile.open_for_update(config_file) as config:
             config[config_key] = config_value
             raise exception_type()
     # No value has been saved for `config_key`.
     with ConfigurationFile.open(config_file) as config:
         self.assertRaises(KeyError, lambda: config[config_key])
示例#9
0
    def test__savepoint_restores_hooks_only_on_dirty_exit(self):
        d1 = Deferred()
        d2 = Deferred()
        dhooks = DeferredHooks()
        dhooks.add(d1)

        exception_type = factory.make_exception_type()
        with ExpectedException(exception_type):
            with dhooks.savepoint():
                dhooks.add(d2)
                raise exception_type()

        self.expectThat(list(dhooks.hooks), Equals([d1]))
示例#10
0
    def test__logs_errors(self):
        events = []
        namespace = factory.make_name("namespace")
        legacy_logger = LegacyLogger(namespace, self, events.append)
        message = factory.make_name("message")
        exception_type = factory.make_exception_type()
        keywords = {
            factory.make_name("key"): factory.make_name("value")
            for _ in range(3)
        }

        try:
            raise exception_type()
        except exception_type:
            legacy_logger.err(None, message, **keywords)

        expected = {
            'log_failure':
            MatchesAll(
                IsInstance(Failure),
                AfterPreprocessing(
                    (lambda failure: failure.value),
                    IsInstance(exception_type),
                ),
            ),
            'log_format':
            Equals('{_why}'),
            'log_level':
            Equals(logger.LogLevel.critical),
            'log_logger':
            Is(legacy_logger),
            'log_namespace':
            Equals(namespace),
            'log_source':
            Is(self),
            'log_time':
            IsInstance(float),
            '_why':
            Equals(message),
        }
        expected.update(
            {key: Equals(value)
             for key, value in keywords.items()})
        self.assertThat(events, HasLength(1))
        self.assertThat(events[0], MatchesDict(expected))
        # Twisted 16.6.0 (see issue #8858) now includes a traceback,
        # so we only match on the beginning of the string.
        self.assertThat(
            logger.formatEventAsClassicLogText(events[0], formatTimeStatic),
            StartsWith("<when> [%s#critical] %s\n" % (namespace, message)))
    def test_sync_does_propagate_ioerror(self):
        io_error = factory.make_exception_type(bases=(IOError, ))

        mock_sync = self.patch(download_descriptions.BasicMirrorWriter, "sync")
        mock_sync.side_effect = io_error()

        boot_images_dict = BootImageMapping()
        dumper = RepoDumper(boot_images_dict)

        with FakeLogger("maas.import-images", level=logging.INFO) as maaslog:
            self.assertRaises(io_error, dumper.sync, sentinel.reader,
                              sentinel.path)
            self.assertDocTestMatches("...error...syncing boot images...",
                                      maaslog.output)
示例#12
0
 def test_handles_driver_raising_any_Exception(self):
     fake_driver = MagicMock()
     fake_driver.name = factory.make_name("pod")
     fake_exception_type = factory.make_exception_type()
     fake_exception_msg = factory.make_name("error")
     fake_exception = fake_exception_type(fake_exception_msg)
     fake_driver.decompose.return_value = fail(fake_exception)
     pod_id = random.randint(1, 10)
     pod_name = factory.make_name("pod")
     self.patch(PodDriverRegistry, "get_item").return_value = fake_driver
     with ExpectedException(
             exceptions.PodActionFail,
             re.escape("Failed talking to pod: " + fake_exception_msg)):
         yield pods.decompose_machine(fake_driver.name, {},
                                      pod_id=pod_id,
                                      name=pod_name)
示例#13
0
    def test_failure_in_added_task_does_not_crash_service(self):
        things = []  # This will be populated by tasks.
        exception_type = factory.make_exception_type()

        def be_bad():
            raise exception_type("I'm bad, so bad.")

        service = DatabaseTasksService()
        service.startService()
        try:
            service.addTask(things.append, 1)
            service.addTask(be_bad)
            service.addTask(things.append, 2)
        finally:
            service.stopService()

        self.assertThat(things, Equals([1, 2]))
示例#14
0
    def test_failure_in_deferred_task_does_not_crash_service(self):
        things = []  # This will be populated by tasks.
        exception_type = factory.make_exception_type()

        def be_bad():
            raise exception_type("I'm being very naughty.")

        service = DatabaseTasksService()
        service.startService()
        try:
            service.deferTask(things.append, 1).wait(30)
            self.assertRaises(exception_type,
                              service.deferTask(be_bad).wait, 30)
            service.deferTask(things.append, 2).wait(30)
        finally:
            service.stopService()

        self.assertThat(things, Equals([1, 2]))
示例#15
0
 def test_handles_driver_raising_any_Exception(self):
     fake_driver = MagicMock()
     fake_exception_type = factory.make_exception_type()
     fake_exception_msg = factory.make_name("error")
     fake_exception = fake_exception_type(fake_exception_msg)
     fake_driver.get_commissioning_data.return_value = fail(fake_exception)
     self.patch(PodDriverRegistry, "get_item").return_value = fake_driver
     with ExpectedException(
         exceptions.PodActionFail,
         re.escape("Failed talking to pod: " + fake_exception_msg),
     ):
         yield pods.send_pod_commissioning_results(
             pod_type=factory.make_name("type"),
             context={},
             pod_id=random.randint(1, 10),
             name=factory.make_name("name"),
             system_id=factory.make_name("system_id"),
             consumer_key=factory.make_name("consumer_key"),
             token_key=factory.make_name("token_key"),
             token_secret=factory.make_name("token_secret"),
             metadata_url=urlparse(factory.make_url()),
         )
示例#16
0
    def test_get_reader_converts_other_exceptions_to_tftp_error(self):
        exception_type = factory.make_exception_type()
        exception_message = factory.make_string()
        client = Mock()
        client.localIdent = factory.make_name("system_id")
        client.return_value = fail(exception_type(exception_message))
        client_service = Mock()
        client_service.getClientNow.return_value = succeed(client)
        backend = TFTPBackend(self.make_dir(), client_service)

        with TwistedLoggerFixture() as logger:
            with ExpectedException(BackendError, re.escape(exception_message)):
                yield backend.get_reader(b'pxelinux.cfg/default')

        # The original exception is logged.
        self.assertDocTestMatches(
            """\
            TFTP back-end failed.
            Traceback (most recent call last):
            ...
            maastesting.factory.TestException#...
            """, logger.output)
示例#17
0
    def test_failed_run_deletes_snapshot(self):
        # Patch out things that we don't want running during the test.  Patch
        # at a low level, so that we exercise all the function calls that a
        # unit test might not put to the test.
        self.patch_maaslog()
        self.patch(boot_resources, "call_and_check")
        self.patch(boot_resources, "service_monitor")

        args = self.make_working_args()

        # Cause the import to fail.
        exception_type = factory.make_exception_type()
        mock_download = self.patch(boot_resources,
                                   "download_all_boot_resources")
        mock_download.side_effect = exception_type()

        # Run the import code.
        self.assertRaises(exception_type, boot_resources.main, args)

        # Verify the reuslts.
        self.assertThat(os.path.join(self.storage, "cache"), Not(DirExists()))
        self.assertThat(os.path.join(self.storage, "current"),
                        Not(DirExists()))
示例#18
0
 def test__sets_self_as_process_group_leader(self):
     exception_type = factory.make_exception_type()
     os = self.patch(avahi_module, "os")
     os.setpgrp.side_effect = exception_type
     self.assertRaises(exception_type, run, [])
     self.assertThat(os.setpgrp, MockCalledOnceWith())
示例#19
0
    def test_report_power_state_reports_all_exceptions(self):
        logger_twisted = self.useFixture(TwistedLoggerFixture())
        logger_maaslog = self.useFixture(FakeLogger("maas"))

        # Avoid threads here.
        self.patch(power, "deferToThread", maybeDeferred)

        exception_type = factory.make_exception_type()
        exception_message = factory.make_string()
        exception = exception_type(exception_message)

        # Pretend the query always fails with `exception`.
        query = self.patch_autospec(power, self.func)
        query.side_effect = always_fail_with(exception)

        # Intercept calls to power_state_update() and send_node_event().
        power_state_update = self.patch_autospec(power, "power_state_update")
        power_state_update.return_value = succeed(None)
        send_node_event = self.patch_autospec(power, "send_node_event")
        send_node_event.return_value = succeed(None)

        self.patch(
            self.power_driver, "detect_missing_packages"
        ).return_value = []

        system_id = factory.make_name("system_id")
        hostname = factory.make_name("hostname")
        context = sentinel.context
        clock = Clock()

        d = power.get_power_state(
            system_id, hostname, self.power_type, context, clock
        )
        d = power.report_power_state(d, system_id, hostname)

        # Crank through some number of retries.
        for wait in self.waits:
            self.assertFalse(d.called)
            clock.advance(wait)
        self.assertTrue(d.called)

        # Finally the exception from the query is raised.
        self.assertRaises(exception_type, extract_result, d)

        # The broken power query function patched earlier was called the same
        # number of times as there are steps in the default waiting policy.
        expected_call = call(system_id, hostname, self.power_type, context)
        expected_calls = [expected_call] * self.calls
        self.assertThat(query, MockCallsMatch(*expected_calls))

        expected_message = "%s: Power state could not be queried: %s" % (
            hostname,
            exception_message,
        )

        # An attempt was made to report the failure to the region.
        self.assertThat(
            power_state_update, MockCalledOnceWith(system_id, "error")
        )
        # An attempt was made to log a node event with details.
        self.assertThat(
            send_node_event,
            MockCalledOnceWith(
                EVENT_TYPES.NODE_POWER_QUERY_FAILED,
                system_id,
                hostname,
                exception_message,
            ),
        )

        # Nothing was logged to the Twisted log.
        self.assertEqual("", logger_twisted.output)
        # A brief message is written to maaslog.
        self.assertEqual(expected_message + "\n", logger_maaslog.output)