def test_compaction_rules(self): with Env().getConnection() as r: assert r.execute_command('TS.CREATE', 'tester', 'CHUNK_SIZE', '360') assert r.execute_command('TS.CREATE', 'tester_agg_max_10') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.CREATERULE', 'tester', 'tester_agg_max_10', 'AGGREGATION', 'avg', -10) with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.CREATERULE', 'tester', 'tester_agg_max_10', 'AGGREGATION', 'avg', 0) assert r.execute_command('TS.CREATERULE', 'tester', 'tester_agg_max_10', 'AGGREGATION', 'avg', 10) start_ts = 1488823384 samples_count = 1500 _insert_data(r, 'tester', start_ts, samples_count, 5) last_ts = start_ts + samples_count + 10 r.execute_command('TS.ADD', 'tester', last_ts, 5) actual_result = r.execute_command('TS.RANGE', 'tester_agg_max_10', start_ts, start_ts + samples_count) assert len(actual_result) == samples_count / 10 info = _get_ts_info(r, 'tester') assert info.rules == [[b'tester_agg_max_10', 10, b'AVG']]
def test_aggreataion_alignment(): start_ts = 1511885909 samples_count = 1200 env = Env(decodeResponses=True) with env.getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', 'tester') _insert_data(r, 'tester', start_ts, samples_count, list(i for i in range(samples_count))) agg_size = 60 expected_data = build_expected_aligned_data(start_ts, start_ts + samples_count, agg_size, start_ts) assert expected_data == \ decode_if_needed(r.execute_command('TS.range', 'tester', start_ts, '+', 'ALIGN', 'start', 'AGGREGATION', 'count', agg_size)) assert expected_data == \ decode_if_needed(r.execute_command('TS.range', 'tester', start_ts, '+', 'ALIGN', '-', 'AGGREGATION', 'count', agg_size)) specific_ts = start_ts + 50 expected_data = build_expected_aligned_data(start_ts, start_ts + samples_count, agg_size, specific_ts) assert expected_data == \ decode_if_needed(r.execute_command('TS.range', 'tester', '-', '+', 'ALIGN', specific_ts, 'AGGREGATION', 'count', agg_size)) end_ts = start_ts + samples_count - 1 expected_data = build_expected_aligned_data(start_ts, start_ts + samples_count, agg_size, end_ts) assert expected_data == \ decode_if_needed(r.execute_command('TS.range', 'tester', '-', end_ts, 'ALIGN', 'end', 'AGGREGATION', 'count', agg_size)) assert expected_data == \ decode_if_needed(r.execute_command('TS.range', 'tester', '-', end_ts, 'ALIGN', '+', 'AGGREGATION', 'count', agg_size))
def test_range_with_agg_query(): start_ts = 1488823384 samples_count = 1500 with Env().getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', 'tester') _insert_data(r, 'tester', start_ts, samples_count, 5) expected_result = [[1488823000, b'116'], [1488823500, b'500'], [1488824000, b'500'], [1488824500, b'384']] actual_result = r.execute_command('TS.range', 'tester', start_ts, start_ts + samples_count, 'AGGREGATION', 'count', 500) assert expected_result == actual_result # test first aggregation is not [0,0] if out of range expected_result = [[1488823000, b'116'], [1488823500, b'500']] actual_result = r.execute_command('TS.range', 'tester', 1488822000, 1488823999, b'AGGREGATION', 'count', 500) assert expected_result == actual_result with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.range', 'tester', start_ts, start_ts + samples_count, 'AGGREGATION', 'count', -1)
def test_filter_by(): start_ts = 1511885909 samples_count = 1500 env = Env() with env.getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', 'tester', 'RETENTION', '0', 'CHUNK_SIZE', '1024', 'LABELS', 'name', 'brown', 'color', 'pink') _insert_data(r, 'tester', start_ts, samples_count, list(i for i in range(samples_count))) res = r.execute_command('ts.range', 'tester', start_ts, -1, 'FILTER_BY_VALUE', 40, 52) assert len(res) == 13 assert [int(sample[1]) for sample in res] == list(range(40, 53)) res = r.execute_command('ts.range', 'tester', start_ts, -1, 'FILTER_BY_TS', start_ts + 1021, start_ts + 1022, start_ts + 1025, start_ts + 1029) env.assertEqual( res, [[start_ts + 1021, b'1021'], [start_ts + 1022, b'1022'], [start_ts + 1025, b'1025'], [start_ts + 1029, b'1029']]) res = r.execute_command('ts.range', 'tester', start_ts, -1, 'FILTER_BY_TS', start_ts + 1021, start_ts + 1022, start_ts + 1023, start_ts + 1025, start_ts + 1029, 'FILTER_BY_VALUE', 1022, 1025) env.assertEqual( res, [[start_ts + 1022, b'1022'], [start_ts + 1023, b'1023'], [start_ts + 1025, b'1025']])
def test_compaction_rules(self): with Env().getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', key_name, 'CHUNK_SIZE', '360') assert r.execute_command('TS.CREATE', agg_key_name) with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.CREATERULE', key_name, agg_key_name, 'AGGREGATION', 'avg', -10) with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.CREATERULE', key_name, agg_key_name, 'AGGREGATION', 'avg', 0) assert r.execute_command('TS.CREATERULE', key_name, agg_key_name, 'AGGREGATION', 'avg', 10) start_ts = 1488823384 samples_count = 1500 _insert_data(r, key_name, start_ts, samples_count, 5) last_ts = start_ts + samples_count + 10 r.execute_command('TS.ADD', key_name, last_ts, 5) actual_result = r.execute_command('TS.RANGE', agg_key_name, start_ts, start_ts + samples_count) assert len(actual_result) == samples_count / 10 info = _get_ts_info(r, key_name) assert info.rules == [[agg_key_name.encode('ascii'), 10, b'AVG']]
def test_rdb(): start_ts = 1511885909 samples_count = 1500 data = None key_name = 'tester{abc}' with Env().getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', key_name, 'RETENTION', '0', 'CHUNK_SIZE', '360', 'LABELS', 'name', 'brown', 'color', 'pink') assert r.execute_command('TS.CREATE', '{}_agg_avg_10'.format(key_name)) assert r.execute_command('TS.CREATE', '{}_agg_max_10'.format(key_name)) assert r.execute_command('TS.CREATE', '{}_agg_sum_10'.format(key_name)) assert r.execute_command('TS.CREATE', '{}_agg_stds_10'.format(key_name)) assert r.execute_command('TS.CREATERULE', key_name, '{}_agg_avg_10'.format(key_name), 'AGGREGATION', 'AVG', 10) assert r.execute_command('TS.CREATERULE', key_name, '{}_agg_max_10'.format(key_name), 'AGGREGATION', 'MAX', 10) assert r.execute_command('TS.CREATERULE', key_name, '{}_agg_sum_10'.format(key_name), 'AGGREGATION', 'SUM', 10) assert r.execute_command('TS.CREATERULE', key_name, '{}_agg_stds_10'.format(key_name), 'AGGREGATION', 'STD.S', 10) _insert_data(r, key_name, start_ts, samples_count, 5) data = r.execute_command('DUMP', key_name) avg_data = r.execute_command('DUMP', '{}_agg_avg_10'.format(key_name)) r.execute_command('DEL', key_name, '{}_agg_avg_10'.format(key_name)) r.execute_command('RESTORE', key_name, 0, data) r.execute_command('RESTORE', '{}_agg_avg_10'.format(key_name), 0, avg_data) expected_result = [[start_ts + i, b'5'] for i in range(samples_count)] actual_result = r.execute_command('TS.range', key_name, start_ts, start_ts + samples_count) assert expected_result == actual_result actual_result = r.execute_command('TS.range', key_name, start_ts, start_ts + samples_count, 'count', 3) assert expected_result[:3] == actual_result assert _get_ts_info(r, key_name).rules == [] assert _get_ts_info(r, '{}_agg_avg_10'.format(key_name)).sourceKey == None
def test_rdb_aggregation_context(): """ Check that the aggregation context of the rules is saved in rdb. Write data with not a full bucket, then save it and restore, add more data to the bucket and check the rules results considered the previous data that was in that bucket in their calculation. Check on avg and min, since all the other rules use the same context as min. """ start_ts = 3 samples_count = 4 # 1 full bucket and another one with 1 value key_name = 'tester{abc}' with Env().getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', key_name) assert r.execute_command('TS.CREATE', '{}_agg_avg_3'.format(key_name)) assert r.execute_command('TS.CREATE', '{}_agg_min_3'.format(key_name)) assert r.execute_command('TS.CREATE', '{}_agg_sum_3'.format(key_name)) assert r.execute_command('TS.CREATE', '{}_agg_std_3'.format(key_name)) assert r.execute_command('TS.CREATERULE', key_name, '{}_agg_avg_3'.format(key_name), 'AGGREGATION', 'AVG', 3) assert r.execute_command('TS.CREATERULE', key_name, '{}_agg_min_3'.format(key_name), 'AGGREGATION', 'MIN', 3) assert r.execute_command('TS.CREATERULE', key_name, '{}_agg_sum_3'.format(key_name), 'AGGREGATION', 'SUM', 3) assert r.execute_command('TS.CREATERULE', key_name, '{}_agg_std_3'.format(key_name), 'AGGREGATION', 'STD.S', 3) _insert_data(r, key_name, start_ts, samples_count, list(range(samples_count))) data_tester = r.execute_command('dump', key_name) data_avg_tester = r.execute_command('dump', '{}_agg_avg_3'.format(key_name)) data_min_tester = r.execute_command('dump', '{}_agg_min_3'.format(key_name)) data_sum_tester = r.execute_command('dump', '{}_agg_sum_3'.format(key_name)) data_std_tester = r.execute_command('dump', '{}_agg_std_3'.format(key_name)) r.execute_command('DEL', key_name, '{}_agg_avg_3'.format(key_name), '{}_agg_min_3'.format(key_name), '{}_agg_sum_3'.format(key_name), '{}_agg_std_3'.format(key_name)) r.execute_command('RESTORE', key_name, 0, data_tester) r.execute_command('RESTORE', '{}_agg_avg_3'.format(key_name), 0, data_avg_tester) r.execute_command('RESTORE', '{}_agg_min_3'.format(key_name), 0, data_min_tester) r.execute_command('RESTORE', '{}_agg_sum_3'.format(key_name), 0, data_sum_tester) r.execute_command('RESTORE', '{}_agg_std_3'.format(key_name), 0, data_std_tester) assert r.execute_command('TS.CREATERULE', key_name, '{}_agg_avg_3'.format(key_name), 'AGGREGATION', 'AVG', 3) assert r.execute_command('TS.CREATERULE', key_name, '{}_agg_min_3'.format(key_name), 'AGGREGATION', 'MIN', 3) assert r.execute_command('TS.CREATERULE', key_name, '{}_agg_sum_3'.format(key_name), 'AGGREGATION', 'SUM', 3) assert r.execute_command('TS.CREATERULE', key_name, '{}_agg_std_3'.format(key_name), 'AGGREGATION', 'STD.S', 3) assert r.execute_command('TS.ADD', key_name, start_ts + samples_count, samples_count - 1) assert r.execute_command('TS.ADD', key_name, start_ts + samples_count + 1, samples_count) assert r.execute_command('TS.ADD', key_name, start_ts + samples_count + 10, 0) # closes the last time_bucket # if the aggregation context wasn't saved, the results were considering only the new value added expected_result_avg = [[start_ts, b'1'], [start_ts + 3, b'3.5']] expected_result_min = [[start_ts, b'0'], [start_ts + 3, b'3']] expected_result_sum = [[start_ts, b'3'], [start_ts + 3, b'7']] expected_result_std = [[start_ts, b'1'], [start_ts + 3, b'0.7071']] actual_result_avg = r.execute_command('TS.range', '{}_agg_avg_3'.format(key_name), start_ts, start_ts + samples_count) assert actual_result_avg == expected_result_avg actual_result_min = r.execute_command('TS.range', '{}_agg_min_3'.format(key_name), start_ts, start_ts + samples_count) assert actual_result_min == expected_result_min actual_result_sum = r.execute_command('TS.range', '{}_agg_sum_3'.format(key_name), start_ts, start_ts + samples_count) assert actual_result_sum == expected_result_sum actual_result_std = r.execute_command('TS.range', '{}_agg_std_3'.format(key_name), start_ts, start_ts + samples_count) assert actual_result_std[0] == expected_result_std[0] assert abs(float(actual_result_std[1][1]) - float(expected_result_std[1][1])) < ALLOWED_ERROR
def test_create_compaction_rule_and_del_dest_series(): with Env().getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', key_name) assert r.execute_command('TS.CREATE', agg_key_name) assert r.execute_command('TS.CREATERULE', key_name, agg_key_name, 'AGGREGATION', 'AVG', 10) assert r.delete(agg_key_name) start_ts = 1488823384 samples_count = 1500 _insert_data(r, key_name, start_ts, samples_count, 5)
def test_create_compaction_rule_and_del_dest_series(): with Env().getConnection() as r: assert r.execute_command('TS.CREATE', 'tester') assert r.execute_command('TS.CREATE', 'tester_agg_max_10') assert r.execute_command('TS.CREATERULE', 'tester', 'tester_agg_max_10', 'AGGREGATION', 'AVG', 10) assert r.delete('tester_agg_max_10') start_ts = 1488823384 samples_count = 1500 _insert_data(r, 'tester', start_ts, samples_count, 5)
def test_downsampling_rules(self): """ Test downsmapling rules - avg,min,max,count,sum with 4 keys each. Downsample in resolution of: 1sec (should be the same length as the original series), 3sec (number of samples is divisible by 10), 10s (number of samples is not divisible by 10), 1000sec (series should be empty since there are not enough samples) Insert some data and check that the length, the values and the info of the downsample series are as expected. """ with Env().getConnection() as r: assert r.execute_command('TS.CREATE', 'tester') rules = ['avg', 'sum', 'count', 'max', 'min'] resolutions = [1, 3, 10, 1000] for rule in rules: for resolution in resolutions: assert r.execute_command( 'TS.CREATE', 'tester_{}_{}'.format(rule, resolution)) assert r.execute_command( 'TS.CREATERULE', 'tester', 'tester_{}_{}'.format(rule, resolution), 'AGGREGATION', rule, resolution) start_ts = 0 samples_count = 501 end_ts = start_ts + samples_count values = list(range(samples_count)) _insert_data(r, 'tester', start_ts, samples_count, values) r.execute_command('TS.ADD', 'tester', 3000, 7.77) for rule in rules: for resolution in resolutions: actual_result = r.execute_command( 'TS.RANGE', 'tester_{}_{}'.format(rule, resolution), start_ts, end_ts) assert len(actual_result) == math.ceil(samples_count / float(resolution)) expected_result = calc_rule(rule, values, resolution) assert _get_series_value(actual_result) == expected_result # last time stamp should be the beginning of the last bucket assert _get_ts_info(r, 'tester_{}_{}'.format(rule, resolution)).last_time_stamp == \ (samples_count - 1) - (samples_count - 1) % resolution # test for results after empty buckets r.execute_command('TS.ADD', 'tester', 6000, 0) for rule in rules: for resolution in resolutions: actual_result = r.execute_command( 'TS.RANGE', 'tester_{}_{}'.format(rule, resolution), 3000, 6000) assert len(actual_result) == 1 assert _get_series_value(actual_result) == [7.77] or \ _get_series_value(actual_result) == [1]
def test_alter_cmd(): start_ts = 1511885909 samples_count = 1500 end_ts = start_ts + samples_count key = 'tester' with Env().getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', key, 'CHUNK_SIZE', '360', 'LABELS', 'name', 'brown', 'color', 'pink') _insert_data(r, key, start_ts, samples_count, 5) expected_data = [[start_ts + i, str(5).encode('ascii')] for i in range(samples_count)] # test alter retention, chunk size and labels expected_labels = [[b'A', b'1'], [b'B', b'2'], [b'C', b'3']] expected_retention = 500 expected_chunk_size = 100 _ts_alter_cmd(r, key, expected_retention, expected_chunk_size, expected_labels) _assert_alter_cmd(r, key, end_ts - 501, end_ts, expected_data[-501:], expected_retention, expected_chunk_size, expected_labels) # test alter retention expected_retention = 200 _ts_alter_cmd(r, key, set_retention=expected_retention) _assert_alter_cmd(r, key, end_ts - 201, end_ts, expected_data[-201:], expected_retention, expected_chunk_size, expected_labels) # test alter chunk size expected_chunk_size = 100 expected_labels = [[b'A', b'1'], [b'B', b'2'], [b'C', b'3']] _ts_alter_cmd(r, key, set_chunk_size=expected_chunk_size) _assert_alter_cmd(r, key, end_ts - 201, end_ts, expected_data[-201:], expected_retention, expected_chunk_size, expected_labels) # test alter labels expected_labels = [[b'A', b'1']] _ts_alter_cmd(r, key, expected_retention, set_labels=expected_labels) _assert_alter_cmd(r, key, end_ts - 201, end_ts, expected_data[-201:], expected_retention, expected_chunk_size, expected_labels) # test indexer was updated assert r.execute_command('TS.QUERYINDEX', 'A=1') == [key.encode('ascii')] assert r.execute_command('TS.QUERYINDEX', 'name=brown') == []
def test_sanity_pipeline(): start_ts = 1488823384 samples_count = 1500 with Env().getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', 'tester') with r.pipeline(transaction=False) as p: p.set("name", "danni") _insert_data(p, 'tester', start_ts, samples_count, 5) p.execute() expected_result = [[start_ts + i, str(5).encode('ascii')] for i in range(samples_count)] actual_result = r.execute_command('TS.range', 'tester', start_ts, start_ts + samples_count) assert expected_result == actual_result
def test_range_query(): start_ts = 1488823384 samples_count = 1500 with Env().getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', 'tester', 'uncompressed', 'RETENTION', samples_count - 100) _insert_data(r, 'tester', start_ts, samples_count, 5) expected_result = [[start_ts + i, str(5).encode('ascii')] for i in range(99, 151)] actual_result = r.execute_command('TS.range', 'tester', start_ts + 50, start_ts + 150) assert expected_result == actual_result rev_result = r.execute_command('TS.revrange', 'tester', start_ts + 50, start_ts + 150) rev_result.reverse() assert expected_result == rev_result # test out of range returns empty list assert [] == r.execute_command('TS.range', 'tester', int(start_ts * 2), -1) assert [] == r.execute_command('TS.range', 'tester', int(start_ts / 3), int(start_ts / 2)) assert [] == r.execute_command('TS.revrange', 'tester', int(start_ts * 2), -1) assert [] == r.execute_command('TS.revrange', 'tester', int(start_ts / 3), int(start_ts / 2)) with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.RANGE', 'tester', 'string', -1) with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.RANGE', 'tester', 0, 'string') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.RANGE', 'nonexist', 0 - 1) with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.RANGE', 'tester', 0, -1, 'count', 'number') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.RANGE', 'tester', 0, -1, 'count') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.RANGE', 'tester', 0, -1, 'aggregation', 'count', 'number') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.RANGE', 'tester', 0, -1, 'aggregation', 'count')
def test_mrange_withlabels(): start_ts = 1511885909 samples_count = 50 with Env().getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', 'tester1', 'LABELS', 'name', 'bob', 'class', 'middle', 'generation', 'x') assert r.execute_command('TS.CREATE', 'tester2', 'LABELS', 'name', 'rudy', 'class', 'junior', 'generation', 'x') assert r.execute_command('TS.CREATE', 'tester3', 'LABELS', 'name', 'fabi', 'class', 'top', 'generation', 'x') _insert_data(r, 'tester1', start_ts, samples_count, 5) _insert_data(r, 'tester2', start_ts, samples_count, 15) _insert_data(r, 'tester3', start_ts, samples_count, 25) expected_result = [[start_ts + i, str(5).encode('ascii')] for i in range(samples_count)] actual_result = r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'WITHLABELS', 'FILTER', 'name=bob') assert [[ b'tester1', [[b'name', b'bob'], [b'class', b'middle'], [b'generation', b'x']], expected_result ]] == actual_result actual_result = r.execute_command('TS.mrange', start_ts + 1, start_ts + samples_count, 'WITHLABELS', 'AGGREGATION', 'COUNT', 1, 'FILTER', 'generation=x') # assert the labels length is 3 (name,class,generation) for each of the returned time-series assert len(actual_result[0][1]) == 3 assert len(actual_result[1][1]) == 3 assert len(actual_result[2][1]) == 3
def test_sanity(): start_ts = 1511885909 samples_count = 1500 with Env().getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', 'tester', 'RETENTION', '0', 'CHUNK_SIZE', '1024', 'LABELS', 'name', 'brown', 'color', 'pink') _insert_data(r, 'tester', start_ts, samples_count, 5) expected_result = [[start_ts + i, str(5).encode('ascii')] for i in range(samples_count)] actual_result = r.execute_command('TS.range', 'tester', start_ts, start_ts + samples_count) assert expected_result == actual_result expected_result = [ b'totalSamples', 1500, b'memoryUsage', 1166, b'firstTimestamp', start_ts, b'chunkCount', 1, b'labels', [[b'name', b'brown'], [b'color', b'pink']], b'lastTimestamp', start_ts + samples_count - 1, b'chunkSize', 1024, b'retentionTime', 0, b'sourceKey', None, b'rules', [] ] assert TSInfo(expected_result) == _get_ts_info(r, 'tester')
def testLibmrFail(): env = Env() if env.shardsCount < 3: env.skip() if (not env.isCluster): env.skip() env.skipOnSlave() # There can't be 2 rdb save at the same time env.skipOnAOF() start_ts = 1 samples_count = 10 with env.getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', 'tester1{1}', 'LABELS', 'name', 'bob') _insert_data(r, 'tester1{1}', start_ts, samples_count, 1) try: env.envRunner.shards[2].stopEnv() except Exception as e: pass Refresh_Cluster(env) try: actual_result = env.getConnection(1).execute_command( 'TS.mrange', start_ts, start_ts + samples_count, 'WITHLABELS', 'FILTER', 'name=bob') assert (False) except Exception as e: env.assertResponseError(e, "multi shard cmd failed") env.envRunner.shards[2].startEnv() Refresh_Cluster(env) expected_res = [[ b'tester1{1}', [[b'name', b'bob']], [[1, b'1'], [2, b'1'], [3, b'1'], [4, b'1'], [5, b'1'], [6, b'1'], [7, b'1'], [8, b'1'], [9, b'1'], [10, b'1']] ]] actual_result = env.getConnection(1).execute_command( 'TS.mrange', start_ts, start_ts + samples_count, 'WITHLABELS', 'FILTER', 'name=bob') env.assertEqual(actual_result, expected_res)
def test_mrevrange(): start_ts = 1511885909 samples_count = 50 with Env().getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', 'tester1', 'LABELS', 'name', 'bob', 'class', 'middle', 'generation', 'x') assert r.execute_command('TS.CREATE', 'tester2', 'LABELS', 'name', 'rudy', 'class', 'junior', 'generation', 'x') assert r.execute_command('TS.CREATE', 'tester3', 'LABELS', 'name', 'fabi', 'class', 'top', 'generation', 'x') _insert_data(r, 'tester1', start_ts, samples_count, 5) _insert_data(r, 'tester2', start_ts, samples_count, 15) _insert_data(r, 'tester3', start_ts, samples_count, 25) expected_result = [[start_ts + i, str(5).encode('ascii')] for i in range(samples_count)] expected_result.reverse() actual_result = r.execute_command('TS.mrevrange', start_ts, start_ts + samples_count, 'FILTER', 'name=bob') assert [[b'tester1', [], expected_result]] == actual_result actual_result = r.execute_command('TS.mrevrange', start_ts, start_ts + samples_count, 'COUNT', '5', 'FILTER', 'generation=x') actual_result.sort(key=lambda x: x[0]) assert actual_result == [[ b'tester1', [], [[1511885958, b'5'], [1511885957, b'5'], [1511885956, b'5'], [1511885955, b'5'], [1511885954, b'5']] ], [ b'tester2', [], [[1511885958, b'15'], [1511885957, b'15'], [1511885956, b'15'], [1511885955, b'15'], [1511885954, b'15']] ], [ b'tester3', [], [[1511885958, b'25'], [1511885957, b'25'], [1511885956, b'25'], [1511885955, b'25'], [1511885954, b'25']] ]] agg_result = r.execute_command('TS.mrange', 0, -1, 'AGGREGATION', 'sum', 50, 'FILTER', 'name=bob')[0][2] rev_agg_result = r.execute_command('TS.mrevrange', 0, -1, 'AGGREGATION', 'sum', 50, 'FILTER', 'name=bob')[0][2] rev_agg_result.reverse() assert rev_agg_result == agg_result last_results = list(agg_result) last_results.reverse() last_results = last_results[0:3] assert r.execute_command('TS.mrevrange', 0, -1, 'AGGREGATION', 'sum', 50, 'COUNT', 3, 'FILTER', 'name=bob')[0][2] == last_results
def test_range_by_labels(): start_ts = 1511885909 samples_count = 50 env = Env() with Env().getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', 'tester1', 'LABELS', 'name', 'bob', 'class', 'middle', 'generation', 'x') assert r.execute_command('TS.CREATE', 'tester2', 'LABELS', 'name', 'rudy', 'class', 'junior', 'generation', 'x') assert r.execute_command('TS.CREATE', 'tester3', 'LABELS', 'name', 'fabi', 'class', 'top', 'generation', 'x') _insert_data(r, 'tester1', start_ts, samples_count, 5) _insert_data(r, 'tester2', start_ts, samples_count, 15) _insert_data(r, 'tester3', start_ts, samples_count, 25) expected_result = [[start_ts + i, str(5).encode('ascii')] for i in range(samples_count)] actual_result = r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'FILTER', 'name=bob') assert [[b'tester1', [], expected_result]] == actual_result expected_result.reverse() actual_result = r.execute_command('TS.mrevrange', start_ts, start_ts + samples_count, 'FILTER', 'name=bob') assert [[b'tester1', [], expected_result]] == actual_result def build_expected(val, time_bucket): return [[int(i - i % time_bucket), str(val).encode('ascii')] for i in range(start_ts, start_ts + samples_count + 1, time_bucket)] actual_result = r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'AGGREGATION', 'LAST', 5, 'FILTER', 'generation=x') expected_result = [ [b'tester1', [], build_expected(5, 5)], [b'tester2', [], build_expected(15, 5)], [b'tester3', [], build_expected(25, 5)], ] env.assertEqual(sorted(expected_result), sorted(actual_result)) assert expected_result[1:] == sorted(r.execute_command( 'TS.mrange', start_ts, start_ts + samples_count, 'AGGREGATION', 'LAST', 5, 'FILTER', 'generation=x', 'class!=middle'), key=lambda x: x[0]) actual_result = r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'COUNT', 3, 'AGGREGATION', 'LAST', 5, 'FILTER', 'generation=x') assert expected_result[0][2][:3] == sorted(actual_result, key=lambda x: x[0])[0][2] actual_result = r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'AGGREGATION', 'COUNT', 5, 'FILTER', 'generation=x') assert [[1511885905, b'1']] == actual_result[0][2][:1] assert expected_result[0][2][1:9] == actual_result[0][2][1:9] actual_result = r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'AGGREGATION', 'COUNT', 3, 'COUNT', 3, 'FILTER', 'generation=x') assert 3 == len(actual_result[0] [2]) # just checking that agg count before count works actual_result = r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'COUNT', 3, 'AGGREGATION', 'COUNT', 3, 'FILTER', 'generation=x') assert 3 == len(actual_result[0] [2]) # just checking that agg count before count works actual_result = r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'AGGREGATION', 'COUNT', 3, 'FILTER', 'generation=x') assert 18 == len( actual_result[0] [2]) # just checking that agg count before count works with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'AGGREGATION', 'invalid', 3, 'FILTER', 'generation=x') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'AGGREGATION', 'AVG', 'string', 'FILTER', 'generation=x') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'COUNT', 'string', 'FILTER', 'generation=x') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', '-', '+', 'FILTER') # missing args with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', '-', '+', 'RETLIF') # no filter word with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', 'string', start_ts + samples_count, 'FILTER', 'generation=x') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', start_ts, 'string', 'FILTER', 'generation=x') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'FILTER', 'generation+x') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'FILTER', 'generation!=x') # issue 414 with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'FILTER', 'name=(bob,rudy,)') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'FILTER', 'name=(bob,,rudy)') # test SELECTED_LABELS with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'SELECTED_LABELS', 'filter', 'k!=5') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'SELECTED_LABELS', 'filter', 'k!=5') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'SELECTED_LABELS', 'WITHLABELS', 'filter', 'k!=5') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'WITHLABELS', 'SELECTED_LABELS', 'filter', 'k!=5')
def test_mrange_filterby(): start_ts = 1511885909 samples_count = 50 env = Env() with env.getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', 'tester1', 'LABELS', 'name', 'bob', 'class', 'middle', 'generation', 'x') assert r.execute_command('TS.CREATE', 'tester2', 'LABELS', 'name', 'rudy', 'class', 'junior', 'generation', 'x') assert r.execute_command('TS.CREATE', 'tester3', 'LABELS', 'name', 'fabi', 'class', 'top', 'generation', 'x') _insert_data(r, 'tester1', start_ts, samples_count, 5) _insert_data(r, 'tester2', start_ts, samples_count, 15) _insert_data(r, 'tester3', start_ts, samples_count, 25) with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'FILTER_BY_VALUE', "a", 1, 'FILTER', 'name=bob') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'FILTER_BY_VALUE', "a", "a", 'FILTER', 'name=bob') with pytest.raises(redis.ResponseError) as excinfo: assert r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'FILTER_BY_VALUE', 1, "a", 'FILTER', 'name=bob') expected_result = [ [b'tester1', [], []], [ b'tester2', [], [[start_ts + i, str(15).encode('ascii')] for i in range(samples_count)] ], [b'tester3', [], []], ] actual_result = r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'FILTER_BY_VALUE', 10, 20, 'FILTER', 'generation=x') env.assertEqual(sorted(actual_result), sorted(expected_result)) expected_result = [ [b'tester1', [], []], [ b'tester2', [], [[start_ts + i, str(15).encode('ascii')] for i in range(9, 12)] ], [b'tester3', [], []], ] actual_result = r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'FILTER_BY_TS', start_ts + 9, start_ts + 10, start_ts + 11, 'FILTER_BY_VALUE', 10, 20, 'FILTER', 'generation=x') env.assertEqual(sorted(actual_result), sorted(expected_result))
def test_mrange_align(): start_ts = 1511885909 samples_count = 50 with Env(decodeResponses=True).getClusterConnectionIfNeeded() as r: assert r.execute_command('TS.CREATE', 'tester1', 'LABELS', 'name', 'bob', 'class', 'middle', 'generation', 'x') assert r.execute_command('TS.CREATE', 'tester2', 'LABELS', 'name', 'rudy', 'class', 'junior', 'generation', 'x') assert r.execute_command('TS.CREATE', 'tester3', 'LABELS', 'name', 'fabi', 'class', 'top', 'generation', 'x') _insert_data(r, 'tester1', start_ts, samples_count, 5) _insert_data(r, 'tester2', start_ts, samples_count, 15) _insert_data(r, 'tester3', start_ts, samples_count, 25) end_ts = start_ts + samples_count agg_bucket_size = 15 expected_start_result = [ [ 'tester1', [], build_expected_aligned_data(start_ts, start_ts + samples_count, agg_bucket_size, start_ts) ], [ 'tester2', [], build_expected_aligned_data(start_ts, start_ts + samples_count, agg_bucket_size, start_ts) ], [ 'tester3', [], build_expected_aligned_data(start_ts, start_ts + samples_count, agg_bucket_size, start_ts) ], ] expected_end_result = [ [ 'tester1', [], build_expected_aligned_data(start_ts, start_ts + samples_count, agg_bucket_size, end_ts) ], [ 'tester2', [], build_expected_aligned_data(start_ts, start_ts + samples_count, agg_bucket_size, end_ts) ], [ 'tester3', [], build_expected_aligned_data(start_ts, start_ts + samples_count, agg_bucket_size, end_ts) ], ] assert expected_start_result == decode_if_needed( sorted( r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'ALIGN', '-', 'AGGREGATION', 'COUNT', agg_bucket_size, 'FILTER', 'generation=x'))) assert expected_end_result == decode_if_needed( sorted( r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'ALIGN', '+', 'AGGREGATION', 'COUNT', agg_bucket_size, 'FILTER', 'generation=x'))) def groupby(data): result = defaultdict(lambda: 0) for key, labels, samples in data: for sample in samples: result[sample[0]] = max(result[sample[0]], int(sample[1])) return [[s[0], str(s[1])] for s in result.items()] expected_groupby_start_result = [[ 'generation=x', [], groupby(expected_start_result) ]] expected_groupby_end_result = [[ 'generation=x', [], groupby(expected_end_result) ]] assert expected_groupby_start_result == decode_if_needed( r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'ALIGN', '-', 'AGGREGATION', 'COUNT', agg_bucket_size, 'FILTER', 'generation=x', 'GROUPBY', 'generation', 'REDUCE', 'max')) assert expected_groupby_end_result == decode_if_needed( r.execute_command('TS.mrange', start_ts, start_ts + samples_count, 'ALIGN', '+', 'AGGREGATION', 'COUNT', agg_bucket_size, 'FILTER', 'generation=x', 'GROUPBY', 'generation', 'REDUCE', 'max'))