def test_dashboard_create(): chart1 = TimeSeriesChart() chart1.with_name('chart1') chart1.with_program("data('requests.min').publish()") chart1.with_default_plot_type(PlotType.area_chart) chart2 = TimeSeriesChart() chart2.with_name('chart2') chart2.with_program("data('requests.min').publish()") chart2.with_default_plot_type(PlotType.line_chart) dashboard_name = 'removeme111' dashboard = Dashboard() dashboard.with_charts(chart1, chart2) dashboard.with_name(dashboard_name) f = StringIO() with stdout_redirected(f): dashboard.create(dry_run=True) response = f.getvalue() result_string = response[response.find('{'):]\ .replace('\'', '\"')\ .replace('("', '(\\"')\ .replace('")', '\\")') result = json.loads(result_string) assert 'charts' in result assert 'name' in result assert len(result['charts']) == 2 assert result['name'] == dashboard_name assert result['charts'][0]['options']['defaultPlotType'] \ == PlotType.area_chart.value assert result['charts'][1]['options']['defaultPlotType'] \ == PlotType.line_chart.value
def test_ts_chart_with_publish_label_options(): """'Legacy' behavior, verified still working.""" opts = PublishLabelOptions( 'somelabel', 0, PaletteColor.mountain_green, PlotType.area_chart, 'foo' ) chart = TimeSeriesChart().with_publish_label_options(opts) assert chart.chart_options['publishLabelOptions'] == [opts.to_dict()]
def test_ts_chart_with_axes(): axis_of_evil = AxisOption(1, 2, 'evil', 1, 2) opts = [axis_of_evil.to_dict()] chart = TimeSeriesChart().with_axes([axis_of_evil]) assert chart.chart_options['axes'] == opts
def test_ts_chart_with_publish_label_options_happy(): opts = PublishLabelOptions( 'somelabel', y_axis=1, palette_index=PaletteColor.mountain_green, plot_type=PlotType.area_chart, display_name='lol', value_prefix='hi', value_suffix='weee', value_unit='hithere') chart = TimeSeriesChart().with_publish_label_options(opts) assert chart.chart_options['publishLabelOptions'] == [opts.to_dict()]
def test_detector_from_chart_not_program(): """We should throw an error if we receive a chart that doesn't have a proper program. """ program = Data('awesome.metrics').publish(label='A') chart = TimeSeriesChart().with_program(program) with pytest.raises(ValueError): Detector().from_chart(chart, lambda x: x)
def test_detector_from_chart(): program = Program(Data('cpu.utilization').publish(label='Z')) chart = TimeSeriesChart().with_program(program) def helper(p): return Program(Detect(LT(p.find_label('Z'), 10)).publish(label='foo')) detector = Detector().from_chart(chart, helper) assert detector.options['programText'] == str(helper(program))
def test_sfx_field_options_happy(): """We also expect that string values are still valid.""" expected = {'fields': [{'property': 'foo', 'enabled': False}]} ts = TimeSeriesChart()\ .with_legend_options([FieldOption('foo', enabled=False)]) assert ts.chart_options['legendOptions'] == expected
def test_sfx_field_options_invalid(): """Other enums should not be allowed.""" class InvalidEnum(Enum): foo = 'bar' with pytest.raises(ValueError): ts = TimeSeriesChart()\ .with_legend_options([ FieldOption(InvalidEnum.foo, enabled=False) ])
def test_sfx_field_options_enum(): """We expect values from the SignalFxFieldOption enum to be serialized. """ expected = {'fields': [{'property': 'sf_originatingMetric', 'enabled': False}]} ts = TimeSeriesChart()\ .with_legend_options([ FieldOption(SignalFxFieldOption.plot_name, enabled=False) ]) assert ts.chart_options['legendOptions'] == expected
def test_ts_chart_overwrite_time_config(): """Ensure that relative/absolute options overwrite each other""" opts_a = {'type': 'absolute', 'start': 1, 'end': 2} opts_r = {'type': 'relative', 'range': 1000} chart = TimeSeriesChart().with_time_config_absolute(1, 2) assert chart.chart_options['time'] == opts_a chart.with_time_config_relative(1000) assert chart.chart_options['time'] != opts_a assert chart.chart_options['time'] == opts_r
def test_detector_from_chart_mod_prog(): """We shouldn't be able to muck about with programs from charts.""" program = Program(Data('disk.utilization').publish(label='X')) prog_size = len(program.statements) chart = TimeSeriesChart().with_program(program) def bad_helper(p): p.add_statements(Data("I shouldn't exist").publish(label='Y')) return Program(Detect(LT(p.find_label('Z'), 10)).publish(label='foo')) Detector().from_chart(chart, bad_helper) # bad_helper should not be allowed to add new program statements to # the originating chart's program. assert prog_size == len(program.statements)
def test_ts_list_charts_mixin(): """TimeSeries and ListCharts can set legend options. But not others.""" opt = {'fields': [{'property': 'foo', 'enabled': False}]} ts = TimeSeriesChart()\ .with_legend_options([FieldOption('foo', enabled=False)]) assert ts.chart_options['legendOptions'] == opt lc = ListChart()\ .with_legend_options([FieldOption('foo', enabled=False)]) assert lc.chart_options['legendOptions'] == opt with pytest.raises(Exception): SingleValueChart().with_legend_options(FieldOption('foo', enabled=False))
def test_cli_create_force_success(): program = Data('cpu.utilization').publish() chart = TimeSeriesChart().with_name('lol').with_program(program) with global_recorder.use_cassette('cli_create_force_success', serialize_with='prettyjson'): dashboard = Dashboard(session=global_session)\ .with_name('testy mctesterson')\ .with_charts(chart) cli = CliBuilder().with_resources(dashboard).build() runner = CliRunner() result = runner.invoke(cli, args=['--api-key', 'foo', 'create', '-f']) assert result.exit_code == 0
def test_cli_create_interactive_failure(sfx_recorder, session): program = Data('cpu.utilization').publish() chart = TimeSeriesChart().with_name('lol').with_program(program) with sfx_recorder.use_cassette('cli_create_interactive_failure', serialize_with='prettyjson'): dashboard = Dashboard(session=session)\ .with_name('testy mctesterson')\ .with_charts(chart) cli = CliBuilder().with_resources(dashboard).build() runner = CliRunner() result = runner.invoke(cli, args=['--api-key', 'foo', 'create', '-i'], input='n') click.echo(result.exception) assert result.exception
#!/usr/bin/env python """Examples for the `signal_analog.filters` module.""" from signal_analog.flow import Data, Filter from signal_analog.charts import TimeSeriesChart from signal_analog.dashboards import Dashboard from signal_analog.combinators import And from signal_analog.filters import DashboardFilters, FilterVariable, FilterSource, FilterTime """ Example 1: Creating a new Dashboard with Filter Variable This creates a new dashboard for the app specified and with the charts provided and with the Dashboard Filter provided """ filters = And(Filter('app', 'my-app'), Filter('env', 'test')) program = Data('cpu.utilization', filter=filters).publish() chart = TimeSeriesChart().with_name('Chart_Name').with_program(program) app_var = FilterVariable().with_alias('application name') \ .with_property('app') \ .with_is_required(True) \ .with_value('my-app') app_filter = DashboardFilters() \ .with_variables(app_var) dashboard_with_single_filter_variable = Dashboard()\ .with_name('Dashboard Name')\ .with_charts(chart)\ .with_filters(app_filter) """ Example 2: Creating a new Dashboard with multiple filters
from signal_analog.flow import Data, Filter, Program from signal_analog.combinators import And """ Example 1: single-use chart This is useful when you just want to create a chart and aren't worried about re-usability. """ # Look at the mean of the cpu.user metric for my-app in the prod environment app_filter = And(Filter('app', 'my-app'), Filter('env', 'prod')) program = Program(Data('cpu.user', filter=app_filter).mean().publish('A')) chart = TimeSeriesChart()\ .with_name('CPU Used %')\ .with_description('% CPU used by user')\ .stack_chart(True)\ .with_default_plot_type(PlotType.area_chart)\ .with_program(program) """ Example 2: make a re-usable chart (or template) This is useful when you want your chart to be broadly applicable/used by others """ class UserCpuUsedPercentChart(TimeSeriesChart): def __init__(self, app, env='prod'): super(UserCpuUsedPercentChart, self).__init__() self.with_name('CPU Used % from template class') self.with_description( '% CPU used by type (user, system, i/o, stolen, etc)')
def test_ts_chart_with_time_config_relative(): opts = {'type': 'relative', 'range': 1000} chart = TimeSeriesChart().with_time_config_relative(1000) assert chart.chart_options['time'] == opts
def test_ts_chart_with_program_opts(): opts = {'minimumResolution': 1, 'maxDelay': 2, 'disableSampling': False} chart = TimeSeriesChart().with_program_options(1, 2) assert chart.chart_options['programOptions'] == opts
def test_ts_chart_with_axis_precision(): chart = TimeSeriesChart().with_axis_precision(1) assert chart.chart_options['axisPrecision'] == 1
def test_ts_chart_stack_chart(): chart = TimeSeriesChart().stack_chart(False) assert chart.chart_options['stacked'] is False
def test_ts_chart_show_event_lines(): chart = TimeSeriesChart().show_event_lines(True) assert chart.chart_options['showEventLines'] == 'true'
def test_ts_chart_with_default_plot_type(plot_type): chart = TimeSeriesChart().with_default_plot_type(plot_type) assert chart.chart_options['defaultPlotType'] == plot_type.value
def test_ts_chart_with_color_by(color_by): chart = TimeSeriesChart().with_color_by(color_by) assert chart.chart_options['colorBy'] == color_by.value
def test_ts_chart_with_prefix(prefix): chart = TimeSeriesChart().with_unit_prefix(prefix) assert chart.chart_options['unitPrefix'] == prefix.value
def mk_chart(name): program = Data('cpu.utilization').publish() return TimeSeriesChart(session=global_session)\ .with_name(name)\ .with_program(program)
def test_ts_chart_with_publish_label_options(): opts = PublishLabelOptions('somelabel', 0, PaletteColor.mountain_green, PlotType.area_chart, 'foo') chart = TimeSeriesChart().with_publish_label_options(opts) assert chart.chart_options['publishLabelOptions'] == [opts.to_dict()]
def test_ts_chart_with_legend_options(): opts = {'showLegend': True, 'dimensionInLegend': 'foo'} chart = TimeSeriesChart()\ .with_chart_legend_options('foo', show_legend=True) assert chart.chart_options['onChartLegendOptions'] == opts
def test_ts_chart_include_zero_options(): chart = TimeSeriesChart().with_include_zero(True) assert chart.chart_options['includeZero'] is True
def test_ts_chart_init(): assert TimeSeriesChart().chart_options['type'] == 'TimeSeriesChart'
def test_ts_chart_without_enums(bad_input): with pytest.raises(ValueError): TimeSeriesChart().with_unit_prefix(bad_input) TimeSeriesChart().with_color_by(bad_input) TimeSeriesChart().with_default_plot_type(bad_input)