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):