예제 #1
0
    def test_immediate_success(self, logger):
        """
        If the predicate returns something truthy immediately, then
        ``loop_until`` returns a deferred that has already fired with that
        value.
        """
        result = object()

        def predicate():
            return result

        clock = Clock()
        d = loop_until(clock, predicate)
        self.assertEqual(self.successResultOf(d), result)

        action = LoggedAction.of_type(logger.messages, LOOP_UNTIL_ACTION)[0]
        assertContainsFields(self, action.start_message, {
            'predicate': predicate,
        })
        assertContainsFields(self, action.end_message, {
            'action_status': 'succeeded',
            'result': result,
        })
예제 #2
0
    def test_reconnection_failed(self):
        assert self.factory.disconnect is False
        self.factory.last_reconnection_wait = \
            CardinalBotFactory.MINIMUM_RECONNECTION_WAIT

        clock = Clock()
        mock_connector = Mock()
        self.factory._reactor = clock

        self.factory.clientConnectionFailed(mock_connector,
                                            'Called by unit test')

        # time should have doubled
        assert self.factory.last_reconnection_wait == \
            CardinalBotFactory.MINIMUM_RECONNECTION_WAIT * 2

        # make sure it's not called on original time
        clock.advance(self.factory.MINIMUM_RECONNECTION_WAIT)
        assert not mock_connector.connect.called

        # advance it one more time and it should be
        clock.advance(self.factory.MINIMUM_RECONNECTION_WAIT)
        mock_connector.connect.assert_called_once()
예제 #3
0
    def test_logs_other_errors(self):
        service = ImageDownloadService(
            sentinel.rpc, sentinel.tftp_root, Clock())

        maybe_start_download = self.patch(service, "maybe_start_download")
        maybe_start_download.return_value = defer.fail(
            ZeroDivisionError("Such a shame I can't divide by zero"))

        with FakeLogger("maas") as maaslog, TwistedLoggerFixture() as logger:
            d = service.try_download()

        self.assertEqual(None, extract_result(d))
        self.assertDocTestMatches(
            "Failed to download images: "
            "Such a shame I can't divide by zero",
            maaslog.output)
        self.assertDocTestMatches(
            """\
            Downloading images failed.
            Traceback (most recent call last):
            Failure: builtins.ZeroDivisionError: Such a shame ...
            """,
            logger.output)
예제 #4
0
    def test_partial_predicate(self, logger):
        """
        Predicate can be a functools.partial function.
        """
        result = object()

        def check():
            return result

        predicate = partial(check)

        clock = Clock()
        d = loop_until(clock, predicate)
        self.assertEqual(self.successResultOf(d), result)

        [action] = LoggedAction.of_type(logger.messages, LOOP_UNTIL_ACTION)
        assertContainsFields(self, action.start_message, {
            'predicate': predicate,
        })
        assertContainsFields(self, action.end_message, {
            'action_status': 'succeeded',
            'result': result,
        })
예제 #5
0
def build_control_amp_service(test_case, reactor=None):
    """
    Create a new ``ControlAMPService``.

    :param TestCase test_case: The test this service is for.

    :return ControlAMPService: Not started.
    """
    if reactor is None:
        reactor = Clock()
    cluster_state = ClusterStateService(reactor)
    cluster_state.startService()
    test_case.addCleanup(cluster_state.stopService)
    persistence_service = ConfigurationPersistenceService(
        reactor, test_case.make_temporary_directory())
    persistence_service.startService()
    test_case.addCleanup(persistence_service.stopService)
    return ControlAMPService(
        reactor, cluster_state, persistence_service,
        TCP4ServerEndpoint(MemoryReactor(), 1234),
        # Easiest TLS context factory to create:
        ClientContextFactory(),
    )
