示例#1
0
    def test_cancellation(self, server_name):
        """
        Cancelling the deferred returned by ``issue_cert`` cancels the actual
        issuing process.
        """
        with AcmeFixture() as fixture:
            fixture.service.startService()
            self.assertThat(
                fixture.cert_store.as_dict(),
                succeeded(
                    Not(Contains(server_name))))

            fixture.controller.pause()
            d1 = fixture.service.issue_cert(server_name)
            self.assertThat(d1, has_no_result())
            d2 = fixture.service.issue_cert(server_name)
            self.assertThat(d2, has_no_result())
            self.assertThat(fixture.controller.count(), Equals(1))
            d2.cancel()

            fixture.controller.resume()
            self.assertThat(d1, failed_with(IsInstance(CancelledError)))
            self.assertThat(d2, failed_with(IsInstance(CancelledError)))
            self.assertThat(
                fixture.cert_store.as_dict(),
                succeeded(
                    Not(Contains(server_name))))
示例#2
0
    def test_issue_concurrently(self, server_name):
        """
        Invoking ``issue_cert`` multiple times concurrently for the same name
        will not start multiple issuing processes, only wait for the first
        process to complete.
        """
        with AcmeFixture() as fixture:
            fixture.service.startService()
            self.assertThat(fixture.cert_store.as_dict(),
                            succeeded(Not(Contains(server_name))))

            fixture.controller.pause()
            d1 = fixture.service.issue_cert(server_name)
            self.assertThat(d1, has_no_result())
            d2 = fixture.service.issue_cert(server_name)
            self.assertThat(d2, has_no_result())
            self.assertThat(fixture.controller.count(), Equals(1))

            fixture.controller.resume()
            self.assertThat(d1, succeeded(Always()))
            self.assertThat(d2, succeeded(Always()))

            self.assertThat(
                fixture.cert_store.as_dict(),
                succeeded(MatchesDict({server_name: Not(Equals([]))})))
示例#3
0
    def test_issue_concurrently(self, server_name):
        """
        Invoking ``issue_cert`` multiple times concurrently for the same name
        will not start multiple issuing processes, only wait for the first
        process to complete.
        """
        with AcmeFixture() as fixture:
            fixture.service.startService()
            self.assertThat(
                fixture.cert_store.as_dict(),
                succeeded(
                    Not(Contains(server_name))))

            fixture.controller.pause()
            d1 = fixture.service.issue_cert(server_name)
            self.assertThat(d1, has_no_result())
            d2 = fixture.service.issue_cert(server_name)
            self.assertThat(d2, has_no_result())
            self.assertThat(fixture.controller.count(), Equals(1))

            fixture.controller.resume()
            self.assertThat(d1, succeeded(Always()))
            self.assertThat(d2, succeeded(Always()))

            self.assertThat(
                fixture.cert_store.as_dict(),
                succeeded(
                    MatchesDict({server_name: Not(Equals([]))})))
示例#4
0
    def test_cancellation(self, server_name):
        """
        Cancelling the deferred returned by ``issue_cert`` cancels the actual
        issuing process.
        """
        with AcmeFixture() as fixture:
            fixture.service.startService()
            self.assertThat(
                fixture.cert_store.as_dict(),
                succeeded(
                    Not(Contains(server_name))))

            fixture.controller.pause()
            d1 = fixture.service.issue_cert(server_name)
            self.assertThat(d1, has_no_result())
            d2 = fixture.service.issue_cert(server_name)
            self.assertThat(d2, has_no_result())
            self.assertThat(fixture.controller.count(), Equals(1))
            d2.cancel()

            fixture.controller.resume()
            self.assertThat(d1, failed_with(IsInstance(CancelledError)))
            self.assertThat(d2, failed_with(IsInstance(CancelledError)))
            self.assertThat(
                fixture.cert_store.as_dict(),
                succeeded(
                    Not(Contains(server_name))))
示例#5
0
 def test_starting_stopping_cancellation(self):
     """
     Test the starting and stopping behaviour.
     """
     with AcmeFixture(client=HangingClient()) as fixture:
         d = fixture.service.when_certs_valid()
         self.assertThat(d, has_no_result())
         fixture.service.startService()
         self.assertThat(d, has_no_result())
         fixture.service.stopService()
         self.assertThat(d, failed(Always()))
示例#6
0
 def test_starting_stopping_cancellation(self):
     """
     Test the starting and stopping behaviour.
     """
     with AcmeFixture(client=HangingClient()) as fixture:
         d = fixture.service.when_certs_valid()
         self.assertThat(d, has_no_result())
         fixture.service.startService()
         self.assertThat(d, has_no_result())
         fixture.service.stopService()
         self.assertThat(d, failed(Always()))
