# Copyright (C) The Arvados Authors. All rights reserved. # # SPDX-License-Identifier: Apache-2.0 from builtins import next from builtins import zip from builtins import str from builtins import range import datetime import itertools import random import unittest from arvados.keep import KeepLocator class ArvadosKeepLocatorTest(unittest.TestCase): DEFAULT_TEST_COUNT = 10 def numstrs(fmtstr, base, exponent): def genstrs(self, count=None): return (fmtstr.format(random.randint(0, base ** exponent)) for c in range(count or self.DEFAULT_TEST_COUNT)) return genstrs checksums = numstrs('{:032x}', 16, 32) sizes = numstrs('{:d}', 2, 26) signatures = numstrs('{:040x}', 16, 40) timestamps = numstrs('{:08x}', 16, 8) def base_locators(self, count=DEFAULT_TEST_COUNT): return ('+'.join(pair) for pair in zip(self.checksums(count), self.sizes(count))) def perm_hints(self, count=DEFAULT_TEST_COUNT): for sig, ts in zip(self.signatures(count), self.timestamps(count)): yield 'A{}@{}'.format(sig, ts) def test_good_locators_returned(self): for hint_gens in [(), (self.sizes(),), (self.sizes(), self.perm_hints())]: for loc_data in zip(self.checksums(), *hint_gens): locator = '+'.join(loc_data) self.assertEqual(locator, str(KeepLocator(locator))) def test_nonchecksum_rejected(self): for badstr in ['', 'badbadbad', '8f9e68d957b504a29ba76c526c3145dj', '+8f9e68d957b504a29ba76c526c3145d9', '3+8f9e68d957b504a29ba76c526c3145d9']: self.assertRaises(ValueError, KeepLocator, badstr) def test_unknown_hints_accepted(self): base = next(self.base_locators(1)) for weirdhint in ['Zfoo', 'Ybar234', 'Xa@b_c-372', 'W99']: locator = '+'.join([base, weirdhint]) self.assertEqual(locator, str(KeepLocator(locator))) def test_bad_hints_rejected(self): base = next(self.base_locators(1)) for badhint in ['', 'A', 'lowercase', '+32']: self.assertRaises(ValueError, KeepLocator, '+'.join([base, badhint])) def test_multiple_locator_hints_accepted(self): base = next(self.base_locators(1)) for loc_hints in itertools.permutations(['Kab1cd', 'Kef2gh', 'Kij3kl']): locator = '+'.join((base,) + loc_hints) self.assertEqual(locator, str(KeepLocator(locator))) def test_str_type(self): base = next(self.base_locators(1)) locator = KeepLocator(base) self.assertEqual(type(''), type(locator.__str__())) def test_expiry_passed(self): base = next(self.base_locators(1)) signature = next(self.signatures(1)) dt1980 = datetime.datetime(1980, 1, 1) dt2000 = datetime.datetime(2000, 2, 2) dt2080 = datetime.datetime(2080, 3, 3) locator = KeepLocator(base) self.assertFalse(locator.permission_expired()) self.assertFalse(locator.permission_expired(dt1980)) self.assertFalse(locator.permission_expired(dt2080)) # Timestamped to 1987-01-05 18:48:32. locator = KeepLocator('{}+A{}@20000000'.format(base, signature)) self.assertTrue(locator.permission_expired()) self.assertTrue(locator.permission_expired(dt2000)) self.assertFalse(locator.permission_expired(dt1980)) if __name__ == '__main__': unittest.main()