def test_titled_graphite_documentation(): """Verify description of Graphite JSON response from Graphite docs for titled graph. Same as test_graphite_documentation, but graph has title. """ graphite_data = json.loads( """ [{ "target": "entries", "datapoints": [ [1.0, 1311836008], [2.0, 1311836009], [3.0, 1311836010], [5.0, 1311836011], [6.0, 1311836012] ] }] """ ) graph = {"title": "Metric Over Time", "graphite_data": graphite_data} full_long = wordgraph.describe(graph, source="graphite") expected = """ This graph, Metric Over Time, shows the relationship between time and metric. The x axis, time, ranges from 28 Jul 2011 06:53:28 to 28 Jul 2011 06:53:32. The y axis, metric, ranges from 1.0 to 6.0. It contains 1 series. The entries series is loosely linear """ assertParagraph(full_long, expected)
def test_random_graphite_metric(): "A time series of 50 data points where every value is random" rng = random.Random(0) values = [rng.random() for i in range(50)] graph = to_graphite_metric(values) full_long = wordgraph.describe(graph, source='graphite') assert full_long is not None
def test_too_few_points(): """A time series with too few data points to be analysed. Expected to raise an exception. """ with pytest.raises(ValueError): full_long = wordgraph.describe([Point(x=0, y=0)])
def test_basic_matplotlib(): """ Based on the demo at: http://matplotlib.org/examples/lines_bars_and_markers/barh_demo.html Viewed on 4 August 2014 Simple demo of a horizontal bar chart. """ import matplotlib.pyplot as plt; plt.rcdefaults() import numpy as np import matplotlib.pyplot as plt # Example data people = ('Tom', 'Dick', 'Harry', 'Slim', 'Jim') y_pos = np.arange(len(people)) performance = 3 + 10 * np.random.rand(len(people)) error = np.random.rand(len(people)) plt.barh(y_pos, performance, xerr=error, align='center', alpha=0.4) plt.yticks(y_pos, people) plt.xlabel('Performance') plt.title('How fast do you want to go today?') text = wordgraph.describe(plt, source='matplotlib') assert text is not None
def test_time_goes_backwards(): "A valid time series where time changes linearly backwards" values = [1.0] * 10 times = (EPOCH_START-i for i in range(10)) graph = {'datapoints': [Point(x=t, y=v) for (v, t) in zip(values, times)]} full_long = wordgraph.describe(graph) assert full_long is not None
def test_main_api(): """ Based on one of the integration tests... push some data through the main API methods to verify the public interfaces are basically solid """ graphite_data = json.loads(""" [{ "target": "entries", "datapoints": [ [1.0, 1311836008], [2.0, 1311836009], [3.0, 1311836010], [5.0, 1311836011], [6.0, 1311836012] ] }] """) graph = {'graphite_data': graphite_data} expected = """ This graph shows the relationship between time and metric The x axis, time, ranges from 28 Jul 2011 06:53:28 to 28 Jul 2011 06:53:32 The y axis, metric, ranges from 1.0 to 6.0 It contains 1 series The entries series is loosely linear """ full_long = wordgraph.describe(graph, source='graphite') assertParagraph(full_long, expected) english = wordgraph.Describer(source='graphite') result = english.description(graph) assertParagraph(result, expected)
def test_random_graphite_metric(): "A time series of points where the time is randomly ordered" graphite_data = json.loads(""" [{ "target": "entries", "datapoints": [ [6.0, 1311836008], [1.0, 1311836012], [3.0, 1311836010], [2.0, 1311836011], [5.0, 1311836009] ] }] """) graph = {'graphite_data': graphite_data} full_long = wordgraph.describe(graph, source='graphite') expected = ''' This graph shows the relationship between time and metric. The x axis, time, ranges from 28 Jul 2011 06:53:28 to 28 Jul 2011 06:53:32. The y axis, metric, ranges from 1.0 to 6.0. It contains 1 series. The entries series is loosely linear ''' assertParagraph(full_long, expected)
def test_tent_map(): values = list(float(i) for i in range(10)) values.append(11.0) values+= list(10.0 - i for i in range(10)) datapoints = time_values(values) features = wordgraph.describe(datapoints) assert "" in features
def test_time_goes_backwards(): """ A valid time series where time changes linearly backwards. Since it's a time series, we expect that we can sort it by time and present in order. This will not be true for arbitrary graphs. """ graphite_data = json.loads(""" [{ "target": "entries", "datapoints": [ [1.0, 1311836012], [2.0, 1311836011], [3.0, 1311836010], [5.0, 1311836009], [6.0, 1311836008] ] }] """) graph = {'graphite_data': graphite_data} full_long = wordgraph.describe(graph, source='graphite') expected = ''' This graph shows the relationship between time and metric. The x axis, time, ranges from 28 Jul 2011 06:53:28 to 28 Jul 2011 06:53:32. The y axis, metric, ranges from 1.0 to 6.0. It contains 1 series. The entries series is loosely linear ''' assertParagraph(full_long, expected)
def test_graphite_documentation(): """Verify description of Graphite JSON response from Graphite docs. The Graphite JSON response is for a single timeseries with five, monotonically increasing data points with the series name 'entries'. There is no graph title for the response. """ graphite_data = json.loads( """ [{ "target": "entries", "datapoints": [ [1.0, 1311836008], [2.0, 1311836009], [3.0, 1311836010], [5.0, 1311836011], [6.0, 1311836012] ] }] """ ) graph = {"graphite_data": graphite_data} full_long = wordgraph.describe(graph, source="graphite") expected = """ This graph shows the relationship between time and metric The x axis, time, ranges from 28 Jul 2011 06:53:28 to 28 Jul 2011 06:53:32 The y axis, metric, ranges from 1.0 to 6.0 It contains 1 series The entries series is loosely linear """ assertParagraph(full_long, expected)
def test_nonuniform_time_periods(): """A time series where time periods are wildly different. Expected to raise an exception. """ times = [1, 3, 4, 6, 7, 9, 10] graph = {'data_points': [Point(x=t, y=1.0) for t in times]} with pytest.raises(ValueError): full_long = wordgraph.describe(graph)
def test_normal(mean, stddev, offset): n_datapoints = 1000 points = set(random.gauss(mu=mean, sigma=stddev) for i in range(n_datapoints)) step_size = stddev / 10 frequency_count = defaultdict(int) for point in points: frequency_count[point % step_size] += 1 assert "???" == describe(data=frequency_count.items())
def test_step_function(): """Step function time series A 20 second time series in two distinct, 10 second ranges with one second increments. First period is a positive constant value. The second period is a different, positive constant value. """ values = [1.0] * 10 values += [2.0] * 10 graph = {'datapoints': time_values(values)} full_long = wordgraph.describe(datapoints) assert full_long is not None
def test_saw_tooth(): """A saw tooth time series A 25 second time series of 5 distinct periods. Each period exhibits the same monotonically increasing positive series. The series resets to the initial state on each section boundary. """ values = [1.0 + i for i in range(5)] values *= 5 values.append(1.0) graph = {'datapoints': time_values(values)} full_long = wordgraph.describe(datapoints) assert full_long is not None
def test_tent_map(): """Tent map time series A 20 second time series in two distinct, 10 second ranges with one second increments. First period is monotonically increasing. The second period is monotonically decreasing at the same rate. """ values = [float(i) for i in range(10)] values.append(11.0) values += [10.0 - i for i in range(10)] graph = {'datapoints': time_values(values)} full_long = wordgraph.describe(datapoints) assert full_long is not None
def test_server_requests(): """Response data from Graphite server of fictional server requests. Fictional data represents server requests for four fictional web servers. Each server's request load are approximately linear. http://play.grafana.org/graphite/render?from=-15min&until=now&target=aliasByNode(scaleToSeconds(apps.fakesite.*.counters.requests.count%2C1)%2C2)&format=json """ with open('tests/data/server_requests.json') as data: graph = {'graphite_data': json.load(data)} full_long = wordgraph.describe(graph, source='graphite') assert full_long is not None
def test_no_points(): """A time series no data points.""" graphite_data = json.loads(""" [{ "target": "entries", "datapoints": [] }] """) graph = {'graphite_data': graphite_data} full_long = wordgraph.describe(graph, source='graphite') expected = '''Graph invalid, because it contains no data points!''' assertParagraph(full_long, expected)
def test_memory_usage(): """Response data from Graphite server of fictional memory usage. Fictional data represents memory usage of a Graphite server. http://play.grafana.org/graphite/render?from=-15min&until=now&target=aliasByNode(integral(carbon.agents.ip-172-31-27-225-a.memUsage),3)&format=json """ with open("tests/data/memory_usage.json") as data: graph = {"graphite_data": json.load(data)} full_long = wordgraph.describe(graph, source="graphite") expected = """ This graph shows the relationship between time and metric The x axis, time, ranges from 04 Aug 2014 03:40:00 to 04 Aug 2014 03:54:00 The y axis, metric, ranges from 44736512.0 to 671047680.0 It contains 1 series """ assertParagraph(full_long, expected)
def test_single_point(): """A time series with a single data point.""" graphite_data = json.loads(""" [{ "target": "entries", "datapoints": [ [1.0, 1311836012] ] }] """) graph = {'graphite_data': graphite_data} full_long = wordgraph.describe(graph, source='graphite') expected = ''' This graph shows the relationship between time and metric. The entries series is a single point, with value 1.0 at time 28 Jul 2011 06:53:32. ''' assertParagraph(full_long, expected)
def test_memory_usage(): """Response data from Graphite server of fictional memory usage. Fictional data represents memory usage of a Graphite server. http://play.grafana.org/graphite/render?from=-15min&until=now&target=aliasByNode(integral(carbon.agents.ip-172-31-27-225-a.memUsage),3)&format=json """ with open('tests/data/memory_usage.json') as data: graph = {'graphite_data': json.load(data)} full_long = wordgraph.describe(graph, source='graphite') expected_sents = [ 'This graph shows the relationship between time and metric', 'The x axis, time, ranges from 1407123600 to 1407124440', 'The y axis, metric, ranges from 44736512.0 to 671047680.0', 'It contains 1 series' ] found_sents = [s.strip() for s in full_long.split('. ') if s != ''] for expected, found in zip(expected_sents, found_sents): assert expected == found, "\n%s\n%s " % (expected, found)
def test_titled_graphite_documentation(): """Verify description of Graphite JSON response from Graphite docs for titled graph. Same as test_graphite_documentation, but graph has title. """ graphite_data = json.loads(""" [{ "target": "entries", "datapoints": [ [1.0, 1311836008], [2.0, 1311836009], [3.0, 1311836010], [5.0, 1311836011], [6.0, 1311836012] ] }] """) graph = {'title': 'Metric Over Time', 'graphite_data': graphite_data} full_long = wordgraph.describe(graph, source='graphite') expected_sents = [ 'This graph, Metric Over Time, shows the relationship between time and metric', 'The x axis, time, ranges from 1311836008 to 1311836012', 'The y axis, metric, ranges from 1.0 to 6.0', 'It contains 1 series', 'The entries series is loosely linear', ] expected = ''' This graph, None, shows the relationship between time and metric. The x axis, time, ranges from 1311836008 to 1311836012. The y axis, metric, ranges from 1.0 to 6.0'. It contains 1 series'. The entriesseries is loosely linear' ''' assertParagraph(full_long, expected)
def test_two_points(): """A time series with two data points.""" graphite_data = json.loads(""" [{ "target": "entries", "datapoints": [ [1.0, 1311836012], [2.0, 1311836009] ] }] """) graph = {'graphite_data': graphite_data} full_long = wordgraph.describe(graph, source='graphite') expected = ''' This graph shows the relationship between time and metric. The x axis, time, ranges from 28 Jul 2011 06:53:29 to 28 Jul 2011 06:53:32. The y axis, metric, ranges from 1.0 to 2.0. It contains 1 series. The entries series is broadly linear ''' assertParagraph(full_long, expected)
def test_graphite_documentation(): """Verify description of Graphite JSON response from Graphite docs. The Graphite JSON response is for a single timeseries with five, monotonically increasing data points with the series name 'entries'. There is no graph title for the response. """ graphite_data = json.loads(""" [{ "target": "entries", "datapoints": [ [1.0, 1311836008], [2.0, 1311836009], [3.0, 1311836010], [5.0, 1311836011], [6.0, 1311836012] ] }] """) graph = {'graphite_data': graphite_data} full_long = wordgraph.describe(graph, source='graphite') expected_sents = [ 'This graph shows the relationship between time and metric', 'The x axis, time, ranges from 1311836008 to 1311836012', 'The y axis, metric, ranges from 1.0 to 6.0', 'It contains 1 series', 'The entries series is loosely linear', ] found_sents = [s.strip() for s in full_long.split('. ') if s != ''] for expected, found in zip(expected_sents, found_sents): assert expected == found, "\n%s\n%s " % (expected, found)
def test_linear_values(): "Postiive constant value time series in 10, one second increments" graph = {'datapoints': time_values(3.0 for i in range(10))} full_long = wordgraph.describe(datapoints) assert full_long is not None
def test_monotonic_down_per_second(): datapoints = time_values(10.0 - i for i in range(10)) features = wordgraph.describe(datapoints) assert "" in features
def test_monotonic_down_per_second(): "Monotonically descreasing positive series in 10, one second increments" graph = {'datapoints': time_values(10.0 - i for i in range(10))} full_long = wordgraph.describe(datapoints) assert full_long is not None
def graphite_POST(self, request, params): data = {"graphite_data": json.loads(params["params"]["data"])} return describe(data, source="graphite")