示例#7
0
    def test_not_done_yet(self):
        """
        If the decorated method returns ``NOT_DONE_YET`` then the resource is
        responsible for finishing the request itself.
        """
        the_request = []
        class R(Resource):
            @render_exception
            def render(self, request):
                the_request.append(request)
                return NOT_DONE_YET

        d = render(R(), {})

        self.assertThat(
            d,
            has_no_result(),
        )

        the_request[0].write(b"some content")
        the_request[0].finish()

        self.assertThat(
            d,
            succeeded(
                Equals(b"some content"),
            ),
        )
    def test_run_job(self):
        """
        Tests send() and ensure that the job-event is fired.
        """
        job_handler = Mock()
        self.dispatcher.add_listener(JobEvent, 0, job_handler)

        port_out = object()
        port_in = Mock(spec=_port_callback)
        self.flowmap[port_out] = port_in

        self.scheduler.run(self.clock)
        self.scheduler.send('some item', port_out)

        expected_job = Job(port_in, 'some item', self.scheduler.send, port_out)
        self.assertEquals(job_handler.call_count, 1)
        assert_that(job_handler.call_args, MatchesInvocation(
            MatchesEvent(JobEvent,
                         scheduler=matchers.Equals(self.scheduler),
                         job=matchers.Equals(expected_job),
                         completed=twistedsupport.has_no_result())
        ))
        self.assertEquals(port_in.call_count, 0)

        self.assertEquals(len(list(self.scheduler.pending)), 1)

        # Trigger queue run.
        self.clock.advance(self.epsilon)

        port_in.assert_called_once_with('some item', self.scheduler.send)

        self.assertEquals(len(list(self.scheduler.pending)), 0)
示例#9
0
    def test_expected_output(self):
        """
        If some expected output is required, the 'ready' deferred fires only
        when such output has been received.
        """
        self.protocol.expectedOutput = "hello"
        self.protocol.makeConnection(self.process)

        self.reactor.advance(self.protocol.minUptime)
        self.assertThat(self.protocol.ready, has_no_result())

        self.protocol.outReceived(b"hello world!\n")
        self.assertThat(self.protocol.ready, succeeded(Is(None)))
        self.assertIn("Service process emitted 'hello'", self.logger.output)
示例#10
0
 def first_try():
     controller = PaymentController(
         store,
         # It will let `before_restart` attempts succeed before hanging.
         IndexedRedeemer([DummyRedeemer(public_key)] * before_restart +
                         [NonRedeemer()] * after_restart, ),
         default_token_count=num_tokens,
         num_redemption_groups=num_redemption_groups,
         clock=Clock(),
     )
     self.assertThat(
         controller.redeem(voucher),
         has_no_result(),
     )
示例#11
0
    def test_expected_port(self):
        """
        If some expected port is required, the 'ready' deferred fires only
        when such port has been opened.
        """
        self.protocol.expectedPort = 1234
        self.protocol.makeConnection(self.process)

        self.reactor.advance(self.protocol.minUptime)
        self.assertThat(self.protocol.ready, has_no_result())

        factory = self.reactor.tcpClients[0][2]
        factory.buildProtocol(None).connectionMade()
        self.assertThat(self.protocol.ready, succeeded(Is(None)))
        self.assertIn("Service opened port 1234", self.logger.output)
示例#12
0
 def test_deferred(self):
     """
     Any interceptor stage can return a `Deferred` and the execution will
     wait for it to resolve (or fail) before continuing.
     """
     clock = Clock()
     interceptors = [tracer('a'), deferrer('b', clock, 1), tracer('c')]
     d = execute(empty_context, interceptors)
     self.assertThat(d, has_no_result())
     clock.advance(1)
     self.assertThat(
         d,
         succeeded(
             Equals({
                 TRACE:
                 v(('enter', 'a'), ('enter', 'b'), ('enter', 'c'),
                   ('leave', 'c'), ('leave', 'b'), ('leave', 'a'))
             })))
