Skip to content

Commit 28b83af

Browse files
committed
Add support for tagged logs
This patch addresses #27 Change-Id: Ib9c133ba8f7ebfa2ff60017f882475f70cf0b2d6
1 parent 8101bf1 commit 28b83af

File tree

9 files changed

+188
-34
lines changed

9 files changed

+188
-34
lines changed

hdrh/codec.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,3 @@ def dump_payload(counts, max_index):
388388
# there is always a last series to dump
389389
_dump_series(series_start_index, index, counts[index])
390390
print('[%06d] --END-- total count=%d' % (index + 1, total_count))
391-
392-
def hex_dump(label, hstr):
393-
print(label)
394-
print(':'.join(x.encode('hex') for x in hstr))

hdrh/dump.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,25 @@
2020

2121
from hdrh.histogram import HdrHistogram
2222

23-
24-
def main():
25-
args = sys.argv[1:]
23+
def dump(args=None):
24+
"""
25+
Dump a list of Hdr histograms encodings
26+
27+
args: list of strings, each string representing an Hdr encoding
28+
"""
29+
if not args:
30+
args = sys.argv[1:]
31+
res = 1
2632
if args:
2733
encoded_histograms = args
2834
for hdrh in encoded_histograms:
2935
print('\nDumping histogram: ' + hdrh + '\n')
3036
HdrHistogram.dump(hdrh)
37+
res = 0
3138
else:
3239
print('\nUsage: %s [<string encoded hdr histogram>]*\n' % (sys.argv[0]))
40+
return res
3341

3442

3543
if __name__ == '__main__':
36-
main()
44+
sys.exit(dump())

