def update(self, label, value, update_timestamp=None): """Stores the given value and timestamp for the given label. Args: label: the value's label. It must be a string. It can be empty. value: the value stored in the cache. Must not be None. update_timestamp: the timestamp in seconds of the value. If 'update_timestamp' is None, then the update timestamp associated with 'value' is the current wallclock time. If 'update_timestamp' is not None, then this timestamp is stored with 'value'. If 'value' is the same as the current value associated with the label after removal of 'timestamp' attributes, then the cached value is not changed. The cache keeps a deep copy of 'value', so the caller may change 'value' afterwards. Returns: The values that was stored in the cache. If the value stored in the cache was not changed, then the returned value is the deep copy of the old cached value. Otherwise the returned value is 'value'. In any case, the caller may modify 'value' or the returned value after this method returns. """ assert isinstance(label, types.StringTypes) assert value is not None assert ((update_timestamp is None) or isinstance(update_timestamp, float)) self._lock.acquire() # Cleanup only when inserting new values into the cache in order to # avoid penalizing the cache hit operation. ts = time.time() if update_timestamp is None else update_timestamp self._cleanup(ts) if ((label in self._label_to_tuple) and (utilities.timeless_json_hash(value) == utilities.timeless_json_hash( self._label_to_tuple[label].value))): # cannot update just one field in a named tuple. create_ts = self._label_to_tuple[label].create_timestamp update_value = self._label_to_tuple[label].value ret_value = copy.deepcopy(update_value) else: create_ts = ts update_value = copy.deepcopy(value) ret_value = value # cannot update just one field in a named tuple. self._label_to_tuple[label] = self._namedtuple( update_timestamp=ts, create_timestamp=create_ts, value=update_value) self._lock.release() return ret_value
def update(self, label, value, update_timestamp=None): """Stores the given value and timestamp for the given label. Args: label: the value's label. It must be a string. It can be empty. value: the value stored in the cache. Must not be None. update_timestamp: the timestamp in seconds of the value. If 'update_timestamp' is None, then the update timestamp associated with 'value' is the current wallclock time. If 'update_timestamp' is not None, then this timestamp is stored with 'value'. If 'value' is the same as the current value associated with the label after removal of 'timestamp' attributes, then the cached value is not changed. The cache keeps a deep copy of 'value', so the caller may change 'value' afterwards. Returns: The values that was stored in the cache. If the value stored in the cache was not changed, then the returned value is the deep copy of the old cached value. Otherwise the returned value is 'value'. In any case, the caller may modify 'value' or the returned value after this method returns. """ assert isinstance(label, types.StringTypes) assert value is not None assert ((update_timestamp is None) or isinstance(update_timestamp, types.FloatType)) self._lock.acquire() # Cleanup only when inserting new values into the cache in order to # avoid penalizing the cache hit operation. ts = time.time() if update_timestamp is None else update_timestamp self._cleanup(ts) if ((label in self._label_to_tuple) and (utilities.timeless_json_hash(value) == utilities.timeless_json_hash(self._label_to_tuple[label].value))): # cannot update just one field in a named tuple. create_ts = self._label_to_tuple[label].create_timestamp update_value = self._label_to_tuple[label].value ret_value = copy.deepcopy(update_value) else: create_ts = ts update_value = copy.deepcopy(value) ret_value = value # cannot update just one field in a named tuple. self._label_to_tuple[label] = self._namedtuple( update_timestamp=ts, create_timestamp=create_ts, value=update_value) self._lock.release() return ret_value
def test_make_response(self): """Tests make_response().""" # The timestamp of the first response is the current time. start_time = utilities.now() resp = utilities.make_response([], 'resources') end_time = utilities.now() # Note that timless_json_hash() ignores the value of the timestamp. self.assertEqual( utilities.timeless_json_hash( {'success': True, 'timestamp': utilities.now(), 'resources': []}), utilities.timeless_json_hash(resp)) self.assertTrue(start_time <= resp.get('timestamp') <= end_time) # The timestamp of the second response is the timestamp of the container. resp = utilities.make_response([CONTAINER], 'resources') self.assertEqual( utilities.timeless_json_hash( {'success': True, 'timestamp': utilities.now(), 'resources': [CONTAINER]}), utilities.timeless_json_hash(resp)) self.assertEqual(CONTAINER['timestamp'], resp['timestamp'])
def test_timeless_json_hash(self): """Tests timeless_json_hash() with multiple similar and dissimilar objects. """ a = {'uid': 'A', 'creationTimestamp': '2015-02-20T21:39:34Z'} # 'b1' and 'b2' differs just by the value of the 'lastProbeTime' attribute. b1 = {'uid': 'B', 'lastProbeTime': '2015-03-13T22:32:15Z'} b2 = {'uid': 'B', 'lastProbeTime': datetime.datetime.now().isoformat()} # 'wrapped_xxx' objects look like the objects we normally keep in the cache. # The difference between 'wrapped_a1' and 'wrapped_a2' is the value of the # 'timestamp' attribute. wrapped_a1 = utilities.wrap_object(a, 'Node', 'aaa', time.time()) wrapped_a2 = utilities.wrap_object(a, 'Node', 'aaa', time.time() + 100) # The difference between the 'wrapped_b1', 'wrapped_b2' and 'wrapped_b3' # objects are the values of the 'timestamp' and 'lastProbeTime' attributes. now = time.time() wrapped_b1 = utilities.wrap_object(b1, 'Node', 'bbb', now) wrapped_b2 = utilities.wrap_object(b2, 'Node', 'bbb', now) wrapped_b3 = utilities.wrap_object(b2, 'Node', 'bbb', now + 100) self.assertEqual(utilities.timeless_json_hash(wrapped_a1), utilities.timeless_json_hash(wrapped_a2)) self.assertEqual(utilities.timeless_json_hash(wrapped_b1), utilities.timeless_json_hash(wrapped_b2)) self.assertEqual(utilities.timeless_json_hash(wrapped_b1), utilities.timeless_json_hash(wrapped_b3)) # Verify that the hash values of lists of objects behaves as expected. self.assertEqual(utilities.timeless_json_hash([wrapped_a1, wrapped_b3]), utilities.timeless_json_hash([wrapped_a2, wrapped_b1])) # Verify that the hash value of dissimilar objects is not equal. self.assertTrue(utilities.timeless_json_hash(wrapped_a1) != utilities.timeless_json_hash(wrapped_b1))
def test_timeless_json_hash(self): """Tests timeless_json_hash() with multiple similar and dissimilar objects. """ a = {'uid': 'A', 'creationTimestamp': '2015-02-20T21:39:34Z'} # 'b1' and 'b2' differs just by the value of the 'lastProbeTime' attribute. b1 = {'uid': 'B', 'lastProbeTime': '2015-03-13T22:32:15Z'} b2 = {'uid': 'B', 'lastProbeTime': utilities.now()} # 'wrapped_xxx' objects look like the objects we normally keep in the cache. # The difference between 'wrapped_a1' and 'wrapped_a2' is the value of the # 'timestamp' attribute. wrapped_a1 = utilities.wrap_object(a, 'Node', 'aaa', time.time()) wrapped_a2 = utilities.wrap_object(a, 'Node', 'aaa', time.time() + 100) # The difference between the 'wrapped_b1', 'wrapped_b2' and 'wrapped_b3' # objects are the values of the 'timestamp' and 'lastProbeTime' attributes. now = time.time() wrapped_b1 = utilities.wrap_object(b1, 'Node', 'bbb', now) wrapped_b2 = utilities.wrap_object(b2, 'Node', 'bbb', now) wrapped_b3 = utilities.wrap_object(b2, 'Node', 'bbb', now + 100) self.assertEqual(utilities.timeless_json_hash(wrapped_a1), utilities.timeless_json_hash(wrapped_a2)) self.assertEqual(utilities.timeless_json_hash(wrapped_b1), utilities.timeless_json_hash(wrapped_b2)) self.assertEqual(utilities.timeless_json_hash(wrapped_b1), utilities.timeless_json_hash(wrapped_b3)) # Verify that the hash values of lists of objects behaves as expected. self.assertEqual(utilities.timeless_json_hash([wrapped_a1, wrapped_b3]), utilities.timeless_json_hash([wrapped_a2, wrapped_b1])) # Verify that the hash value of dissimilar objects is not equal. self.assertTrue(utilities.timeless_json_hash(wrapped_a1) != utilities.timeless_json_hash(wrapped_b1))