示例#13
0
    def test_wait_for_completion(self, author, folder_name, path_in_folder,
                                 some_content):
        """
        A **POST** request to **/v1/magic-folder/:folder-name/snapshot** does not receive a
        response before the snapshot has been created in the local database.
        """
        local_path = FilePath(self.mktemp())
        local_path.makedirs()

        some_file = local_path.preauthChild(path_in_folder).asBytesMode(
            "utf-8")
        some_file.parent().makedirs(ignoreExistingDirectory=True)
        some_file.setContent(some_content)

        treq = treq_for_folders(
            object(),
            FilePath(self.mktemp()),
            AUTH_TOKEN,
            {
                folder_name:
                magic_folder_config(author, FilePath(self.mktemp()),
                                    local_path)
            },
            # The interesting behavior of this test hinges on this flag.  We
            # decline to start the folder services here.  Therefore, no local
            # snapshots will ever be created.  This lets us observe the
            # request in a state where it is waiting to receive its response.
            # This demonstrates that the response is not delivered before the
            # local snapshot is created.  See test_create_snapshot for the
            # alternative case.
            start_folder_services=False,
        )

        self.assertThat(
            authorized_request(
                treq,
                AUTH_TOKEN,
                b"POST",
                self.url.child(folder_name,
                               "snapshot").set(u"path", path_in_folder),
            ),
            has_no_result(),
        )
示例#14
0
    def test_expected_port_probe_failed(self):
        """
        If probing for the expected port fails, the probe will be retried.
        """
        self.protocol.expectedPort = 1234
        self.protocol.makeConnection(self.process)

        self.reactor.advance(self.protocol.minUptime)
        self.assertThat(self.protocol.ready, has_no_result())

        factory = self.reactor.tcpClients[0][2]
        factory.clientConnectionFailed(None, ConnectionRefusedError())
        self.assertIn("Service port probe failed", self.logger.output)

        self.reactor.advance(0.1)
        factory = self.reactor.tcpClients[1][2]
        factory.buildProtocol(None).connectionMade()
        self.assertThat(self.protocol.ready, succeeded(Is(None)))
        self.assertIn("Service opened port 1234", self.logger.output)
示例#15
0
    def test_process_dies_while_waiting_expected_output(self):
        """
        If the service process exists while waiting for the expected output,
        the 'ready' Deferred fires with an errback.
        """
        self.protocol.expectedOutput = "hello"
        self.protocol.makeConnection(self.process)

        self.reactor.advance(self.protocol.minUptime)

        error = ProcessTerminated(exitCode=1, signal=None)
        self.protocol.processExited(Failure(error))
        self.assertThat(self.protocol.ready,
                        failed(MatchesStructure(value=Is(error))))

        # Further input received on the file descriptor will be discarded
        self.protocol.ready = Deferred()  # pretend that we didn't get fired
        self.protocol.outReceived(b"hello world!\n")
        self.assertThat(self.protocol.ready, has_no_result())
示例#16
0
 def test_when_certs_valid_certs_expired(self, fixture):
     """
     The deferred returned by ``when_certs_valid`` only fires once all
     panicing and expired certs have been renewed.
     """
     with fixture:
         service = fixture.service
         d = service.when_certs_valid()
         self.assertThat(d, has_no_result())
         service.startService()
         self.assertThat(d, succeeded(Is(None)))
         max_expiry = fixture.now + service.panic_interval
         self.assertThat(
             fixture.cert_store.as_dict(),
             succeeded(AfterPreprocessing(
                 methodcaller('values'),
                 AllMatch(AllMatch(
                     _match_certificate(
                         MatchesStructure(
                             not_valid_after=GreaterThan(max_expiry))))))))
         self.assertThat(fixture.responder.challenges, HasLength(0))
示例#17
0
 def test_when_certs_valid_certs_expired(self, fixture):
     """
     The deferred returned by ``when_certs_valid`` only fires once all
     panicing and expired certs have been renewed.
     """
     with fixture:
         service = fixture.service
         d = service.when_certs_valid()
         self.assertThat(d, has_no_result())
         service.startService()
         self.assertThat(d, succeeded(Is(None)))
         max_expiry = fixture.now + service.panic_interval
         self.assertThat(
             fixture.cert_store.as_dict(),
             succeeded(AfterPreprocessing(
                 methodcaller('values'),
                 AllMatch(AllMatch(
                     _match_certificate(
                         MatchesStructure(
                             not_valid_after=GreaterThan(max_expiry))))))))
         self.assertThat(fixture.responder.challenges, HasLength(0))
示例#18
0
    def test_not_redeemed_while_redeeming(self, get_config, now, voucher):
        """
        A ``Voucher`` is not marked redeemed before ``IRedeemer.redeem``
        completes.
        """
        store = self.useFixture(TemporaryVoucherStore(get_config, lambda: now)).store
        controller = PaymentController(
            store,
            NonRedeemer(),
            default_token_count=100,
        )
        self.assertThat(
            controller.redeem(voucher),
            has_no_result(),
        )

        persisted_voucher = store.get(voucher)
        self.assertThat(
            persisted_voucher.state,
            Equals(model_Pending(counter=0)),
        )
示例#19
0
    def test_redeeming(self, get_config, now, voucher, num_successes,
                       public_key):
        """
        A ``Voucher`` is marked redeeming while ``IRedeemer.redeem`` is actively
        working on redeeming it with a counter value that reflects the number
        of successful partial redemptions so far completed.
        """
        # The voucher counter can be zero (no tries yet succeeded).  We want
        # at least *one* run through so we'll bump this up to be sure we get
        # that.
        counter = num_successes + 1
        redeemer = IndexedRedeemer(
            [DummyRedeemer(public_key)] * num_successes + [NonRedeemer()], )
        store = self.useFixture(TemporaryVoucherStore(get_config,
                                                      lambda: now)).store
        controller = PaymentController(
            store,
            redeemer,
            # This will give us one ZKAP per attempt.
            default_token_count=counter,
            # Require more success than we're going to get so it doesn't
            # finish.
            num_redemption_groups=counter,
            clock=Clock(),
        )

        self.assertThat(
            controller.redeem(voucher),
            has_no_result(),
        )

        controller_voucher = controller.get_voucher(voucher)
        self.assertThat(
            controller_voucher.state,
            Equals(model_Redeeming(
                started=now,
                counter=num_successes,
            )),
        )
示例#20
0
    def test_yield_unfired_deferred(self, logger):
        waiting = Deferred()

        @inline_callbacks
        def g():
            Message.log(message_type=u"a")
            yield waiting
            Message.log(message_type=u"b")

        with start_action(action_type=u"the-action"):
            d = g()
            self.assertThat(waiting, has_no_result())
            waiting.callback(None)
            self.assertThat(d, succeeded(Is(None)))
        assert_expected_action_tree(
            self,
            logger,
            u"the-action",
            [
                u"a",
                u"yielded",
                u"b",
            ],
        )
    def test_run_scheduler(self):
        """
        Tests run(), stop() and join() and ensures that appropriate events are fired.
        """
        job_handler = Mock()
        attach_handler = Mock()
        start_handler = Mock()
        join_handler = Mock()
        detach_handler = Mock()

        self.dispatcher.add_listener(JobEvent, 0, job_handler)
        self.dispatcher.add_listener(AttachEvent, 0, attach_handler)
        self.dispatcher.add_listener(DetachEvent, 0, detach_handler)

        # Start the scheduler.
        run_deferred = self.scheduler.run(self.clock)
        assert_that(run_deferred, twistedsupport.has_no_result())

        self.assertEquals(job_handler.call_count, 0)
        attach_handler.assert_called_once_with(AttachEvent(scheduler=self.scheduler, reactor=self.clock))
        self.assertEquals(join_handler.call_count, 0)
        self.assertEquals(detach_handler.call_count, 0)

        job_handler.reset_mock()
        attach_handler.reset_mock()
        start_handler.reset_mock()
        join_handler.reset_mock()
        detach_handler.reset_mock()

        # Turn a bit on the clock.
        self.clock.advance(self.epsilon)
        assert_that(run_deferred, twistedsupport.has_no_result())

        self.assertEquals(job_handler.call_count, 0)
        self.assertEquals(attach_handler.call_count, 0)
        self.assertEquals(start_handler.call_count, 0)
        self.assertEquals(join_handler.call_count, 0)
        self.assertEquals(detach_handler.call_count, 0)

        job_handler.reset_mock()
        attach_handler.reset_mock()
        start_handler.reset_mock()
        join_handler.reset_mock()
        detach_handler.reset_mock()

        # Stop the scheduler.
        self.scheduler.stop('some reason')
        assert_that(run_deferred, twistedsupport.succeeded(matchers.Equals('some reason')))

        self.assertEquals(job_handler.call_count, 0)
        self.assertEquals(attach_handler.call_count, 0)
        self.assertEquals(start_handler.call_count, 0)
        self.assertEquals(join_handler.call_count, 0)
        self.assertEquals(detach_handler.call_count, 0)

        job_handler.reset_mock()
        attach_handler.reset_mock()
        start_handler.reset_mock()
        join_handler.reset_mock()
        detach_handler.reset_mock()

        # Stop the queue and join processes.
        join_deferred = self.scheduler.join()
        self.clock.advance(self.epsilon)
        assert_that(join_deferred, twistedsupport.succeeded(matchers.Always()))

        self.assertEquals(job_handler.call_count, 0)
        self.assertEquals(attach_handler.call_count, 0)
        self.assertEquals(start_handler.call_count, 0)
        detach_handler.assert_called_once_with(DetachEvent(scheduler=self.scheduler))