Skip to content

Commit

Permalink
Merge c010b0c into c9c1776
Browse files Browse the repository at this point in the history
  • Loading branch information
rarruda committed Dec 16, 2021
2 parents c9c1776 + c010b0c commit ec27545
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 12 deletions.
3 changes: 3 additions & 0 deletions .rubocop.yml
Expand Up @@ -113,6 +113,9 @@ Style/SoleNestedConditional:
Enabled: true
Style/StringConcatenation:
Enabled: false
Style/TrailingCommaInHashLiteral:
Enabled: true
# EnforcedStyleForMultiline: consistent_comma

Layout/BeginEndAlignment:
Enabled: true
Expand Down
5 changes: 0 additions & 5 deletions lib/unleash.rb
Expand Up @@ -24,11 +24,6 @@ class << self
attr_accessor :configuration, :toggle_fetcher, :toggles, :toggle_metrics, :reporter, :logger
end

def self.initialize
self.toggles = []
self.toggle_metrics = {}
end

# Support for configuration via yield:
def self.configure
self.configuration ||= Unleash::Configuration.new
Expand Down
4 changes: 2 additions & 2 deletions lib/unleash/client.rb
Expand Up @@ -94,7 +94,7 @@ def get_variant(feature, context = Unleash::Context.new, fallback_variant = disa
def shutdown
unless Unleash.configuration.disable_client
Unleash.toggle_fetcher.save!
Unleash.reporter.send unless Unleash.configuration.disable_metrics
Unleash.reporter.post unless Unleash.configuration.disable_metrics
shutdown!
end
end
Expand Down Expand Up @@ -141,7 +141,7 @@ def start_metrics
Unleash.configuration.retry_limit
)
self.metrics_scheduled_executor.run do
Unleash.reporter.send
Unleash.reporter.post
end
end

Expand Down
20 changes: 17 additions & 3 deletions lib/unleash/metrics_reporter.rb
Expand Up @@ -6,6 +6,8 @@

module Unleash
class MetricsReporter
LONGEST_WITHOUT_A_REPORT = 600

attr_accessor :last_time

def initialize
Expand Down Expand Up @@ -33,16 +35,28 @@ def generate_report
report
end

def send
Unleash.logger.debug "send() Report"
def post
Unleash.logger.debug "post() Report"

if bucket_empty? && (Time.now - self.last_time < LONGEST_WITHOUT_A_REPORT) # and last time is less then 10 minutes...
Unleash.logger.debug "Report not posted to server, as it would have been empty. (and has been empty for up to 10 min)"

return
end

response = Unleash::Util::Http.post(Unleash.configuration.client_metrics_uri, self.generate_report.to_json)

if ['200', '202'].include? response.code
Unleash.logger.debug "Report sent to unleash server sucessfully. Server responded with http code #{response.code}"
Unleash.logger.debug "Report sent to unleash server successfully. Server responded with http code #{response.code}"
else
Unleash.logger.error "Error when sending report to unleash server. Server responded with http code #{response.code}."
end
end

private

def bucket_empty?
Unleash.toggle_metrics.features.empty?
end
end
end
28 changes: 26 additions & 2 deletions spec/unleash/client_spec.rb
Expand Up @@ -23,6 +23,18 @@
}
)
.to_return(status: 200, body: "", headers: {})

simple_features = {
"version": 1,
"features": [
{
"name": "Feature.A",
"description": "Enabled toggle",
"enabled": true,
"strategies": [{ "name": "default" }]
}
]
}
WebMock.stub_request(:get, "http://test-url/client/features")
.with(
headers: {
Expand All @@ -35,7 +47,7 @@
'X-Api-Key' => '123'
}
)
.to_return(status: 200, body: "", headers: {})
.to_return(status: 200, body: simple_features.to_json, headers: {})

Unleash.configure do |config|
config.url = 'http://test-url/'
Expand Down Expand Up @@ -69,7 +81,19 @@
).to have_been_made.once

