def test_value_accumulator_can_be_created_from_value(): reference = ValueAccumulator() reference.add(4.2) acc = ValueAccumulator(4.2) assert acc == reference
def test_value_accumulator_can_be_created_from_list(): reference = ValueAccumulator() reference.add(4.2) reference.add(1.3) acc = ValueAccumulator([4.2, 1.3]) assert acc == reference
def test_value_accumulator_can_be_stored_as_bytes(): values = [4.2, -1.3, 10.8] acc = ValueAccumulator(values) data = acc.to_bytes() assert isinstance(data, bytes) restored_acc = ValueAccumulator.from_bytes(data) assert acc == restored_acc
def test_value_accumulator_can_add_value(): value = 4.2 acc = ValueAccumulator() acc.add(value) assert acc.count == 1 assert acc.sum == value assert acc.avg == value assert acc.stddev is None assert acc.min == value assert acc.max == value assert acc.lo == value assert acc.hi == value
def test_value_accumulator_can_add_several_values(): values = [4.2, -1.3, 10.8] acc = ValueAccumulator() for value in values: acc.add(value) assert acc.count == len(values) assert acc.sum == sum(values) assert acc.avg == statistics.mean(values) assert acc.stddev == statistics.stdev(values) assert acc.min == min(values) assert acc.max == max(values) assert acc.min < acc.lo < acc.avg assert acc.avg < acc.hi < acc.max assert math.isclose(acc.hi - acc.lo, acc.stddev)
def test_value_accumulator_handles_same_values(): value = 4.2 count = 5 acc = ValueAccumulator() for _ in range(count): acc.add(value) assert acc.count == count assert acc.sum == value * count assert acc.avg == value assert acc.stddev == 0 assert acc.min == value assert acc.max == value assert acc.lo == value assert acc.hi == value
def test_value_accumulator_dont_return_anything_when_created(): acc = ValueAccumulator() assert acc.count == 0 assert acc.sum == 0 assert acc.avg is None assert acc.stddev is None assert acc.min is None assert acc.max is None assert acc.lo is None assert acc.hi is None
def generate_events(num: int, min_ts=None) -> List[MetricsEvent]: ts = gen_next_timestamp(min_ts) result = [] for _ in range(num): ts = gen_next_timestamp(ts) name = gen_metrics_name() if random() > 0.5: value = gauss(0.0, 100.0) else: value = ValueAccumulator([gauss(0.0, 100.0) for _ in range(randint(2, 5))]) result += [MetricsEvent(ts, name, value)] return result
def decode(key: bytes, value: bytes) -> Optional[MetricsEvent]: key = int.from_bytes(key, byteorder='big', signed=False) ts = datetime.utcfromtimestamp((key >> KvStoreMetricsFormat.seq_bits) / 1000000.0) name = int.from_bytes(value[:32], byteorder='big', signed=False) if name not in MetricsName.__members__.values(): return None name = MetricsName(name) data = value[32:] if len(data) == 8: value = struct.unpack('d', data)[0] else: value = ValueAccumulator.from_bytes(data) return MetricsEvent(ts, name, value)
def test_value_accumulator_with_one_value_is_stored_as_single_float64(): acc = ValueAccumulator() acc.add(4.2) data = acc.to_bytes() assert struct.unpack('d', data)[0] == 4.2 restored_acc = ValueAccumulator.from_bytes(data) assert acc == restored_acc
def test_value_accumulator_can_merge(): values = [4.2, -1.3, 10.8] acc = ValueAccumulator(values) other_values = [3.7, 7.6, -8.5] other_acc = ValueAccumulator(other_values) all_values = values + other_values all_acc = ValueAccumulator(all_values) acc.merge(other_acc) assert acc == all_acc
decoded_event = KvStoreMetricsFormat.decode(k, v) assert event == decoded_event def test_kv_store_encode_generate_different_keys_for_different_seq_no(): event = MetricsEvent(gen_next_timestamp(), gen_metrics_name(), 4.2) k1, v1 = KvStoreMetricsFormat.encode(event, 1) k2, v2 = KvStoreMetricsFormat.encode(event, 2) assert k1 != k2 assert v1 == v2 @pytest.mark.parametrize("value", [4.2, ValueAccumulator([42, -7, 0])]) def test_kv_store_metrics_collector_stores_properly_encoded_data( storage: KeyValueStorage, value): ts = MockTimestamp(gen_next_timestamp()) metrics = KvStoreMetricsCollector(storage, ts) assert len([(k, v) for k, v in storage.iterator()]) == 0 id = gen_metrics_name() event = MetricsEvent(ts.value, id, value) encoded_key, encoded_value = KvStoreMetricsFormat.encode(event) metrics.store_event(id, value) stored_events = [(k, v) for k, v in storage.iterator()] assert len(stored_events) == 1 assert stored_events[0][0] == encoded_key
def test_value_accumulator_eq_has_value_semantics(): a = ValueAccumulator() b = ValueAccumulator() assert a == b a.add(1.0) assert a != b b.add(1.0) assert a == b a.add(2.0) b.add(3.0) assert a != b