Commit 4cefbc2f authored by Alishan Ladhani's avatar Alishan Ladhani Committed by Dmytro Zaporozhets (DZ)

Extract snowplow tracker into separate class

To prepare for sending events to multiple destinations
parent 1a043e6f
# frozen_string_literal: true
require 'snowplow-tracker'
module Gitlab
module Tracking
SNOWPLOW_NAMESPACE = 'gl'
......@@ -27,16 +25,11 @@ module Gitlab
end
def event(category, action, label: nil, property: nil, value: nil, context: nil)
return unless enabled?
snowplow.track_struct_event(category, action, label, property, value, context, (Time.now.to_f * 1000).to_i)
snowplow.event(category, action, label: label, property: property, value: value, context: context)
end
def self_describing_event(schema_url, event_data_json, context: nil)
return unless enabled?
event_json = SnowplowTracker::SelfDescribingJson.new(schema_url, event_data_json)
snowplow.track_self_describing_event(event_json, context, (Time.now.to_f * 1000).to_i)
snowplow.self_describing_event(schema_url, event_data_json, context: context)
end
def snowplow_options(group)
......@@ -54,19 +47,7 @@ module Gitlab
private
def snowplow
@snowplow ||= SnowplowTracker::Tracker.new(
emitter,
SnowplowTracker::Subject.new,
SNOWPLOW_NAMESPACE,
Gitlab::CurrentSettings.snowplow_app_id
)
end
def emitter
SnowplowTracker::AsyncEmitter.new(
Gitlab::CurrentSettings.snowplow_collector_hostname,
protocol: 'https'
)
@snowplow ||= Gitlab::Tracking::Destinations::Snowplow.new
end
end
end
......
# frozen_string_literal: true
module Gitlab
module Tracking
module Destinations
class Base
def event(category, action, label: nil, property: nil, value: nil, context: nil)
raise NotImplementedError, "#{self} does not implement #{__method__}"
end
end
end
end
end
# frozen_string_literal: true
require 'snowplow-tracker'
module Gitlab
module Tracking
module Destinations
class Snowplow < Base
extend ::Gitlab::Utils::Override
override :event
def event(category, action, label: nil, property: nil, value: nil, context: nil)
return unless enabled?
tracker.track_struct_event(category, action, label, property, value, context, (Time.now.to_f * 1000).to_i)
end
def self_describing_event(schema_url, event_data_json, context: nil)
return unless enabled?
event_json = SnowplowTracker::SelfDescribingJson.new(schema_url, event_data_json)
tracker.track_self_describing_event(event_json, context, (Time.now.to_f * 1000).to_i)
end
private
def enabled?
Gitlab::CurrentSettings.snowplow_enabled?
end
def tracker
@tracker ||= SnowplowTracker::Tracker.new(
emitter,
SnowplowTracker::Subject.new,
Gitlab::Tracking::SNOWPLOW_NAMESPACE,
Gitlab::CurrentSettings.snowplow_app_id
)
end
def emitter
SnowplowTracker::AsyncEmitter.new(
Gitlab::CurrentSettings.snowplow_collector_hostname,
protocol: 'https'
)
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Tracking::Destinations::Snowplow do
let(:emitter) { SnowplowTracker::Emitter.new('localhost', buffer_size: 1) }
let(:tracker) { SnowplowTracker::Tracker.new(emitter, SnowplowTracker::Subject.new, 'namespace', 'app_id') }
before do
stub_application_setting(snowplow_collector_hostname: 'gitfoo.com')
stub_application_setting(snowplow_app_id: '_abc123_')
end
around do |example|
freeze_time { example.run }
end
context 'when snowplow is enabled' do
before do
stub_application_setting(snowplow_enabled: true)
expect(SnowplowTracker::AsyncEmitter)
.to receive(:new)
.with('gitfoo.com', { protocol: 'https' })
.and_return(emitter)
expect(SnowplowTracker::Tracker)
.to receive(:new)
.with(emitter, an_instance_of(SnowplowTracker::Subject), Gitlab::Tracking::SNOWPLOW_NAMESPACE, '_abc123_')
.and_return(tracker)
end
describe '#event' do
it 'sends event to tracker' do
allow(tracker).to receive(:track_struct_event).and_call_original
subject.event('category', 'action', label: 'label', property: 'property', value: 1.5)
expect(tracker)
.to have_received(:track_struct_event)
.with('category', 'action', 'label', 'property', 1.5, nil, (Time.now.to_f * 1000).to_i)
end
end
describe '#self_describing_event' do
it 'sends event to tracker' do
allow(tracker).to receive(:track_self_describing_event).and_call_original
subject.self_describing_event('iglu:com.gitlab/foo/jsonschema/1-0-0', foo: 'bar')
expect(tracker).to have_received(:track_self_describing_event) do |event, context, timestamp|
expect(event.to_json[:schema]).to eq('iglu:com.gitlab/foo/jsonschema/1-0-0')
expect(event.to_json[:data]).to eq(foo: 'bar')
expect(context).to eq(nil)
expect(timestamp).to eq((Time.now.to_f * 1000).to_i)
end
end
end
end
context 'when snowplow is not enabled' do
describe '#event' do
it 'does not send event to tracker' do
expect_any_instance_of(SnowplowTracker::Tracker).not_to receive(:track_struct_event)
subject.event('category', 'action', label: 'label', property: 'property', value: 1.5)
end
end
describe '#self_describing_event' do
it 'does not send event to tracker' do
expect_any_instance_of(SnowplowTracker::Tracker).not_to receive(:track_self_describing_event)
subject.self_describing_event('iglu:com.gitlab/foo/jsonschema/1-0-0', foo: 'bar')
end
end
end
end
......@@ -2,13 +2,13 @@
require 'spec_helper'
RSpec.describe Gitlab::Tracking do
let(:timestamp) { Time.utc(2017, 3, 22) }
before do
stub_application_setting(snowplow_enabled: true)
stub_application_setting(snowplow_collector_hostname: 'gitfoo.com')
stub_application_setting(snowplow_cookie_domain: '.gitfoo.com')
stub_application_setting(snowplow_app_id: '_abc123_')
described_class.instance_variable_set("@snowplow", nil)
end
describe '.snowplow_options' do
......@@ -35,99 +35,23 @@ RSpec.describe Gitlab::Tracking do
end
end
describe 'tracking events' do
shared_examples 'events not tracked' do
it 'does not track events' do
stub_application_setting(snowplow_enabled: false)
expect(SnowplowTracker::AsyncEmitter).not_to receive(:new)
expect(SnowplowTracker::Tracker).not_to receive(:new)
track_event
end
end
around do |example|
travel_to(timestamp) { example.run }
end
before do
described_class.instance_variable_set("@snowplow", nil)
end
let(:tracker) { double }
def receive_events
expect(SnowplowTracker::AsyncEmitter).to receive(:new).with(
'gitfoo.com', { protocol: 'https' }
).and_return('_emitter_')
expect(SnowplowTracker::Tracker).to receive(:new).with(
'_emitter_',
an_instance_of(SnowplowTracker::Subject),
'gl',
'_abc123_'
).and_return(tracker)
end
describe '.event' do
let(:track_event) do
described_class.event('category', 'action',
label: '_label_',
property: '_property_',
value: '_value_',
context: nil
)
end
it 'delegates to snowplow destination' do
expect_any_instance_of(Gitlab::Tracking::Destinations::Snowplow)
.to receive(:event)
.with('category', 'action', label: 'label', property: 'property', value: 1.5, context: nil)
it_behaves_like 'events not tracked'
it 'can track events' do
receive_events
expect(tracker).to receive(:track_struct_event).with(
'category',
'action',
'_label_',
'_property_',
'_value_',
nil,
(timestamp.to_f * 1000).to_i
)
track_event
described_class.event('category', 'action', label: 'label', property: 'property', value: 1.5)
end
end
describe '.self_describing_event' do
let(:track_event) do
described_class.self_describing_event('iglu:com.gitlab/example/jsonschema/1-0-2',
{
foo: 'bar',
foo_count: 42
},
context: nil
)
end
it_behaves_like 'events not tracked'
it 'can track self describing events' do
receive_events
expect(SnowplowTracker::SelfDescribingJson).to receive(:new).with(
'iglu:com.gitlab/example/jsonschema/1-0-2',
{
foo: 'bar',
foo_count: 42
}
).and_return('_event_json_')
it 'delegates to snowplow destination' do
expect_any_instance_of(Gitlab::Tracking::Destinations::Snowplow)
.to receive(:self_describing_event)
.with('iglu:com.gitlab/foo/jsonschema/1-0-0', { foo: 'bar' }, context: nil)
expect(tracker).to receive(:track_self_describing_event).with(
'_event_json_',
nil,
(timestamp.to_f * 1000).to_i
)
track_event
end
described_class.self_describing_event('iglu:com.gitlab/foo/jsonschema/1-0-0', foo: 'bar')
end
end
end
......@@ -7,7 +7,7 @@ RSpec.configure do |config|
# WebMock is set up to allow requests to `localhost`
host = 'localhost'
allow(Gitlab::Tracking)
allow_any_instance_of(Gitlab::Tracking::Destinations::Snowplow)
.to receive(:emitter)
.and_return(SnowplowTracker::Emitter.new(host, buffer_size: buffer_size))
......@@ -17,6 +17,6 @@ RSpec.configure do |config|
end
config.after(:each, :snowplow) do
Gitlab::Tracking.send(:snowplow).flush
Gitlab::Tracking.send(:snowplow).send(:tracker).flush
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment