From d50627989267678fe35a4e47846447b82524fda8 Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Mon, 13 Feb 2017 15:33:47 -0500 Subject: [PATCH] Change entitlement sorting to sort *valid* entitlements by reverse expiration time With this change, if all entitlements are valid, we sort to show the entitlement that will expire the farthest in the future, as that defines the point at which the user must act before the license becomes invalid. --- test/test_license.py | 100 ++++++++++++++++++++++++++++++++++++++++++- util/license.py | 8 ++++ 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/test/test_license.py b/test/test_license.py index 0c5a72c1e..4656625cd 100644 --- a/test/test_license.py +++ b/test/test_license.py @@ -408,8 +408,11 @@ class TestLicense(unittest.TestCase): expired=ExpirationType.trial_only) def test_valid_regions_across_multiple_sub_one_expired(self): + service_end = get_date(timedelta(days=20)) + expiration_date = get_date(timedelta(days=10)) + license = self.create_license({ - "expirationDate": get_date(timedelta(days=10)), + "expirationDate": expiration_date, "subscriptions": { "somesub": { "trialEnd": get_date(TRIAL_GRACE_PERIOD * -1 + timedelta(days=-1)), @@ -420,7 +423,7 @@ class TestLicense(unittest.TestCase): }, }, "anothersub": { - "serviceEnd": get_date(timedelta(days=20)), + "serviceEnd": service_end, "entitlements": { QUAY_ENTITLEMENT: 1, QUAY_DEPLOYMENTS_ENTITLEMENT: 5, @@ -438,6 +441,12 @@ class TestLicense(unittest.TestCase): self.assertValid(license, config=config) + entitlements = license.validate(config) + self.assertEquals(2, len(entitlements)) + + self.assertEntitlement(entitlements[0], QUAY_ENTITLEMENT, expiration_date) + self.assertEntitlement(entitlements[1], QUAY_DEPLOYMENTS_ENTITLEMENT, expiration_date) + def test_quay_is_under_expired_sub(self): license = self.create_license({ "expirationDate": get_date(timedelta(days=10)), @@ -469,6 +478,93 @@ class TestLicense(unittest.TestCase): self.assertNotValid(license, config=config, expired=ExpirationType.trial_only, requirement=QUAY_ENTITLEMENT) + def assertEntitlement(self, entitlement, expected_name, expected_date): + self.assertEquals(expected_name, entitlement.requirement.name) + self.assertEquals(expected_date, str(entitlement.entitlement.expiration.expiration_date)) + + def test_license_with_multiple_subscriptions(self): + service_end = get_date(timedelta(days=20)) + expiration_date = get_date(timedelta(days=10)) + trial_end = get_date(timedelta(days=2)) + + license = self.create_license({ + "expirationDate": expiration_date, + "subscriptions": { + "realsub": { + "serviceEnd": service_end, + "entitlements": { + QUAY_ENTITLEMENT: 1, + }, + }, + "trialsub": { + "trialEnd": trial_end, + "trialOnly": True, + "inTrial": True, + "entitlements": { + QUAY_ENTITLEMENT: 1, + QUAY_DEPLOYMENTS_ENTITLEMENT: 3, + }, + }, + }, + }) + + config = { + 'DISTRIBUTED_STORAGE_CONFIG': [ + {'name': 'first'}, + {'name': 'second'}, + ], + } + + self.assertValid(license, config=config) + + entitlements = license.validate(config) + self.assertEquals(2, len(entitlements)) + + self.assertEntitlement(entitlements[0], QUAY_ENTITLEMENT, expiration_date) + self.assertEntitlement(entitlements[1], QUAY_DEPLOYMENTS_ENTITLEMENT, trial_end) + + def test_license_with_multiple_subscriptions_one_expired(self): + service_end = get_date(timedelta(days=20)) + expiration_date = get_date(timedelta(days=10)) + trial_end = get_date(timedelta(days=-2)) + + license = self.create_license({ + "expirationDate": expiration_date, + "subscriptions": { + "realsub": { + "serviceEnd": service_end, + "entitlements": { + QUAY_ENTITLEMENT: 1, + QUAY_DEPLOYMENTS_ENTITLEMENT: 3, + }, + }, + "trialsub": { + "trialEnd": trial_end, + "trialOnly": True, + "inTrial": True, + "entitlements": { + QUAY_ENTITLEMENT: 1, + QUAY_DEPLOYMENTS_ENTITLEMENT: 3, + }, + }, + }, + }) + + config = { + 'DISTRIBUTED_STORAGE_CONFIG': [ + {'name': 'first'}, + {'name': 'second'}, + ], + } + + self.assertValid(license, config=config) + + entitlements = license.validate(config) + self.assertEquals(2, len(entitlements)) + + self.assertEntitlement(entitlements[0], QUAY_ENTITLEMENT, expiration_date) + self.assertEntitlement(entitlements[1], QUAY_DEPLOYMENTS_ENTITLEMENT, expiration_date) + if __name__ == '__main__': unittest.main() diff --git a/util/license.py b/util/license.py index 57def018f..decd6bdbb 100644 --- a/util/license.py +++ b/util/license.py @@ -187,6 +187,14 @@ class EntitlementValidationResult(object): return self.get_status() == EntitlementStatus.met def __lt__(self, rhs): + # If this result has the same status as another, return the result with an expiration date + # further in the future, as it will be more relevant. The results may expire, but so long as + # this result is valid, so will the entitlement. + if self.get_status() == rhs.get_status(): + return (self.entitlement.expiration.expiration_date > + rhs.entitlement.expiration.expiration_date) + + # Otherwise, sort lexically by status. return self.get_status() < rhs.get_status() def __repr__(self):