Esempio n. 1
0
    def test_send_event_mac_address_logs_if_unknown_node(self):
        log = self.patch(events_module, 'log')
        name = factory.make_name('type_name')
        description = factory.make_name('description')
        level = random.randint(0, 100)
        yield deferToDatabase(self.create_event_type, name, description, level)
        mac_address = factory.make_mac_address()
        event_description = factory.make_name('event-description')

        yield eventloop.start()
        try:
            yield call_responder(
                Region(), SendEventMACAddress, {
                    'mac_address': mac_address,
                    'type_name': name,
                    'description': event_description,
                })
        finally:
            yield eventloop.reset()

        self.assertThat(
            log.debug,
            MockCalledOnceWith(
                "Event '{type}: {description}' sent for non-existent node "
                "with MAC address '{mac}'.",
                type=name,
                description=event_description,
                mac=mac_address))
Esempio n. 2
0
    def test_send_event_mac_address_stores_event(self):
        name = factory.make_name('type_name')
        description = factory.make_name('description')
        level = random.randint(0, 100)
        yield deferToDatabase(self.create_event_type, name, description, level)
        interface = yield deferToDatabase(self.make_interface)
        mac_address = interface.mac_address
        event_description = factory.make_name('description')

        yield eventloop.start()
        try:
            response = yield call_responder(
                Region(), SendEventMACAddress, {
                    'mac_address': mac_address.get_raw(),
                    'type_name': name,
                    'description': event_description,
                })
        finally:
            yield eventloop.reset()

        self.assertEqual({}, response)
        event = yield deferToDatabase(self.get_event, mac_address, name)
        self.expectThat(event.node.system_id, Equals(interface.node.system_id))
        self.expectThat(event.description, Equals(event_description))
        self.expectThat(event.type.name, Equals(name))
Esempio n. 3
0
    def test_send_event_mac_address_does_not_fail_if_unknown_type(self):
        name = factory.make_name('type_name')
        mac_address = factory.make_mac_address()
        description = factory.make_name('description')

        logger = self.useFixture(TwistedLoggerFixture())

        yield eventloop.start()
        try:
            yield call_responder(
                Region(), SendEventMACAddress, {
                    'mac_address': mac_address,
                    'type_name': name,
                    'description': description,
                })
        finally:
            yield eventloop.reset()

        # The log records the issue. FIXME: Why reject logs if the type is not
        # registered? Seems like the region should record all logs and figure
        # out how to present them.
        self.assertDocTestMatches(
            """\
            Unhandled failure in database task.
            Traceback (most recent call last):
            ...
            provisioningserver.rpc.exceptions.NoSuchEventType:
            ...
            """, logger.output)
Esempio n. 4
0
    def test_send_event_stores_event(self):
        name = factory.make_name('type_name')
        description = factory.make_name('description')
        level = random.randint(0, 100)
        yield deferToDatabase(self.create_event_type, name, description, level)
        system_id = yield deferToDatabase(self.create_node)

        event_description = factory.make_name('description')

        yield eventloop.start()
        try:
            response = yield call_responder(
                Region(), SendEvent, {
                    'system_id': system_id,
                    'type_name': name,
                    'description': event_description,
                })
        finally:
            yield eventloop.reset()

        self.assertEqual({}, response)
        event = yield deferToDatabase(self.get_event, system_id, name)
        self.expectThat(event.node.system_id, Equals(system_id))
        self.expectThat(event.description, Equals(event_description))
        self.expectThat(event.type.name, Equals(name))
Esempio n. 5
0
    def test_send_event_logs_if_unknown_node(self):
        log = self.patch(events_module, 'log')
        name = factory.make_name('type_name')
        description = factory.make_name('description')
        level = random.randint(0, 100)
        yield deferToDatabase(self.create_event_type, name, description, level)

        system_id = factory.make_name('system_id')
        event_description = factory.make_name('event-description')

        yield eventloop.start()
        try:
            yield call_responder(
                Region(), SendEvent, {
                    'system_id': system_id,
                    'type_name': name,
                    'description': event_description,
                })
        finally:
            yield eventloop.reset()

        self.assertThat(
            log.debug,
            MockCalledOnceWith(
                "Event '{type}: {description}' sent for "
                "non-existent node '{node_id}'.",
                type=name,
                description=event_description,
                node_id=system_id))
Esempio n. 6
0
    def test_send_event_mac_address_stores_event_with_timestamp_received(self):
        # Use a random time in the recent past and coerce the responder to use
        # it as the time-stamp for the event. We'll check this later on.
        timestamp = datetime.now() - timedelta(seconds=randint(99, 99999))
        self.patch(regionservice, "datetime").now.return_value = timestamp

        event_type = factory.make_name("type_name")
        yield deferToDatabase(self.create_event_type, event_type, "", 0)
        interface = yield deferToDatabase(self.make_interface)
        mac_address = interface.mac_address.get_raw()

        yield eventloop.start()
        try:
            yield call_responder(
                Region(),
                SendEventMACAddress,
                {
                    "mac_address": mac_address,
                    "type_name": event_type,
                    "description": factory.make_name("description"),
                },
            )
        finally:
            yield eventloop.reset()

        event = yield deferToDatabase(self.get_event, mac_address, event_type)
        self.expectThat(event.created, Equals(timestamp))
Esempio n. 7
0
    def test_calls_update_services_in_database_thread(self):
        system_id = factory.make_name("system_id")
        services = [
            {
                "name": factory.make_name("service"),
                "status": factory.make_name("status"),
                "status_info": factory.make_name("status_info"),
            }
        ]

        mock_deferToDatabase = self.patch(regionservice, "deferToDatabase")
        mock_deferToDatabase.return_value = succeed({})

        yield eventloop.start()
        try:
            yield call_responder(
                Region(),
                UpdateServices,
                {"system_id": system_id, "services": services},
            )
        finally:
            yield eventloop.reset()

        self.assertThat(
            mock_deferToDatabase,
            MockCalledWith(update_services, system_id, services),
        )
Esempio n. 8
0
    def test_rpc_info_from_running_ipc_master(self):
        # Run the IPC master, IPC worker, and RPC service so the endpoints
        # are updated in the database.
        region = factory.make_RegionController()
        self.useFixture(MAASIDFixture(region.system_id))
        region.owner = factory.make_admin()
        region.save()
        # `workers` is only included so ipc-master will not actually get the
        # workers service because this test runs in all-in-one mode.
        self.useFixture(
            RegionEventLoopFixture(
                "ipc-master", "ipc-worker", "rpc", "workers"
            )
        )

        eventloop.start(master=True, all_in_one=True).wait(5)
        self.addCleanup(lambda: eventloop.reset().wait(5))

        getServiceNamed = eventloop.services.getServiceNamed
        ipcMaster = getServiceNamed("ipc-master")

        @wait_for(5)
        @inlineCallbacks
        def wait_for_startup():
            # Wait for the service to complete startup.
            yield ipcMaster.starting
            yield getServiceNamed("ipc-worker").starting
            yield getServiceNamed("rpc").starting
            # Force an update, because it's very hard to track when the
            # first iteration of the ipc-master service has completed.
            yield ipcMaster.update()

        wait_for_startup()

        response = self.client.get(reverse("rpc-info"))

        self.assertEqual("application/json", response["Content-Type"])
        info = json.loads(response.content.decode("unicode_escape"))
        self.assertThat(info, KeysEqual("eventloops"))
        self.assertThat(
            info["eventloops"],
            MatchesDict(
                {
                    # Each entry in the endpoints dict is a mapping from an
                    # event loop to a list of (host, port) tuples. Each tuple is
                    # a potential endpoint for connecting into that event loop.
                    eventloop.loop.name: MatchesSetwise(
                        *(
                            MatchesListwise((Equals(addr), is_valid_port))
                            for addr, _ in ipcMaster._getListenAddresses(5240)
                        )
                    )
                }
            ),
        )
Esempio n. 9
0
    def test_rpc_info_when_rpc_advertise_startup_failed(self):
        self.useFixture(RegionEventLoopFixture("rpc", "rpc-advertise"))

        # Simulate a crash when the rpc-advertise service starts.
        self.simulateExceptionInAdvertiseService(factory.make_exception())

        eventloop.start().wait(2.0)
        self.addCleanup(lambda: eventloop.reset().wait(5))

        response = self.client.get(reverse('rpc-info'))
        self.assertEqual("application/json", response["Content-Type"])
        info = json.loads(response.content.decode("unicode_escape"))
        self.assertEqual({"eventloops": None}, info)
