From c94ded9a4226d542f71a3101d288f18fe941d4c5 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone <exarkun@twistedmatrix.com> Date: Wed, 29 Apr 2020 14:35:36 -0400 Subject: [PATCH] Add a test for stopping redemption of an error is encountered --- src/_zkapauthorizer/controller.py | 18 +++++++++++ src/_zkapauthorizer/tests/test_controller.py | 32 ++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/_zkapauthorizer/controller.py b/src/_zkapauthorizer/controller.py index 57c9d81..6cc8f02 100644 --- a/src/_zkapauthorizer/controller.py +++ b/src/_zkapauthorizer/controller.py @@ -320,6 +320,24 @@ class UnpaidRedeemer(object): return fail(Unpaid(voucher)) +@implementer(IRedeemer) +@attr.s +class RecordingRedeemer(object): + """ + A ``CountingRedeemer`` delegates redemption logic to another object but + records all redemption attempts. + """ + original = attr.ib() + redemptions = attr.ib(default=attr.Factory(list)) + + def random_tokens_for_voucher(self, voucher, counter, count): + return dummy_random_tokens(voucher, counter, count) + + def redeemWithCounter(self, voucher, counter, random_tokens): + self.redemptions.append((voucher, counter, random_tokens)) + return self.original.redeemWithCounter(voucher, counter, random_tokens) + + def dummy_random_tokens(voucher, counter, count): v = urlsafe_b64decode(voucher.number.encode("ascii")) def dummy_random_token(n): diff --git a/src/_zkapauthorizer/tests/test_controller.py b/src/_zkapauthorizer/tests/test_controller.py index 48cfb2f..df77bfe 100644 --- a/src/_zkapauthorizer/tests/test_controller.py +++ b/src/_zkapauthorizer/tests/test_controller.py @@ -109,6 +109,7 @@ from ..controller import ( UnpaidRedeemer, RistrettoRedeemer, IndexedRedeemer, + RecordingRedeemer, PaymentController, AlreadySpent, Unpaid, @@ -355,6 +356,37 @@ class PaymentControllerTests(TestCase): ), ) + + @given(tahoe_configs(), datetimes(), vouchers(), voucher_counters(), integers(min_value=0, max_value=100)) + def test_stop_redeeming_on_error(self, get_config, now, voucher, counter, extra_tokens): + """ + If an error is encountered on one of the redemption attempts performed by + ``IRedeemer.redeem``, the effort is suspended until the normal retry + logic activates. + """ + num_redemption_groups = counter + 1 + num_tokens = num_redemption_groups + extra_tokens + redeemer = RecordingRedeemer(UnpaidRedeemer()) + + store = self.useFixture(TemporaryVoucherStore(get_config, lambda: now)).store + controller = PaymentController( + store, + redeemer, + default_token_count=num_tokens, + num_redemption_groups=num_redemption_groups, + ) + self.assertThat( + controller.redeem(voucher), + succeeded(Always()), + ) + self.assertThat( + redeemer.redemptions, + AfterPreprocessing( + len, + Equals(1), + ), + ) + @given(tahoe_configs(), dummy_ristretto_keys(), datetimes(), vouchers()) def test_redeemed_after_redeeming(self, get_config, public_key, now, voucher): """ -- GitLab