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))
Exemple #5
0
  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))