diff options
-rw-r--r-- | morphlib/cachekeycomputer.py | 22 | ||||
-rw-r--r-- | morphlib/cachekeycomputer_tests.py | 14 |
2 files changed, 32 insertions, 4 deletions
diff --git a/morphlib/cachekeycomputer.py b/morphlib/cachekeycomputer.py index a1c2ebd6..6ae2b107 100644 --- a/morphlib/cachekeycomputer.py +++ b/morphlib/cachekeycomputer.py @@ -89,12 +89,26 @@ class CacheKeyComputer(object): if kind == 'chunk': keys['ref'] = artifact.source.sha1 elif kind in ('system', 'stratum'): - checksum = hashlib.sha1() morphology = artifact.source.morphology - getkey = lambda s: [ord(c) for c in s] - for key in sorted(morphology.keys(), key=getkey): - checksum.update('%s=%s' % (key, morphology[key])) + le_dict = dict((k,morphology[k]) for k in morphology.keys()) + checksum = hashlib.sha1(self._stringify(le_dict)) keys['morphology-sha1'] = checksum.hexdigest() return keys + def _stringify(self, value): + if type(value) in [str, unicode, int]: + return str(value) + elif value is None: + return '' + elif type(value) is list: + return '[' + ','.join(self._stringify(x) for x in value) + ']' + elif type(value) is dict: + keys = value.keys() + keys.sort(key=lambda s: [ord(c) for c in s]) + pairs = ['%s:%s' % (self._stringify(k), self._stringify(value[k])) + for k in keys] + return '{' + ','.join(pairs) + '}' + else: # pragma: no cover + raise NotImplementedError( + 'type %s is not stringified' % type(value)) diff --git a/morphlib/cachekeycomputer_tests.py b/morphlib/cachekeycomputer_tests.py index 7fc47370..32aef02e 100644 --- a/morphlib/cachekeycomputer_tests.py +++ b/morphlib/cachekeycomputer_tests.py @@ -166,3 +166,17 @@ class CacheKeyComputerTests(unittest.TestCase): old_sha = self.ckc.compute_key(old_artifact) new_sha = self.ckc.compute_key(new_artifact) self.assertEqual(old_sha, new_sha) + + def test_stringifies_string(self): + self.assertEqual(self.ckc._stringify('foo'), 'foo') + + def test_stringifies_integer(self): + self.assertEqual(self.ckc._stringify(12765), '12765') + + def test_stringifies_dict(self): + self.assertEqual(self.ckc._stringify({'foo': 'bar', 'yo': 'foobar' }), + '{foo:bar,yo:foobar}') + + def test_stringifies_list(self): + self.assertEqual(self.ckc._stringify(['foo', 'bar']), '[foo,bar]') + |