Skip to content

Commit

Permalink
feat: add telemetry (#256)
Browse files Browse the repository at this point in the history
  • Loading branch information
Inksprout authored Feb 21, 2022
1 parent b8dbfab commit 4497ee9
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 2 deletions.
3 changes: 3 additions & 0 deletions lib/pact/provider/pact_spec_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
require 'pact/provider/rspec/json_formatter'
require 'pact/provider/rspec'
require 'pact/provider/rspec/calculate_exit_code'
require 'pact/utils/metrics'

module Pact
module Provider
Expand Down Expand Up @@ -130,6 +131,8 @@ def initialize_specs
ignore_failures: options[:ignore_failures],
request_customizer: options[:request_customizer]
}
Pact::Utils::Metrics.report_metric("Pacts verified", "ProviderTest", "Completed")

honour_pactfile pact_source, ordered_pact_json(pact_source.pact_json), spec_options
end
end
Expand Down
85 changes: 85 additions & 0 deletions lib/pact/utils/metrics.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
require 'securerandom'
require 'digest'
require 'socket'
require 'pact/version'
require 'net/http'

module Pact
module Utils
class Metrics

def self.report_metric(event, category, action, value = 1)
in_thread do
begin
if track_events?
Pact.configuration.output_stream.puts "WARN: Please note: we are tracking events anonymously to gather important usage statistics like Pact-Ruby version
and operating system. To disable tracking, set the 'PACT_DO_NOT_TRACK' environment
variable to 'true'."

uri = URI('https://www.google-analytics.com/collect')
req = Net::HTTP::Post.new(uri)
req.set_form_data(create_tracking_event(event, category, action, value))

Net::HTTP.start(uri.hostname, uri.port, read_timeout:2, open_timeout:2, :use_ssl => true ) do |http|
http.request(req)
end
end
rescue StandardError => e
handle_error(e)
end
end
end

private
def self.handle_error e
if ENV['PACT_METRICS_DEBUG'] == 'true'
Pact.configuration.output_stream.puts("DEBUG: #{e.inspect}\n" + e.backtrace.join("\n"))
end
end

def self.in_thread
Thread.new do
yield
end
end

def self.create_tracking_event(event, category, action, value)
{
"v" => 1,
"t" => "event",
"tid" => "UA-117778936-1",
"cid" => calculate_cid,
"an" => "Pact Ruby",
"av" => Pact::VERSION,
"aid" => "pact-ruby",
"aip" => 1,
"ds" => ENV['PACT_EXECUTING_LANGUAGE'] ? "client" : "cli",
"cd2" => ENV['CI'] == "true" ? "CI" : "unknown",
"cd3" => RUBY_PLATFORM,
"cd6" => ENV['PACT_EXECUTING_LANGUAGE'] || "unknown",
"cd7" => ENV['PACT_EXECUTING_LANGUAGE_VERSION'],
"el" => event,
"ec" => category,
"ea" => action,
"ev" => value
}
end

def self.track_events?
ENV['PACT_DO_NOT_TRACK'] != 'true'
end

def self.calculate_cid
if RUBY_PLATFORM.include? "windows"
hostname = ENV['COMPUTERNAME']
else
hostname = ENV['HOSTNAME']
end
if !hostname
hostname = Socket.gethostname
end
Digest::MD5.hexdigest hostname || SecureRandom.urlsafe_base64(5)
end
end
end
end
9 changes: 8 additions & 1 deletion spec/lib/pact/provider/pact_spec_runner_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
end
allow(subject).to receive(:configure_rspec)
allow(subject).to receive(:run_specs)
allow(Pact::Utils::Metrics).to receive(:report_metric)

expect(Pact::Provider::PactSource).to receive(:new).with(pact_url).and_return(pact_source)
end
Expand All @@ -62,6 +63,13 @@
subject.run
end

it 'reports pacts verified metric' do
allow(subject).to receive(:honour_pactfile).and_return([])

expect(Pact::Utils::Metrics).to receive(:report_metric).with("Pacts verified", "ProviderTest", "Completed")
subject.run
end

context 'and interactions_replay_order option set to random' do
let(:interactions_replay_order) { :random }

Expand All @@ -82,6 +90,5 @@
end
end
end

end
end
51 changes: 51 additions & 0 deletions spec/pact/utils/metrics_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require 'rspec'
require 'pact/utils/metrics'

describe Pact::Utils::Metrics do

before do
stub_request(:post, "https://www.google-analytics.com/collect").to_return(status: 200, body: "", headers: {})
ENV['COMPUTERNAME'] = 'test'
ENV['HOSTNAME'] = 'test'
end

describe ".report_metric" do
subject { Pact::Utils::Metrics.report_metric("Event", "Category", "Action", "Value") }
context 'when do not track is not set' do
let(:expected_event) { {
"v" => 1,
"t" => "event",
"tid" => "UA-117778936-1",
"cid" => "098f6bcd4621d373cade4e832627b4f6",
"an" => "Pact Ruby",
"av" => Pact::VERSION,
"aid" => "pact-ruby",
"aip" => 1,
"ds" => ENV['PACT_EXECUTING_LANGUAGE'] ? "client" : "cli",
"cd2" => ENV['CI'] == "true" ? "CI" : "unknown",
"cd3" => RUBY_PLATFORM,
"cd6" => ENV['PACT_EXECUTING_LANGUAGE'] || "unknown",
"cd7" => ENV['PACT_EXECUTING_LANGUAGE_VERSION'],
"el" => "Event",
"ec" => "Category",
"ea" => "Action",
"ev" => "Value"
} }

it 'sends metrics' do
expect_any_instance_of(Net::HTTP::Post).to receive(:set_form_data).with(expected_event)
expect(Net::HTTP).to receive(:start)
subject
end
end
context 'when do not track is set to true' do
before do
ENV['PACT_DO_NOT_TRACK'] = "true"
end
it 'does not send metrics' do
expect(Net::HTTP).to_not receive(:post)
subject
end
end
end
end
2 changes: 1 addition & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
require 'support/spec_support'
require 'pact/provider/rspec'

WebMock.disable_net_connect!(allow_localhost: true)
WebMock.disable_net_connect!(allow_localhost: true, allow: 'https://www.google-analytics.com')

require './spec/support/active_support_if_configured'
require './spec/support/warning_silencer'
Expand Down

0 comments on commit 4497ee9

Please sign in to comment.