summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--morphlib/cachekeycomputer.py22
-rw-r--r--morphlib/cachekeycomputer_tests.py14
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]')
+