예제 #6
0
    def test_glass_from_sand_on_wood(self):
        """
        Crafting one glass, from one sand, using one wood, should take 15s.
        """

        # Patch the clock.
        clock = Clock()
        self.tile.burning.clock = clock

        self.tile.inventory.fuel[0] = Slot(blocks['wood'].slot, 0, 1)
        self.tile.inventory.crafting[0] = Slot(blocks['sand'].slot, 0, 1)
        self.tile.changed(self.factory, coords)

        # Pump the clock. Burn time is 15s.
        clock.pump([0.5] * 30)

        self.assertEqual(self.factory.world.chunk.states[0],
                         blocks["burning-furnace"].slot) # it was started...
        self.assertEqual(self.factory.world.chunk.states[1],
                         blocks["furnace"].slot) # ...and stopped at the end
        self.assertEqual(self.tile.inventory.fuel[0], None)
        self.assertEqual(self.tile.inventory.crafting[0], None)
        self.assertEqual(self.tile.inventory.crafted[0], (blocks['glass'].slot, 0, 1))
예제 #7
0
    def test_scenario_succeeds_when_rate_has_tolerated_drop(self, _logger):
        """
        ``read_request_load_scenario`` succeeds even if the rate drops,
        if it is within the tolerance percentage.

        Establish the requested rate by having the ``FakeFlockerClient``
        respond to all requests, then lower the rate by dropping
        alternate requests.
        """
        c = Clock()

        cluster = self.make_cluster(RequestDroppingFakeFlockerClient)
        sample_size = 5
        s = read_request_load_scenario(c, cluster, sample_size=sample_size,
                                       tolerance_percentage=0.6)
        cluster.get_control_service(c).drop_requests = True
        d = s.start()
        s.maintained().addBoth(lambda x: self.fail())
        d.addCallback(lambda ignored: s.stop())
        # Generate enough samples to finish the scenario
        c.pump(repeat(1, sample_size*s.request_rate))

        self.successResultOf(d)
 def test_requests_beaconing_when_timer_fires(self):
     fixture = self.useFixture(MockLiveClusterToRegionRPCFixture())
     protocol, connecting = fixture.makeEventLoop(region.UpdateInterfaces,
                                                  region.GetDiscoveryState)
     self.addCleanup((yield connecting))
     rpc_service = services.getServiceNamed("rpc")
     reactor = Clock()
     service = RackNetworksMonitoringService(
         rpc_service,
         reactor,
         enable_monitoring=False,
         enable_beaconing=True,
     )
     service.beaconing_protocol = Mock()
     service.beaconing_protocol.queueMulticastBeaconing = Mock()
     service.getInterfaces = lambda: succeed({})
     service._recorded = {}
     service.startService()
     yield service.stopService()
     self.assertThat(
         service.beaconing_protocol.queueMulticastBeaconing,
         MockCallsMatch(call(solicitation=True)),
     )
예제 #9
0
    def test_late_succeed(self):
        m = mock_manager()
        m.allocate_subchannel_id = mock.Mock(return_value=0)
        hostaddr = _WormholeAddress()
        peeraddr = _SubchannelAddress(0)
        eq = EventualQueue(Clock())
        ep = SubchannelConnectorEndpoint(m, hostaddr, eq)
        ep._main_channel_ready()

        f = mock.Mock()
        p = mock.Mock()
        t = mock.Mock()
        f.buildProtocol = mock.Mock(return_value=p)
        with mock.patch("wormhole._dilation.subchannel.SubChannel",
                        return_value=t) as sc:
            d = ep.connect(f)
            eq.flush_sync()

        self.assertIdentical(self.successResultOf(d), p)
        self.assertEqual(f.buildProtocol.mock_calls, [mock.call(peeraddr)])
        self.assertEqual(sc.mock_calls, [mock.call(0, m, hostaddr, peeraddr)])
        self.assertEqual(t.mock_calls, [mock.call._set_protocol(p)])
        self.assertEqual(p.mock_calls, [mock.call.makeConnection(t)])
예제 #10
0
    def test_starting_and_stopping(self):
        deferToDatabase = self.patch(publication, "deferToDatabase")

        utcnow = patch_utcnow(self)
        cutoff = utcnow.replace(tzinfo=UTC) - timedelta(days=7)

        dnsgc = publication.DNSPublicationGarbageService()
        dnsgc.clock = clock = Clock()

        dnsgc.startService()
        self.assertTrue(dnsgc.running)
        self.assertTrue(dnsgc._loop.running)
        self.assertThat(deferToDatabase, MockNotCalled())
        self.assertThat(dnsgc._loop.interval, IsExpectedInterval)

        clock.advance(dnsgc._loop.interval)
        self.assertThat(deferToDatabase,
                        MockCalledOnceWith(dnsgc._collectGarbage, cutoff))
        self.assertThat(dnsgc._loop.interval, IsExpectedInterval)

        dnsgc.stopService()
        self.assertFalse(dnsgc.running)
        self.assertFalse(dnsgc._loop.running)
