Rebuild the core telemetry interface.

Signed-off-by: Miah Johnson <miah@chia-pet.org>
This commit is contained in:
Miah Johnson 2019-04-03 00:44:39 -07:00
parent 18928db7be
commit 56a5c80bf5
8 changed files with 255 additions and 0 deletions

View file

@ -20,6 +20,7 @@ require 'inspec/input_registry'
require 'inspec/rspec_extensions' require 'inspec/rspec_extensions'
require 'inspec/globals' require 'inspec/globals'
require 'inspec/impact' require 'inspec/impact'
require 'inspec/utils/telemetry'
require 'inspec/plugin/v2' require 'inspec/plugin/v2'
require 'inspec/plugin/v1' require 'inspec/plugin/v1'

View file

@ -0,0 +1,3 @@
require 'inspec/utils/telemetry/collector'
require 'inspec/utils/telemetry/data_series'
require 'inspec/utils/telemetry/global_methods'

View file

@ -0,0 +1,66 @@
require 'inspec/utils/telemetry/data_series'
require 'singleton'
module Inspec::Telemetry
# A Singleton collection of data series objects.
class Collector
include Singleton
def initialize
@data_series = []
@enabled = true
end
# Add a data series to the collection.
# @return [True]
def add_data_series(data_series)
@data_series << data_series
end
# Is the Telemetry system enabled or disabled?
# Always true until we add configuration parsing.
# @return [True, False]
def telemetry_enabled?
@enabled
end
# A way to disable the telemetry system.
# @return [True]
def disable_telemetry
@enabled = false
end
# The entire data series collection.
# @return [Array]
def list_data_series
@data_series
end
# Finds the data series object with the specified name and returns it.
# If it does not exist then creates a new data series with that name
# and returns it.
# @return [Inspec::Telemetry::DataSeries]
def find_or_create_data_series(name)
ds = @data_series.select { |data_series| data_series.name.eql?(name) }
if ds.empty?
new_data_series = Inspec::Telemetry::DataSeries.new(name)
@data_series << new_data_series
new_data_series
else
ds.first
end
end
# Lists all the data series objects that match the specified name.
# @return [Array]
def list_data_series_by_name(name)
@data_series.select { |ds| ds.name.eql?(name) }
end
# Blanks the contents of the data series collection.
# @return [True]
def reset
@data_series = []
end
end
end

View file

@ -0,0 +1,45 @@
require 'json'
# A minimal Dataseries Object
# Stores the name of the data series and an array of data.
# Stored data should be a object that supports #to_s
module Inspec::Telemetry
class DataSeries
def initialize(name)
@name = name
@enabled = true
end
attr_reader :name
def data
@data ||= []
end
# This needs to also be set by configuration.
def enabled?
@enabled
end
def disable
@enabled = false
end
def <<(appending_data)
data << appending_data
end
alias push <<
def to_h
{
name: @name,
data: @data,
}
end
def to_json
to_h.to_json
end
end
end

View file

@ -0,0 +1,22 @@
require 'inspec/utils/telemetry'
module Inspec
# A Global method to add a data series object to the Telemetry Collection.
# `data_series_name`s are unique, so `:dependency_group` will always return
# the same object.
# `data_point` is optional, you may also supply a block with several data points.
# All data points should allow #to_s
# @return [True]
def self.record_telemetry_data(data_series_name, data_point = nil)
coll = Inspec::Telemetry::Collector.instance
return unless coll.telemetry_enabled?
ds = coll.find_or_create_data_series(data_series_name)
return unless ds.enabled?
if block_given?
ds << yield
else
ds << data_point
end
end
end

View file

@ -0,0 +1,46 @@
require 'inspec/utils/telemetry'
require_relative '../../../helper.rb'
class TestTelemetryCollector < Minitest::Test
def setup
@collector = Inspec::Telemetry::Collector.instance
@collector.reset
end
def test_collector_singleton
assert_equal Inspec::Telemetry::Collector.instance, @collector
end
def test_add_data_series
data_series = Inspec::Telemetry::DataSeries.new('/resource/File')
assert @collector.add_data_series(data_series)
end
def test_list_data_series
assert @collector.list_data_series
end
def test_find_or_create_data_series
dg = @collector.find_or_create_data_series(:deprecation_group)
assert_kind_of Inspec::Telemetry::DataSeries, dg
assert_equal :deprecation_group, dg.name
assert_equal @collector.find_or_create_data_series(:deprecation_group), dg
end
def test_list_data_series_names
data_series = Inspec::Telemetry::DataSeries.new('/resource/File')
data_series2 = Inspec::Telemetry::DataSeries.new('/resource/Dir')
@collector.add_data_series(data_series)
@collector.add_data_series(data_series2)
list = @collector.list_data_series_by_name('/resource/File')
assert_kind_of Array, list
assert_equal 1, list.count
end
def test_reset_singleton
data_series = Inspec::Telemetry::DataSeries.new('/resource/File')
@collector.add_data_series(data_series)
@collector.reset
assert_equal 0, @collector.list_data_series.count
end
end

View file

@ -0,0 +1,45 @@
require 'inspec/utils/telemetry'
require 'json'
require_relative '../../../helper.rb'
class TestTelemetryDataSeries < Minitest::Test
def test_name
ds = Inspec::Telemetry::DataSeries.new('fizz')
refute_nil ds
assert_equal 'fizz', ds.name
end
def test_data
ds = Inspec::Telemetry::DataSeries.new('fizz')
refute_nil ds.data
assert_kind_of Array, ds.data
assert_empty ds.data
end
def test_data_append
ds = Inspec::Telemetry::DataSeries.new('fizz')
assert_empty ds.data
assert ds << 'foo'
assert_equal ['foo'], ds.data
end
def test_data_push_alias
ds = Inspec::Telemetry::DataSeries.new('fizz')
assert_empty ds.data
assert ds.push 'bar'
assert_equal ['bar'], ds.data
end
def test_to_h
ds = Inspec::Telemetry::DataSeries.new('fizz')
ds << 'foo'
assert_kind_of Hash, ds.to_h
end
def test_to_json
ds = Inspec::Telemetry::DataSeries.new('fizz')
ds << 'foo'
assert_kind_of String, ds.to_json
assert JSON.parse(ds.to_json)
end
end

View file

@ -0,0 +1,27 @@
require 'inspec/utils/telemetry'
require_relative '../../../helper.rb'
class TestTelemetryGlobalMethods < Minitest::Test
def setup
@collector = Inspec::Telemetry::Collector.instance
@collector.reset
end
def test_record_telemetry_data
assert Inspec.record_telemetry_data(:deprecation_group, 'serverspec_compat')
depgrp = @collector.find_or_create_data_series(:deprecation_group)
assert_equal ['serverspec_compat'], depgrp.data
assert_equal :deprecation_group, depgrp.name
end
def test_record_telemetry_data_with_block
Inspec.record_telemetry_data(:deprecation_group) do
'serverspec_compat'
end
depgrp = @collector.find_or_create_data_series(:deprecation_group)
assert_equal ['serverspec_compat'], depgrp.data
assert_equal :deprecation_group, depgrp.name
end
end