Esempio n. 10
0
    def test_rpc_info_when_rpc_advertise_not_fully_started(self):
        self.useFixture(RegionEventLoopFixture("rpc", "rpc-advertise"))

        # Simulate a time-out when getting the advertising instance.
        self.simulateExceptionInAdvertiseService(CancelledError())

        eventloop.start().wait(2.0)
        self.addCleanup(lambda: eventloop.reset().wait(5))

        response = self.client.get(reverse('rpc-info'))
        self.assertEqual("application/json", response["Content-Type"])
        info = json.loads(response.content.decode("unicode_escape"))
        self.assertEqual({"eventloops": None}, info)
Esempio n. 11
0
    def test__doesnt_raises_other_errors(self):
        uuid = factory.make_name("uuid")

        # Cause a random exception
        self.patch(leases_module,
                   "update_lease").side_effect = (factory.make_exception())

        yield eventloop.start()
        try:
            yield call_responder(
                Region(), UpdateLease, {
                    "cluster_uuid": uuid,
                    "action": "expiry",
                    "mac": factory.make_mac_address(),
                    "ip_family": "ipv4",
                    "ip": factory.make_ipv4_address(),
                    "timestamp": int(time.time()),
                })
        finally:
            yield eventloop.reset()
Esempio n. 12
0
    def test_rpc_info_when_rpc_advertise_running(self):
        region = factory.make_RegionController()
        self.useFixture(MAASIDFixture(region.system_id))
        region.owner = factory.make_admin()
        region.save()
        self.useFixture(RegionEventLoopFixture("rpc", "rpc-advertise"))

        eventloop.start().wait(5)
        self.addCleanup(lambda: eventloop.reset().wait(5))

        getServiceNamed = eventloop.services.getServiceNamed

        @wait_for(5)
        @inlineCallbacks
        def wait_for_startup():
            # Wait for the rpc and the rpc-advertise services to start.
            yield getServiceNamed("rpc").starting
            yield getServiceNamed("rpc-advertise").starting
            # Force an update, because it's very hard to track when the
            # first iteration of the rpc-advertise service has completed.
            yield getServiceNamed("rpc-advertise")._tryUpdate()

        wait_for_startup()

        response = self.client.get(reverse('rpc-info'))

        self.assertEqual("application/json", response["Content-Type"])
        info = json.loads(response.content.decode("unicode_escape"))
        self.assertThat(info, KeysEqual("eventloops"))
        self.assertThat(
            info["eventloops"],
            MatchesDict({
                # Each entry in the endpoints dict is a mapping from an
                # event loop to a list of (host, port) tuples. Each tuple is
                # a potential endpoint for connecting into that event loop.
                eventloop.loop.name:
                MatchesSetwise(*(MatchesListwise((Equals(addr), is_valid_port))
                                 for addr in get_all_interface_addresses()
                                 if not IPAddress(addr).is_link_local()
                                 and not IPAddress(addr).is_loopback())),
            }))
Esempio n. 13
0
    def test_send_event_stores_event_with_timestamp_received(self):
        # Use a random time in the recent past and coerce the responder to use
        # it as the time-stamp for the event. We'll check this later on.
        timestamp = datetime.now() - timedelta(seconds=randint(99, 99999))
        self.patch(regionservice, "datetime").now.return_value = timestamp

        event_type = factory.make_name('type_name')
        yield deferToDatabase(self.create_event_type, event_type, "", 0)
        system_id = yield deferToDatabase(self.create_node)

        yield eventloop.start()
        try:
            yield call_responder(
                Region(), SendEvent, {
                    'system_id': system_id, 'type_name': event_type,
                    'description': factory.make_name('description'),
                })
        finally:
            yield eventloop.reset()

        event = yield deferToDatabase(self.get_event, system_id, event_type)
        self.expectThat(event.created, Equals(timestamp))
Esempio n. 14
0
 def tearDown(self):
     super().tearDown()
     # start_up starts the Twisted event loop, so we need to stop it.
     eventloop.reset().wait(5)
Esempio n. 15
0
 def stop(self):
     return eventloop.reset()