예제 #11
0
    def test_early_fail(self):
        m = mock_manager()
        m.allocate_subchannel_id = mock.Mock(return_value=0)
        hostaddr = _WormholeAddress()
        eq = EventualQueue(Clock())
        ep = SubchannelConnectorEndpoint(m, hostaddr, eq)

        f = mock.Mock()
        p = mock.Mock()
        t = mock.Mock()
        f.buildProtocol = mock.Mock(return_value=p)
        with mock.patch("wormhole._dilation.subchannel.SubChannel",
                        return_value=t) as sc:
            d = ep.connect(f)
            eq.flush_sync()
            self.assertNoResult(d)
            ep._main_channel_failed(Failure(CannotDilateError()))
            eq.flush_sync()

        self.failureResultOf(d).check(CannotDilateError)
        self.assertEqual(f.buildProtocol.mock_calls, [])
        self.assertEqual(sc.mock_calls, [])
        self.assertEqual(t.mock_calls, [])
예제 #12
0
    def test_late_fail(self):
        # dilation is abandoned, then ep.connect() is called
        scid0 = 0
        peeraddr = _SubchannelAddress(scid0)
        sc0 = mock.Mock()
        alsoProvides(sc0, ISubChannel)
        eq = EventualQueue(Clock())
        ep = ControlEndpoint(peeraddr, sc0, eq)

        ep._main_channel_failed(Failure(CannotDilateError()))

        f = mock.Mock()
        p = mock.Mock()
        f.buildProtocol = mock.Mock(return_value=p)
        d = ep.connect(f)
        eq.flush_sync()

        self.failureResultOf(d).check(CannotDilateError)
        self.assertEqual(f.buildProtocol.mock_calls, [])
        self.assertEqual(sc0.mock_calls, [])

        d = ep.connect(f)
        self.failureResultOf(d, SingleUseEndpointError)
예제 #13
0
    def test_returnAsynchronousDeferred(self):
        """
        If the greenlet does switch, the Deferred will fire only when the
        greenlet has returned.
        """
        clock = Clock()
        events = []

        @deferredGreenlet
        def waity():
            events.append("prewait")
            wait(3, clock)

        result = []
        d = waity()
        d.addCallback(result.append)
        # Make sure the deferred has *not* fired yet...
        self.assertEquals(result, [])
        # But the greenlet *has* been started
        self.assertEquals(events, ["prewait"])

        clock.advance(3)
        self.assertEquals(result, [None])
예제 #14
0
    def test_late_succeed(self):
        # dilation can proceed, then ep.connect() is called
        scid0 = 0
        peeraddr = _SubchannelAddress(scid0)
        sc0 = mock.Mock()
        alsoProvides(sc0, ISubChannel)
        eq = EventualQueue(Clock())
        ep = ControlEndpoint(peeraddr, sc0, eq)

        ep._main_channel_ready()

        f = mock.Mock()
        p = mock.Mock()
        f.buildProtocol = mock.Mock(return_value=p)
        d = ep.connect(f)
        eq.flush_sync()
        self.assertIdentical(self.successResultOf(d), p)
        self.assertEqual(f.buildProtocol.mock_calls, [mock.call(peeraddr)])
        self.assertEqual(sc0.mock_calls, [mock.call._set_protocol(p)])
        self.assertEqual(p.mock_calls, [mock.call.makeConnection(sc0)])

        d = ep.connect(f)
        self.failureResultOf(d, SingleUseEndpointError)
