-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CIVIS-7948] Test suite level visibility instrumentation for Minitest framework #92
Changes from 10 commits
5afea37
59c0ebd
f1c50f4
1b5d8e9
5c53f85
17e5dc6
addd8c7
a18f013
d7013d6
1c278b7
452b59d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,4 +20,5 @@ target :lib do | |
library "rspec" | ||
library "cucumber" | ||
library "msgpack" | ||
library "weakref" | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# frozen_string_literal: true | ||
|
||
require "weakref" | ||
|
||
require_relative "../../ext/test" | ||
require_relative "ext" | ||
|
||
module Datadog | ||
module CI | ||
module Contrib | ||
module Minitest | ||
module Plugin | ||
def self.included(base) | ||
base.extend(ClassMethods) | ||
end | ||
|
||
class DatadogReporter < ::Minitest::AbstractReporter | ||
def initialize(minitest_reporter) | ||
# This creates circular reference as minitest_reporter also holds reference to DatadogReporter. | ||
# To make sure that minitest_reporter can be garbage collected, we use WeakRef. | ||
@reporter = WeakRef.new(minitest_reporter) | ||
end | ||
|
||
def report | ||
active_test_session = CI.active_test_session | ||
active_test_module = CI.active_test_module | ||
|
||
return unless @reporter.weakref_alive? | ||
return if active_test_session.nil? || active_test_module.nil? | ||
|
||
if @reporter.passed? | ||
active_test_module.passed! | ||
active_test_session.passed! | ||
else | ||
active_test_module.failed! | ||
active_test_session.failed! | ||
end | ||
|
||
active_test_module.finish | ||
active_test_session.finish | ||
|
||
nil | ||
end | ||
end | ||
|
||
module ClassMethods | ||
def plugin_datadog_ci_init(*) | ||
return unless datadog_configuration[:enabled] | ||
|
||
test_session = CI.start_test_session( | ||
tags: { | ||
CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK, | ||
CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::Minitest::Integration.version.to_s, | ||
CI::Ext::Test::TAG_TYPE => CI::Ext::Test::TEST_TYPE | ||
}, | ||
service: datadog_configuration[:service_name] | ||
) | ||
CI.start_test_module(test_session.name) | ||
|
||
reporter.reporters << DatadogReporter.new(reporter) | ||
end | ||
|
||
private | ||
|
||
def datadog_configuration | ||
Datadog.configuration.ci[:minitest] | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
require_relative "suite" | ||
|
||
module Datadog | ||
module CI | ||
module Contrib | ||
module Minitest | ||
module Runnable | ||
def self.included(base) | ||
base.singleton_class.prepend(ClassMethods) | ||
end | ||
|
||
module ClassMethods | ||
def run(*) | ||
return super unless datadog_configuration[:enabled] | ||
return super if parallel? | ||
|
||
method = runnable_methods.first | ||
return super if method.nil? | ||
|
||
test_suite_name = Suite.name(self, method) | ||
|
||
test_suite = Datadog::CI.start_test_suite(test_suite_name) | ||
test_suite.passed! # will be overridden if any test fails | ||
|
||
results = super | ||
|
||
test_suite.finish | ||
|
||
results | ||
end | ||
|
||
private | ||
|
||
def parallel? | ||
test_order == :parallel | ||
end | ||
|
||
def datadog_configuration | ||
Datadog.configuration.ci[:minitest] | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# frozen_string_literal: true | ||
|
||
module Datadog | ||
module CI | ||
module Contrib | ||
module Minitest | ||
# Minitest integration constants | ||
# TODO: mark as `@public_api` when GA, to protect from resource and tag name changes. | ||
module Suite | ||
def self.name(klass, method_name) | ||
source_location, = klass.instance_method(method_name).source_location | ||
source_file_path = Pathname.new(source_location.to_s).relative_path_from(Pathname.pwd).to_s | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like it's implicitly assumed here that the current dir is always the same as the repo root. Not sure if the two can be different in Ruby world. If they can, things like source code integration and ITR will break in the backend There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't yet encountered cases where this wouldn't be true for Ruby as both |
||
|
||
"#{klass.name} at #{source_file_path}" | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it mean a test suite can never have 'skipped' status? Not sure what the intended behaviour is, mentioning it just in case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I haven't implemented
SKIP
for test suites in any of the instrumentations right now. Is it heavily used by other libraries (if we don't include ITR)?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Java the suite status is SKIP if it contains 0 test cases, or if every test case in it is skipped. Not sure about other languages
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you! I will add a note for the future improvements