# Test now sending of metrics
Unleash.reporter.send
# Not sending metrics, if no feature flags were evaluated:
Unleash.reporter.post
expect(
a_request(:post, "http://test-url/client/metrics")
.with(headers: { 'Content-Type': 'application/json' })
.with(headers: { 'X-API-KEY': '123', 'Content-Type': 'application/json' })
.with(headers: { 'UNLEASH-APPNAME': 'my-test-app' })
.with(headers: { 'UNLEASH-INSTANCEID': 'rspec/test' })
).not_to have_been_made

# Sending metrics, if they have been evaluated:
unleash_client.is_enabled?("Feature.A")
Unleash.reporter.post
expect(
a_request(:post, "http://test-url/client/metrics")
.with(headers: { 'Content-Type': 'application/json' })
Expand Down
115 changes: 115 additions & 0 deletions spec/unleash/metrics_reporter_spec.rb
@@ -0,0 +1,115 @@
require "spec_helper"
require "rspec/json_expectations"

RSpec.describe Unleash::MetricsReporter do
let(:metrics_reporter) { Unleash::MetricsReporter.new }

before do
Unleash.configuration = Unleash::Configuration.new
Unleash.logger = Unleash.configuration.logger
Unleash.logger.level = Unleash.configuration.log_level
# Unleash.logger.level = Logger::DEBUG
Unleash.toggles = []
Unleash.toggle_metrics = {}

Unleash.configuration.url = 'http://test-url/'
Unleash.configuration.app_name = 'my-test-app'
Unleash.configuration.instance_id = 'rspec/test'

# Do not test the scheduled calls from client/metrics:
Unleash.configuration.disable_client = true
Unleash.configuration.disable_metrics = true
end

it "generates the correct report" do
Unleash.configure do |config|
config.url = 'http://test-url/'
config.app_name = 'my-test-app'
config.instance_id = 'rspec/test'
config.disable_client = true
end
Unleash.toggle_metrics = Unleash::Metrics.new

Unleash.toggle_metrics.increment('featureA', :yes)
Unleash.toggle_metrics.increment('featureA', :yes)
Unleash.toggle_metrics.increment('featureA', :yes)
Unleash.toggle_metrics.increment('featureA', :no)
Unleash.toggle_metrics.increment('featureA', :no)
Unleash.toggle_metrics.increment('featureB', :yes)

report = metrics_reporter.generate_report
expect(report[:bucket][:toggles]).to include(
"featureA" => {
no: 2,
yes: 3
},
"featureB" => {
no: 0,
yes: 1
}
)

expect(report[:bucket][:toggles].to_json).to include_json(
featureA: {
no: 2,
yes: 3
},
featureB: {
no: 0,
yes: 1
}
)
end

it "sends the correct report" do
WebMock.stub_request(:post, "http://test-url/client/metrics")
.with(
headers: {
'Accept' => '*/*',
'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
'Content-Type' => 'application/json',
'Unleash-Appname' => 'my-test-app',
'Unleash-Instanceid' => 'rspec/test',
'User-Agent' => 'Ruby'
}
)
.to_return(status: 200, body: "", headers: {})

Unleash.toggle_metrics = Unleash::Metrics.new

Unleash.toggle_metrics.increment('featureA', :yes)
Unleash.toggle_metrics.increment('featureA', :yes)
Unleash.toggle_metrics.increment('featureA', :yes)
Unleash.toggle_metrics.increment('featureA', :no)
Unleash.toggle_metrics.increment('featureA', :no)
Unleash.toggle_metrics.increment('featureB', :yes)

metrics_reporter.post

expect(WebMock).to have_requested(:post, 'http://test-url/client/metrics')
.with { |req|
hash = JSON.parse(req.body)

[
DateTime.parse(hash['bucket']['stop']) >= DateTime.parse(hash['bucket']['start']),
hash['bucket']['toggles']['featureA']['yes'] == 3,
hash['bucket']['toggles']['featureA']['no'] == 2,
hash['bucket']['toggles']['featureB']['yes'] == 1
].all?(true)
}
.with(
body: hash_including(
appName: "my-test-app",
instanceId: "rspec/test"
)
)
end

it "does not send a report, if there were no metrics registered/evaluated" do
Unleash.toggle_metrics = Unleash::Metrics.new

metrics_reporter.post

expect(WebMock).to_not have_requested(:post, 'http://test-url/client/metrics')
end
end

0 comments on commit ec27545

Please sign in to comment.