예제 #15
0
def make_outbound():
    m = mock.Mock()
    alsoProvides(m, IDilationManager)
    clock = Clock()
    eq = EventualQueue(clock)
    term = mock.Mock(side_effect=lambda: True)  # one write per Eventual tick

    def term_factory():
        return term
    coop = Cooperator(terminationPredicateFactory=term_factory,
                      scheduler=eq.eventually)
    o = Outbound(m, coop)
    c = mock.Mock()  # Connection

    def maybe_pause(r):
        if isinstance(r, Pauser):
            o.pauseProducing()
        elif isinstance(r, Stopper):
            o.subchannel_unregisterProducer(r.sc)
    c.send_record = mock.Mock(side_effect=maybe_pause)
    o._test_eq = eq
    o._test_term = term
    return o, m, c
예제 #16
0
    def test_logWaits(self):
        """
        CommonStoreTransactionMonitor logs waiting transactions.
        """

        c = Clock()
        self.patch(CommonStoreTransactionMonitor, "callLater", c.callLater)

        # Patch config to turn on log waits then rebuild the store
        self.patch(self.store, "logTransactionWaits", 1)

        ctr = [0]

        def counter(*args, **kwargs):
            ctr[0] += 1

        self.patch(log, "error", counter)

        txn = self.transactionUnderTest()

        c.advance(2)
        self.assertNotEqual(ctr[0], 0)
        txn.abort()
예제 #17
0
 def test_sessions_created_all_have_integer_tenant_ids(self):
     """
     Sessions created by
     :class:`SessionStore.session_for_username_password`,
     :class:`SessionStore.session_for_impersonation`,
     :class:`SessionStore.session_for_api_key`, and
     :class:`SessionStore.session_for_token`, when not passed a specific
     tenant ID, all generate integer-style tenant IDs.
     """
     clock = Clock()
     sessions = SessionStore(clock)
     sessions = [
         sessions.session_for_username_password("someuser1", "testpass"),
         sessions.session_for_impersonation("someuser2", 12),
         sessions.session_for_api_key("someuser3", "someapikey"),
         sessions.session_for_token("sometoken"),
     ]
     integer = re.compile('^\d+$')
     for session in sessions:
         self.assertIsNot(
             integer.match(session.tenant_id), None,
             "{0} is not an integer.".format(session.tenant_id))
         self.assertTrue(int(session.tenant_id) < 1e15)
예제 #18
0
 def test_reports_neighbours_to_region(self):
     fixture = self.useFixture(MockLiveClusterToRegionRPCFixture())
     protocol, connecting = fixture.makeEventLoop(
         region.UpdateInterfaces, region.ReportNeighbours
     )
     self.addCleanup((yield connecting))
     rpc_service = services.getServiceNamed("rpc")
     service = RackNetworksMonitoringService(
         rpc_service,
         Clock(),
         enable_monitoring=False,
         enable_beaconing=False,
     )
     neighbours = [{"ip": factory.make_ip_address()}]
     yield service.reportNeighbours(neighbours)
     self.assertThat(
         protocol.ReportNeighbours,
         MockCalledOnceWith(
             protocol,
             system_id=rpc_service.getClient().localIdent,
             neighbours=neighbours,
         ),
     )
예제 #19
0
    def test_stopServiceWhileRestarting(self):
        """
        Calling L{ClientService.stopService} after calling a
        reconnection attempt returns a L{Deferred} that fires when the
        disconnection has completed.
        """
        clock = Clock()
        cq, service = self.makeReconnector(fireImmediately=False, clock=clock)
        # The protocol connects
        cq.connectQueue[0].callback(None)

        # The protocol begins disconnecting
        firstStopDeferred = service.stopService()
        # The protocol begins reconnecting
        service.startService()
        # The protocol begins disconnecting again
        secondStopDeferred = service.stopService()

        # The protocol is disconnected
        cq.constructedProtocols[0].connectionLost(Failure(IndentationError()))

        self.successResultOf(firstStopDeferred)
        self.successResultOf(secondStopDeferred)
def test_worker_stopped_after_required_executions(num_executions):
    # Control time
    clock = Clock()
    worker = MagicMock()
    worktracker = WorkTrackerTrackExecutions(clock=clock,
                                             num_executions_before_stop=num_executions,
                                             worker=worker)

    def start():
        worktracker.start()

    d = threads.deferToThread(start)

    def advance_one_cycle(_):
        clock.advance(WorkTrackerBase.INTERVAL_CEIL)

    for i in range(10):
        d.addCallback(advance_one_cycle)

    yield d

    assert worktracker.executions_when_stopped == num_executions
    assert worktracker.executions >= num_executions