hdrh/histogram.py

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ def __init__(self,
136136
self.counts = self.encoder.get_counts()
137137
self.start_time_stamp_msec = 0
138138
self.end_time_stamp_msec = 0
139+
# no tag by default
140+
self.tag = None
139141

140142
def _clz(self, value):
141143
"""calculate the leading zeros, equivalent to C __builtin_clzll()
@@ -421,24 +423,24 @@ def encode(self):
421423
'''
422424
return self.encoder.encode()
423425

424-
def adjust_internal_tacking_values(self,
425-
min_non_zero_index,
426-
max_index,
427-
total_added):
428-
'''Called during decoding and add to adjust the new min/max value and
429-
total count
430-
431-
Args:
432-
min_non_zero_index min nonzero index of all added counts (-1 if none)
433-
max_index max index of all added counts (-1 if none)
434-
'''
435-
if max_index >= 0:
436-
max_value = self.get_highest_equivalent_value(self.get_value_from_index(max_index))
437-
self.max_value = max(self.max_value, max_value)
438-
if min_non_zero_index >= 0:
439-
min_value = self.get_value_from_index(min_non_zero_index)
440-
self.min_value = min(self.min_value, min_value)
441-
self.total_count += total_added
426+
# def adjust_internal_tacking_values(self,
427+
# min_non_zero_index,
428+
# max_index,
429+
# total_added):
430+
# '''Called during decoding and add to adjust the new min/max value and
431+
# total count
432+
433+
# Args:
434+
# min_non_zero_index min nonzero index of all added counts (-1 if none)
435+
# max_index max index of all added counts (-1 if none)
436+
# '''
437+
# if max_index >= 0:
438+
# max_value = self.get_highest_equivalent_value(self.get_value_from_index(max_index))
439+
# self.max_value = max(self.max_value, max_value)
440+
# if min_non_zero_index >= 0:
441+
# min_value = self.get_value_from_index(min_non_zero_index)
442+
# self.min_value = min(self.min_value, min_value)
443+
# self.total_count += total_added
442444

443445
def set_internal_tacking_values(self,
444446
min_non_zero_index,
@@ -496,6 +498,18 @@ def set_end_time_stamp(self, time_stamp_msec):
496498
'''
497499
self.end_time_stamp_msec = time_stamp_msec
498500

501+
def set_tag(self, tag):
502+
"""
503+
Associate a tag to this histogram.
504+
"""
505+
self.tag = tag
506+
507+
def get_tag(self):
508+
"""
509+
Retrieve the tag for this histogram.
510+
"""
511+
return self.tag
512+
499513
def add(self, other_hist):
500514
highest_recordable_value = \
501515
self.get_highest_equivalent_value(self.get_value_from_index(self.counts_len - 1))
@@ -633,3 +647,30 @@ def dump(encoded_histogram, output=None,
633647
output = sys.stdout
634648
histogram.output_percentile_distribution(output,
635649
output_value_unit_scaling_ratio)
650+
651+
def equals(self, other):
652+
"""
653+
Check if this instance of histogram is equal to the provided histogram.
654+
655+
other: the other histogram to compare to
656+
return: True if this histogram are equivalent with the other.
657+
"""
658+
if self == other:
659+
return True
660+
if self.lowest_trackable_value != other.lowest_trackable_value or \
661+
self.int_to_double_conversion_ratio != other.int_to_double_conversion_ratio or \
662+
self.significant_figures != other.significant_figures:
663+
return False
664+
if self.get_total_count() != other.get_total_count():
665+
return False
666+
if self.get_max_value() != other.get_max_value():
667+
return False
668+
# if (getMinNonZeroValue() != that.getMinNonZeroValue()) {
669+
if self.get_min_value() != other.get_min_value():
670+
return False
671+
if self.counts_len != other.counts_len:
672+
return False
673+
for index in range(self.counts_len):
674+
if self.get_count_at_index(index) != other.get_count_at_index(index):
675+
return False
676+
return True

hdrh/log.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ def close(self):
138138
# "#[BaseTime: %f (seconds since epoch)]\n"
139139
re_base_time = re.compile(r'#\[BaseTime: *([\d\.]*) ')
140140

141+
142+
# 0.127,1.007,2.769,HISTFAAAAEV42pNpmSz...
143+
# Tag=A,0.127,1.007,2.769,HISTFAAAAEV42pNpmSz
141144
# "%f,%f,%f,%s\n"
142145
re_histogram_interval = re.compile(r'([\d\.]*),([\d\.]*),([\d\.]*),(.*)')
143146

@@ -231,6 +234,13 @@ def _decode_next_interval_histogram(self,
231234
self.observed_base_time = True
232235
continue
233236

237+
# check tag "Tag=<>,"
238+
if line.startswith('Tag='):
239+
index = line.find(',')
240+
tag = line[4:index]
241+
line = line[index + 1:]
242+
else:
243+
tag = None
234244
match_res = re_histogram_interval.match(line)
235245
if not match_res:
236246
# probably a legend line that starts with "\"StartTimestamp"
@@ -286,6 +296,8 @@ def _decode_next_interval_histogram(self,
286296
histogram = HdrHistogram.decode(cpayload)
287297
histogram.set_start_time_stamp(absolute_start_time_stamp_sec * 1000.0)
288298
histogram.set_end_time_stamp(absolute_end_time_stamp_sec * 1000.0)
299+
if tag:
300+
histogram.set_tag(tag)
289301
return histogram
290302

291303
def get_next_interval_histogram(self,

pylint.rc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -373,13 +373,13 @@ max-locals=20
373373
max-parents=7
374374

375375
# Maximum number of public methods for a class (see R0904).
376-
max-public-methods=40
376+
max-public-methods=50
377377

378378
# Maximum number of return / yield for function / method body
379-
max-returns=6
379+
max-returns=10
380380

381381
# Maximum number of statements in function / method body
382-
max-statements=50
382+
max-statements=100
383383

384384
# Minimum number of public methods for a class (see R0903).
385385
min-public-methods=0

test-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
pytest>=2.7.2
22
flake8>=2.3.0
33
pylint>=1.7.1
4+
pytest-cov>=2.9

test/tagged-Log.logV2.hlog

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#[Logged with jHiccup version 2.0.7-SNAPSHOT, manually edited to duplicate contents with Tag=A]
2+
#[Histogram log format version 1.2]
3+
#[StartTime: 1441812279.474 (seconds since epoch), Wed Sep 09 08:24:39 PDT 2015]
4+
"StartTimestamp","Interval_Length","Interval_Max","Interval_Compressed_Histogram"
5+
0.127,1.007,2.769,HISTFAAAAEV42pNpmSzMwMCgyAABTBDKT4GBgdnNYMcCBvsPEBEJISEuATEZMQ4uASkhIR4nrxg9v2lMaxhvMekILGZkKmcCAEf2CsI=
6+
Tag=A,0.127,1.007,2.769,HISTFAAAAEV42pNpmSzMwMCgyAABTBDKT4GBgdnNYMcCBvsPEBEJISEuATEZMQ4uASkhIR4nrxg9v2lMaxhvMekILGZkKmcCAEf2CsI=
7+
1.134,0.999,0.442,HISTFAAAAEJ42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBEWLj45FTExAT4pBSEBKa6UkAgBi1uM7xjfMMlwMDABAC0CCjM=
8+
Tag=A,1.134,0.999,0.442,HISTFAAAAEJ42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBEWLj45FTExAT4pBSEBKa6UkAgBi1uM7xjfMMlwMDABAC0CCjM=
9+
2.133,1.001,0.426,HISTFAAAAD942pNpmSzMwMAgwwABTBDKT4GBgdnNYMcCBvsPEBE+Ph4OLgk5OSkeIS4+LgEeswIDo1+MbmdYNASYAA51CSo=
10+
Tag=A,2.133,1.001,0.426,HISTFAAAAD942pNpmSzMwMAgwwABTBDKT4GBgdnNYMcCBvsPEBE+Ph4OLgk5OSkeIS4+LgEeswIDo1+MbmdYNASYAA51CSo=
11+
3.134,1.001,0.426,HISTFAAAAD942pNpmSzMwMAgwwABTBDKT4GBgdnNYMcCBvsPEBExPiEpITEFGTkRKSEeOR6FkCg1hTeMXvNYlHhYABQ5CTo=
12+
Tag=A,3.134,1.001,0.426,HISTFAAAAD942pNpmSzMwMAgwwABTBDKT4GBgdnNYMcCBvsPEBExPiEpITEFGTkRKSEeOR6FkCg1hTeMXvNYlHhYABQ5CTo=
13+
4.135,0.997,0.426,HISTFAAAAD942pNpmSzMwMAgwwABTBDKT4GBgdnNYMcCBvsPEBE2PiERBREpBREhER4+Hj4uvQAdrTlMBldYDDhYAAugCKk=
14+
Tag=A,4.135,0.997,0.426,HISTFAAAAD942pNpmSzMwMAgwwABTBDKT4GBgdnNYMcCBvsPEBE2PiERBREpBREhER4+Hj4uvQAdrTlMBldYDDhYAAugCKk=
15+
5.132,1.002,0.426,HISTFAAAAEF42pNpmSzMwMAgywABTBDKT4GBgdnNYMcCBvsPEBEWPhElOR4pARUpKTkpGQkxq2mMegZnGI0+MZuIcAEAHo8Jvw==
16+
Tag=A,5.132,1.002,0.426,HISTFAAAAEF42pNpmSzMwMAgywABTBDKT4GBgdnNYMcCBvsPEBEWPhElOR4pARUpKTkpGQkxq2mMegZnGI0+MZuIcAEAHo8Jvw==
17+
6.134,0.999,0.442,HISTFAAAAEF42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBEWIS4FITEhDiEJERE+GT6ZkhZGLbl7jEqrWHREmFgAIbAJMw==
18+
Tag=A,6.134,0.999,0.442,HISTFAAAAEF42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBEWIS4FITEhDiEJERE+GT6ZkhZGLbl7jEqrWHREmFgAIbAJMw==
19+
7.133,0.999,0.459,HISTFAAAAEJ42pNpmSzMwMCgwAABTBDKD8hndjPYsYDB/gNEhEtMQEBBTk5MQERCRkBEQEWlh9FJbg9jE+MS5ig1LhYmADkkCcE=
20+
Tag=A,7.133,0.999,0.459,HISTFAAAAEJ42pNpmSzMwMCgwAABTBDKD8hndjPYsYDB/gNEhEtMQEBBTk5MQERCRkBEQEWlh9FJbg9jE+MS5ig1LhYmADkkCcE=
21+
8.132,1.000,0.459,HISTFAAAAEB42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBEWIREgEOIQEuGT4xHg41Oo0pIqu8LYwVImwMfGBAAfkgkw
22+
Tag=A,8.132,1.000,0.459,HISTFAAAAEB42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBEWIREgEOIQEuGT4xHg41Oo0pIqu8LYwVImwMfGBAAfkgkw
23+
9.132,1.751,1551.892,HISTFAAAAJZ42pNpmSzMwMB0nQECmCCUnwIDA7ObwY4FDPYfYDJMXFxsbGwMbBwszDwsDDxsHFw6RWJMLJMZmcqBMJrJmskSiA2ZZJmkgRBCgmheIORGI1H5rEzMQAyDzFhY2EWRWUwMWCBxQtQQhAIWJiyAaEHyFbKwsLHAADYWAWmiFeKS5gACLsIEzdQICAgBIQShEfhFABXDF+M=
24+
Tag=A,9.132,1.751,1551.892,HISTFAAAAJZ42pNpmSzMwMB0nQECmCCUnwIDA7ObwY4FDPYfYDJMXFxsbGwMbBwszDwsDDxsHFw6RWJMLJMZmcqBMJrJmskSiA2ZZJmkgRBCgmheIORGI1H5rEzMQAyDzFhY2EWRWUwMWCBxQtQQhAIWJiyAaEHyFbKwsLHAADYWAWmiFeKS5gACLsIEzdQICAgBIQShEfhFABXDF+M=
25+
10.883,0.250,0.426,HISTFAAAAD142pNpmSzMwMAgxQABTBDKT4GBgdnNYMcCBvsPEBEeFi4mPg4WLhY2BjY2FhYOBSkpASEtoRA+NgDkCQZR
26+
Tag=A,10.883,0.250,0.426,HISTFAAAAD142pNpmSzMwMAgxQABTBDKT4GBgdnNYMcCBvsPEBEeFi4mPg4WLhY2BjY2FhYOBSkpASEtoRA+NgDkCQZR
27+
11.133,1.003,0.524,HISTFAAAAER42pNpmSzMwMCgyAABTBDKT4GBgdnNYMcCBvsPUBk2HgkZKREpEQUeGSEBAQ6xSYxhCnp7GJ02sWgJsbCwMgEAO0AJSQ==
28+
Tag=A,11.133,1.003,0.524,HISTFAAAAER42pNpmSzMwMCgyAABTBDKT4GBgdnNYMcCBvsPUBk2HgkZKREpEQUeGSEBAQ6xSYxhCnp7GJ02sWgJsbCwMgEAO0AJSQ==
29+
12.136,0.997,0.459,HISTFAAAAEB42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPUBk2AT4eCQURHgkuEREOHjERlSQhhWuMSV9Y7ERYWAAa4gko
30+
Tag=A,12.136,0.997,0.459,HISTFAAAAEB42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPUBk2AT4eCQURHgkuEREOHjERlSQhhWuMSV9Y7ERYWAAa4gko
31+
13.133,0.998,0.459,HISTFAAAAD942pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPMBkRIR4RMRk5KQE+PgEhMRmzEjWZJ4whW1hMBNiYAB42CTA=
32+
Tag=A,13.133,0.998,0.459,HISTFAAAAD942pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPMBkRIR4RMRk5KQE+PgEhMRmzEjWZJ4whW1hMBNiYAB42CTA=
33+
14.131,1.000,0.492,HISTFAAAAEN42pNpmSzMwMCgyAABTBDKT4GBgdnNYMcCBvsPUBkWFhE5GT4FKQkRCR4ZCREpqwmMBhpHGG16WHx42JgYmAA6swk+
34+
Tag=A,14.131,1.000,0.492,HISTFAAAAEN42pNpmSzMwMCgyAABTBDKT4GBgdnNYMcCBvsPUBkWFhE5GT4FKQkRCR4ZCREpqwmMBhpHGG16WHx42JgYmAA6swk+
35+
15.131,1.001,0.442,HISTFAAAAD542pNpmSzMwMAgywABTBDKT4GBgdnNYMcCBvsPMBkuMTEFHgklFRkRATkJERGdKgudfYwRTSwGalwAF2IJOw==
36+
Tag=A,15.131,1.001,0.442,HISTFAAAAD542pNpmSzMwMAgywABTBDKT4GBgdnNYMcCBvsPMBkuMTEFHgklFRkRATkJERGdKgudfYwRTSwGalwAF2IJOw==
37+
16.132,1.001,0.524,HISTFAAAAEZ42pNpmSzMwMCgxAABTBDKT4GBgdnNYMcCBvsPEBE2IQEFCQkpGREpHj4hKS6NU4z7GDMkuBoYDSYw2wiwMLEyAQBQ3wne
38+
Tag=A,16.132,1.001,0.524,HISTFAAAAEZ42pNpmSzMwMCgxAABTBDKT4GBgdnNYMcCBvsPEBE2IQEFCQkpGREpHj4hKS6NU4z7GDMkuBoYDSYw2wiwMLEyAQBQ3wne
39+
17.133,0.998,0.459,HISTFAAAAEB42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPUBk2DjElIR4RHiExKQE5IT61iCodtXWMdn0sKVJMTAAekAk0
40+
Tag=A,17.133,0.998,0.459,HISTFAAAAEB42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPUBk2DjElIR4RHiExKQE5IT61iCodtXWMdn0sKVJMTAAekAk0
41+
18.131,1.000,0.459,HISTFAAAAEF42pNpmSzMwMAgzwABTBDKT4GBgdnNYMcCBvsPUBkWISERJSUJESklHhEJEREhqwZGLakPjDZdLBYCHCwAKOkJPg==
42+
Tag=A,18.131,1.000,0.459,HISTFAAAAEF42pNpmSzMwMAgzwABTBDKT4GBgdnNYMcCBvsPUBkWISERJSUJESklHhEJEREhqwZGLakPjDZdLBYCHCwAKOkJPg==
43+
19.131,1.000,0.475,HISTFAAAAEF42pNpmSzMwMAgzwABTBDKT4GBgdnNYMcCBvsPUAk2HjkJBSk+Pi4BMT4xIQE9pxIluTOMPhtYbITY2JgAKLoJOQ==
44+
Tag=A,19.131,1.000,0.475,HISTFAAAAEF42pNpmSzMwMAgzwABTBDKT4GBgdnNYMcCBvsPUAk2HjkJBSk+Pi4BMT4xIQE9pxIluTOMPhtYbITY2JgAKLoJOQ==
45+
20.131,1.004,0.475,HISTFAAAAEF42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBFmPhEJOSEhDi4+ETEeASEhswIVi1+MFjtYvCRYGJgAIP8JNw==
46+
Tag=A,20.131,1.004,0.475,HISTFAAAAEF42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBFmPhEJOSEhDi4+ETEeASEhswIVi1+MFjtYvCRYGJgAIP8JNw==

test/test_hdrhistogram.py

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
from hdrh.log import HistogramLogReader
4949
from hdrh.codec import HdrPayload
5050
from hdrh.codec import HdrCookieException
51+
from hdrh.dump import dump
5152

5253
def python_bitness():
5354
"cross-platform way of calculating bitness, returns either 32 or 64"
@@ -72,6 +73,8 @@ def test_basic():
7273
assert histogram.counts_len == expected_counts_len
7374
assert histogram.unit_magnitude == 0
7475
assert histogram.sub_bucket_half_count_magnitude == 10
76+
assert histogram.get_count_at_sub_bucket(0, 0) == 0
77+
assert histogram.equals(histogram)
7578

7679
@pytest.mark.basic
7780
def test_empty_histogram():
@@ -296,6 +299,13 @@ def test_reset():
296299
assert histogram.get_value_at_percentile(99.99) == 0
297300
assert histogram.get_start_time_stamp() == sys.maxsize
298301
assert histogram.get_end_time_stamp() == 0
302+
print(histogram.get_percentile_to_value_dict([90, 99, 99.9]))
303+
304+
@pytest.mark.basic
305+
def test_perc_value_list():
306+
histogram = load_histogram()
307+
res = {90: 1000, 99.999: 100007935}
308+
assert histogram.get_percentile_to_value_dict(res.keys()) == res
299309

300310
@pytest.mark.basic
301311
def test_invalid_significant_figures():
@@ -366,6 +376,10 @@ def check_hdr_payload(counter_size):
366376
# now verify that the counters are identical to the original
367377
check_counts(dpayload, HDR_PAYLOAD_COUNTS)
368378

379+
# run dump
380+
payload.dump(label='test')
381+
382+
369383
@pytest.mark.codec
370384
def test_hdr_payload():
371385
# Check the payload work in all 3 supported counter sizes
@@ -625,6 +639,39 @@ def test_jHiccup_v2_log():
625639

626640
log_reader.close()
627641

642+
643+
TAGGED_V2_LOG = 'test/tagged-Log.logV2.hlog'
644+
@pytest.mark.log
645+
def test_tagged_v2_log():
646+
histogram_count = 0
647+
total_count = 0
648+
accumulated_histogram = HdrHistogram(LOWEST, HIGHEST, SIGNIFICANT)
649+
accumulated_histogram_tags = HdrHistogram(LOWEST, HIGHEST, SIGNIFICANT)
650+
log_reader = HistogramLogReader(TAGGED_V2_LOG, accumulated_histogram)
651+
while 1:
652+
decoded_histogram = log_reader.get_next_interval_histogram()
653+
if not decoded_histogram:
654+
break
655+
histogram_count += 1
656+
total_count += decoded_histogram.get_total_count()
657+
if decoded_histogram.get_tag() == 'A':
658+
accumulated_histogram_tags.add(decoded_histogram)
659+
else:
660+
assert decoded_histogram.get_tag() is None
661+
accumulated_histogram.add(decoded_histogram)
662+
663+
assert accumulated_histogram.equals(accumulated_histogram_tags)
664+
assert total_count == 32290
665+
666+
@pytest.mark.log
667+
def test_tagged_v2_log_add():
668+
accumulated_histogram = HdrHistogram(LOWEST, HIGHEST, SIGNIFICANT)
669+
log_reader = HistogramLogReader(TAGGED_V2_LOG, accumulated_histogram)
670+
while 1:
671+
decoded_histogram = log_reader.add_next_interval_histogram()
672+
if not decoded_histogram:
673+
break
674+
628675
@pytest.mark.log
629676
def test_output_percentile_distribution():
630677
histogram = load_histogram()
@@ -818,10 +865,6 @@ def test_zz_decode():
818865
for hdr_len in [0, 8]:
819866
check_zz_decode(int_type, hdr_len)
820867

821-
def hex_dump(label, str):
822-
print(label)
823-
print(':'.join(x.encode('hex') for x in str))
824-
825868
@pytest.mark.basic
826869
def test_get_value_at_percentile():
827870
histogram = HdrHistogram(LOWEST, 3600000000, 3)
@@ -836,3 +879,6 @@ def test_get_value_at_percentile():
836879
# val = histogram.get_value_at_percentile(25)
837880
# assert histogram.get_value_at_percentile(25) == 2
838881
assert histogram.get_value_at_percentile(30) == 2
882+
883+
def test_dump():
884+
dump(['HISTFAAAACl4nJNpmSzMwMBgyAABzFCaEURcm7yEwf4DROA8/4I5jNM7mJgAlWkH9g=='])

tox.ini

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@ commands = flake8 hdrh test
88
commands = pylint --rcfile pylint.rc hdrh test
99

1010
[testenv]
11+
setenv =
12+
LANG=en_US.UTF-8
13+
LC_ALL=en_US.UTF-8
1114
deps = -r{toxinidir}/requirements.txt
1215
-r{toxinidir}/test-requirements.txt
1316
commands=
14-
py.test -q --basetemp={envtmpdir} {posargs}
17+
{posargs:pytest --cov=hdrh --cov-report=term-missing -vv test}
18+
1519

1620
[flake8]
1721
show-source = True

0 commit comments

Comments
 (0)