예제 #21
0
    def test_push_writes_filesystem(self):
        """
        Pushing a locally-owned volume writes its filesystem to the remote
        process.
        """
        pool = FilesystemStoragePool(FilePath(self.mktemp()))
        service = VolumeService(FilePath(self.mktemp()), pool, reactor=Clock())
        service.startService()
        volume = self.successResultOf(service.create(MY_VOLUME))
        filesystem = volume.get_filesystem()
        filesystem.get_path().child(b"foo").setContent(b"blah")
        with filesystem.reader() as reader:
            data = reader.read()
        node = FakeNode([
            # Hard-code the knowledge that first `flocker-volume snapshots` is
            # run.  It doesn't need to produce any particular output for this
            # test, it just needs to not fail.
            b"",
        ])

        self.successResultOf(service.push(volume, RemoteVolumeManager(node)))

        self.assertEqual(node.stdin.read(), data)
예제 #22
0
파일: test_cftp.py 프로젝트: yuu6/twisted
    def test_printProgressBarReporting(self):
        """
        L{StdioClient._printProgressBar} prints a progress description,
        including percent done, amount transferred, transfer rate, and time
        remaining, all based the given start time, the given L{FileWrapper}'s
        progress information and the reactor's current time.
        """
        # Use a short, known console width because this simple test doesn't
        # need to test the console padding.
        self.setKnownConsoleSize(10, 34)
        clock = self.client.reactor = Clock()
        wrapped = BytesIO(b"x")
        wrapped.name = b"sample"
        wrapper = cftp.FileWrapper(wrapped)
        wrapper.size = 1024 * 10
        startTime = clock.seconds()
        clock.advance(2.0)
        wrapper.total += 4096

        self.client._printProgressBar(wrapper, startTime)

        result = b"\rb'sample' 40% 4.0kB 2.0kBps 00:03 "
        self.assertEqual(self.client.transport.value(), result)
예제 #23
0
    def test_calculates_times_with_reference_to_current_time(self):
        # Take control of time.
        clock = Clock()

        gen_retries = utils.retries(5, 2, time=clock.seconds)
        # No time has passed, 5 seconds remain, and it suggests sleeping
        # for 2 seconds.
        self.assertRetry(clock, next(gen_retries), 0, 5, 2)
        # Mimic sleeping for 4 seconds, more than the suggested.
        clock.advance(4)
        # Now 4 seconds have passed, 1 second remains, and it suggests
        # sleeping for just 1 more second.
        self.assertRetry(clock, next(gen_retries), 4, 1, 1)
        # Don't sleep, ask again immediately, and the same answer is given.
        self.assertRetry(clock, next(gen_retries), 4, 1, 1)
        # Mimic sleeping for 100 seconds, much more than the suggested.
        clock.advance(100)
        # There's always a final chance to try something, but the elapsed and
        # remaining figures are still calculated with reference to the current
        # time. The wait time never goes below zero.
        self.assertRetry(clock, next(gen_retries), 104, -99, 0)
        # All done.
        self.assertRaises(StopIteration, next, gen_retries)
예제 #24
0
    def test_enumerate_skips_other_filesystems(self):
        """
        The result of ``enumerate()`` does not include any volumes representing
        filesystems named outside of the Flocker naming convention (which may
        have been created directly by the user).
        """
        path = FilePath(self.mktemp())
        path.child(b"arbitrary stuff").makedirs()
        path.child(b"stuff\tarbitrary").makedirs()
        path.child(b"non-uuid.stuff").makedirs()

        pool = FilesystemStoragePool(path)
        service = VolumeService(FilePath(self.mktemp()), pool, reactor=Clock())
        service.startService()

        name = VolumeName(namespace=u"mynspaces",
                          dataset_id=u"good_volume_name")
        self.successResultOf(service.create(service.get(name)))

        volumes = list(self.successResultOf(service.enumerate()))
        self.assertEqual(
            [Volume(node_id=service.node_id, name=name, service=service)],
            volumes)
예제 #25
0
    def create_client(self):
        """
        Create a new ``FlockerClient`` instance pointing at a running control
        service REST API.

        :return: ``FlockerClient`` instance.
        """
        clock = Clock()
        _, self.port = find_free_port()
        self.persistence_service = ConfigurationPersistenceService(
            clock, FilePath(self.mktemp()))
        self.persistence_service.startService()
        self.cluster_state_service = ClusterStateService(reactor)
        self.cluster_state_service.startService()
        self.addCleanup(self.cluster_state_service.stopService)
        self.addCleanup(self.persistence_service.stopService)
        credential_set, _ = get_credential_sets()
        credentials_path = FilePath(self.mktemp())
        credentials_path.makedirs()

        api_service = create_api_service(
            self.persistence_service,
            self.cluster_state_service,
            TCP4ServerEndpoint(reactor, self.port, interface=b"127.0.0.1"),
            rest_api_context_factory(
                credential_set.root.credential.certificate,
                credential_set.control),
            # Use consistent fake time for API results:
            clock)
        api_service.startService()
        self.addCleanup(api_service.stopService)

        credential_set.copy_to(credentials_path, user=True)
        return FlockerClient(reactor, b"127.0.0.1", self.port,
                             credentials_path.child(b"cluster.crt"),
                             credentials_path.child(b"user.crt"),
                             credentials_path.child(b"user.key"))
예제 #26
0
파일: test_core.py 프로젝트: glyph/mimic
    def test_entries_for_tenant_external_with_tenantid_replacement(self):
        """
        Validate that the external API shows up in the service catalog for a
        given tenant and the tenant id is in the URL.
        """
        eeapi = make_example_external_api(self,
                                          name=self.eeapi_name,
                                          set_enabled=True)

        tenant_id = 'some-tenant-other'

        ept_internal_url = "http://internal.url/v1/" + tenant_id
        ept_public_url = "http://public.url/v1/" + tenant_id
        for ept in eeapi.endpoint_templates.values():
            ept.internal_url = "http://internal.url/v1/%tenant_id%"
            ept.public_url = "http://public.url/v1/%tenant_id%"

        core = MimicCore(Clock(), [eeapi])

        prefix_map = {}
        base_uri = "http://some/random/prefix"
        catalog_entries = [
            entry for entry in core.entries_for_tenant(tenant_id, prefix_map,
                                                       base_uri)
        ]

        self.assertEqual(len(core._uuid_to_api_internal), 0)
        self.assertEqual(len(core._uuid_to_api_external), 1)
        self.assertEqual(len(catalog_entries), 1)
        self.assertEqual(catalog_entries[0].type, eeapi.type_key)
        self.assertEqual(catalog_entries[0].name, eeapi.name_key)
        self.assertEqual(catalog_entries[0].tenant_id, tenant_id)
        self.assertEqual(len(catalog_entries[0].endpoints), 1)
        self.assertEqual(catalog_entries[0].endpoints[0].internal_url,
                         ept_internal_url)
        self.assertEqual(catalog_entries[0].endpoints[0].complete_url,
                         ept_public_url)
예제 #27
0
    def test_exits_gracefully_if_cant_report_foreign_dhcp_server(self):
        clock = Clock()
        interface_name = factory.make_name("eth")
        interfaces = {
            interface_name: {
                "enabled": True,
                "links": [{
                    "address": "10.0.0.1/24"
                }],
            }
        }

        maaslog = self.patch(dhcp_probe_service, "maaslog")
        deferToThread = self.patch(dhcp_probe_service, "deferToThread")
        deferToThread.side_effect = [defer.succeed(interfaces)]
        probe_interface = self.patch(dhcp_probe_service, "probe_interface")
        probe_interface.return_value = ["192.168.0.100"]
        protocol, connecting = self.patch_rpc_methods()
        self.addCleanup((yield connecting))

        del protocol._commandDispatch[
            region.ReportForeignDHCPServer.commandName]

        rpc_service = Mock()
        rpc_service.getClientNow.return_value = defer.succeed(
            getRegionClient())
        service = DHCPProbeService(rpc_service, clock)
        yield service.startService()
        yield service.stopService()

        self.assertThat(
            maaslog.error,
            MockCalledOnceWith(
                "Unable to inform region of DHCP server: the region "
                "does not yet support the ReportForeignDHCPServer RPC "
                "method."),
        )
예제 #28
0
    def test_reports_foreign_dhcp_servers_to_region(self):
        clock = Clock()
        interface_name = factory.make_name("eth")
        interfaces = {
            interface_name: {
                "enabled": True,
                "links": [{
                    "address": "10.0.0.1/24"
                }],
            }
        }

        protocol, connecting = self.patch_rpc_methods()
        self.addCleanup((yield connecting))

        deferToThread = self.patch(dhcp_probe_service, "deferToThread")
        foreign_dhcp_ip = factory.make_ipv4_address()
        deferToThread.side_effect = [defer.succeed(interfaces)]
        probe_interface = self.patch(dhcp_probe_service, "probe_interface")
        probe_interface.return_value = [foreign_dhcp_ip]
        client = getRegionClient()
        rpc_service = Mock()
        rpc_service.getClientNow.return_value = defer.succeed(client)

        service = DHCPProbeService(rpc_service, clock)
        yield service.startService()
        yield service.stopService()

        self.assertThat(
            protocol.ReportForeignDHCPServer,
            MockCalledOnceWith(
                protocol,
                system_id=client.localIdent,
                interface_name=interface_name,
                dhcp_ip=foreign_dhcp_ip,
            ),
        )
예제 #29
0
    def test_convergence_sent_state_fail_resends(self):
        """
        If sending state to the control node fails the next iteration will send
        state even if the state hasn't changed.
        """
        local_state = NodeState(hostname=u'192.0.2.123')
        configuration = Deployment(nodes=[to_node(local_state)])
        state = DeploymentState(nodes=[local_state])
        deployer = ControllableDeployer(
            local_state.hostname,
            [succeed(local_state),
             succeed(local_state.copy())],
            [no_action(), no_action()])
        client = self.make_amp_client(
            [local_state],
            successes=[False],
        )
        reactor = Clock()
        loop = build_convergence_loop_fsm(reactor, deployer)
        loop.receive(
            _ClientStatusUpdate(client=client,
                                configuration=configuration,
                                state=state))
        reactor.advance(1.0)

        # Calculating actions happened, result was run... and then we did
        # whole thing again:
        self.assertTupleEqual(
            (deployer.calculate_inputs, client.calls),
            (
                # Check that the loop has run twice
                [(local_state, configuration, state),
                 (local_state, configuration, state)],
                # And that state was re-sent even though it remained unchanged
                [(NodeStateCommand, dict(state_changes=(local_state, ))),
                 (NodeStateCommand, dict(state_changes=(local_state, )))],
            ))
예제 #30
0
    def test_download_is_initiated_in_new_thread(self):
        clock = Clock()
        maas_meta_last_modified = self.patch(tftppath,
                                             "maas_meta_last_modified")
        one_week = timedelta(minutes=15).total_seconds()
        maas_meta_last_modified.return_value = clock.seconds() - one_week
        http_proxy = factory.make_simple_http_url()
        https_proxy = factory.make_simple_http_url()
        rpc_client = Mock()
        client_call = Mock()
        client_call.side_effect = [
            defer.succeed(dict(sources=sentinel.sources)),
            defer.succeed(
                dict(http=urlparse(http_proxy), https=urlparse(https_proxy))),
        ]
        rpc_client.getClientNow.return_value = defer.succeed(client_call)
        rpc_client.maas_url = factory.make_simple_http_url()

        # We could patch out 'import_boot_images' instead here but I
        # don't do that for 2 reasons:
        # 1. It requires spinning the reactor again before being able to
        # test the result.
        # 2. It means there's no thread to clean up after the test.
        deferToThread = self.patch(boot_images, "deferToThread")
        deferToThread.return_value = defer.succeed(None)
        service = ImageDownloadService(rpc_client, sentinel.tftp_root, clock)
        service.startService()
        self.assertThat(
            deferToThread,
            MockCalledOnceWith(
                _run_import,
                sentinel.sources,
                rpc_client.maas_url,
                http_proxy=http_proxy,
                https_proxy=https_proxy,
            ),
        )