-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c564bbf
commit 723c398
Showing
8 changed files
with
352 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
# frozen_string_literal: true | ||
|
||
require "json" | ||
|
||
require_relative "../ext/transport" | ||
require_relative "../ext/test" | ||
|
||
module Datadog | ||
module CI | ||
module ITR | ||
class Skippable | ||
class Test | ||
attr_reader :name, :suite | ||
|
||
def initialize(name:, suite:) | ||
@name = name | ||
@suite = suite | ||
end | ||
|
||
def ==(other) | ||
name == other.name && suite == other.suite | ||
end | ||
end | ||
|
||
class Response | ||
def initialize(http_response) | ||
@http_response = http_response | ||
@json = nil | ||
end | ||
|
||
def ok? | ||
resp = @http_response | ||
!resp.nil? && resp.ok? | ||
end | ||
|
||
def correlation_id | ||
payload.dig("meta", "correlation_id") | ||
end | ||
|
||
def tests | ||
payload.fetch("data", []) | ||
.filter_map do |test_data| | ||
next unless test_data["type"] == Ext::Test::ITR_TEST_SKIPPING_MODE | ||
|
||
attrs = test_data["attributes"] || {} | ||
Test.new(name: attrs["name"], suite: attrs["suite"]) | ||
end | ||
end | ||
|
||
private | ||
|
||
def payload | ||
cached = @json | ||
return cached unless cached.nil? | ||
|
||
resp = @http_response | ||
return @json = {} if resp.nil? || !ok? | ||
|
||
begin | ||
@json = JSON.parse(resp.payload) | ||
rescue JSON::ParserError => e | ||
Datadog.logger.error("Failed to parse skippable tests response payload: #{e}. Payload was: #{resp.payload}") | ||
@json = {} | ||
end | ||
end | ||
end | ||
|
||
def initialize(api: nil, dd_env: nil) | ||
@api = api | ||
@dd_env = dd_env | ||
end | ||
|
||
def fetch_skippable_tests(test_session) | ||
api = @api | ||
return Response.new(nil) unless api | ||
|
||
request_payload = payload(test_session) | ||
Datadog.logger.debug("Fetching skippable tests with request: #{request_payload}") | ||
|
||
http_response = api.api_request( | ||
path: Ext::Transport::DD_API_SKIPPABLE_TESTS_PATH, | ||
payload: request_payload | ||
) | ||
|
||
Response.new(http_response) | ||
end | ||
|
||
private | ||
|
||
def payload(test_session) | ||
{ | ||
"data" => { | ||
"type" => Ext::Transport::DD_API_SKIPPABLE_TESTS_TYPE, | ||
"attributes" => { | ||
"test_level" => Ext::Test::ITR_TEST_SKIPPING_MODE, | ||
"service" => test_session.service, | ||
"env" => @dd_env, | ||
"repository_url" => test_session.git_repository_url, | ||
"sha" => test_session.git_commit_sha, | ||
"configurations" => { | ||
"os.platform" => test_session.os_platform, | ||
"os.architecture" => test_session.os_architecture, | ||
"runtime.name" => test_session.runtime_name, | ||
"runtime.version" => test_session.runtime_version | ||
} | ||
} | ||
} | ||
}.to_json | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
module Datadog | ||
module CI | ||
module ITR | ||
class Skippable | ||
@api: Datadog::CI::Transport::Api::Base? | ||
@dd_env: String? | ||
|
||
class Test | ||
@name: String? | ||
|
||
@suite: String? | ||
|
||
attr_reader name: String? | ||
|
||
attr_reader suite: String? | ||
|
||
def initialize: (name: String?, suite: String?) -> void | ||
end | ||
|
||
class Response | ||
@http_response: Datadog::Core::Transport::HTTP::Adapters::Net::Response? | ||
@json: Hash[String, untyped]? | ||
|
||
def initialize: (Datadog::Core::Transport::HTTP::Adapters::Net::Response? http_response) -> void | ||
|
||
def ok?: () -> bool | ||
|
||
def correlation_id: () -> String? | ||
|
||
def tests: () -> Array[Test] | ||
|
||
private | ||
|
||
def payload: () -> Hash[String, untyped] | ||
end | ||
|
||
def initialize: (?api: Datadog::CI::Transport::Api::Base?, ?dd_env: String?) -> void | ||
|
||
def fetch_skippable_tests: (Datadog::CI::TestSession test_session) -> Response | ||
|
||
private | ||
|
||
def payload: (Datadog::CI::TestSession test_session) -> String | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative "../../../../lib/datadog/ci/itr/skippable" | ||
|
||
RSpec.describe Datadog::CI::ITR::Skippable do | ||
let(:api) { spy("api") } | ||
let(:dd_env) { "ci" } | ||
|
||
subject(:client) { described_class.new(api: api, dd_env: dd_env) } | ||
|
||
describe "#fetch_skippable_tests" do | ||
let(:service) { "service" } | ||
let(:tracer_span) do | ||
Datadog::Tracing::SpanOperation.new("session", service: service).tap do |span| | ||
span.set_tags({ | ||
"git.repository_url" => "repository_url", | ||
"git.branch" => "branch", | ||
"git.commit.sha" => "commit_sha", | ||
"os.platform" => "platform", | ||
"os.architecture" => "arch", | ||
"runtime.name" => "runtime_name", | ||
"runtime.version" => "runtime_version" | ||
}) | ||
end | ||
end | ||
let(:test_session) { Datadog::CI::TestSession.new(tracer_span) } | ||
|
||
let(:path) { Datadog::CI::Ext::Transport::DD_API_SKIPPABLE_TESTS_PATH } | ||
|
||
it "requests the skippable tests" do | ||
client.fetch_skippable_tests(test_session) | ||
|
||
expect(api).to have_received(:api_request) do |args| | ||
expect(args[:path]).to eq(path) | ||
|
||
data = JSON.parse(args[:payload])["data"] | ||
|
||
expect(data["type"]).to eq(Datadog::CI::Ext::Transport::DD_API_SKIPPABLE_TESTS_TYPE) | ||
|
||
attributes = data["attributes"] | ||
expect(attributes["service"]).to eq(service) | ||
expect(attributes["env"]).to eq(dd_env) | ||
expect(attributes["test_level"]).to eq("test") | ||
expect(attributes["repository_url"]).to eq("repository_url") | ||
expect(attributes["sha"]).to eq("commit_sha") | ||
|
||
configurations = attributes["configurations"] | ||
expect(configurations["os.platform"]).to eq("platform") | ||
expect(configurations["os.architecture"]).to eq("arch") | ||
expect(configurations["runtime.name"]).to eq("runtime_name") | ||
expect(configurations["runtime.version"]).to eq("runtime_version") | ||
end | ||
end | ||
|
||
context "parsing response" do | ||
subject(:response) { client.fetch_skippable_tests(test_session) } | ||
|
||
context "when api is present" do | ||
before do | ||
allow(api).to receive(:api_request).and_return(http_response) | ||
end | ||
|
||
context "when response is OK" do | ||
let(:http_response) do | ||
double( | ||
"http_response", | ||
ok?: true, | ||
payload: { | ||
"meta" => { | ||
"correlation_id" => "correlation_id_123" | ||
}, | ||
"data" => [ | ||
{ | ||
"id" => "123", | ||
"type" => Datadog::CI::Ext::Test::ITR_TEST_SKIPPING_MODE, | ||
"attributes" => { | ||
"suite" => "test_suite_name", | ||
"name" => "test_name", | ||
"parameters" => "string", | ||
"configurations" => { | ||
"os.platform" => "linux", | ||
"os.version" => "bionic", | ||
"os.architecture" => "amd64", | ||
"runtime.vendor" => "string", | ||
"runtime.architecture" => "amd64" | ||
} | ||
} | ||
} | ||
] | ||
}.to_json | ||
) | ||
end | ||
|
||
it "parses the response" do | ||
expect(response.ok?).to be true | ||
expect(response.correlation_id).to eq("correlation_id_123") | ||
expect(response.tests.first).to eq( | ||
Datadog::CI::ITR::Skippable::Test.new(name: "test_name", suite: "test_suite_name") | ||
) | ||
end | ||
end | ||
|
||
context "when response is not OK" do | ||
let(:http_response) do | ||
double( | ||
"http_response", | ||
ok?: false, | ||
payload: "" | ||
) | ||
end | ||
|
||
it "parses the response" do | ||
expect(response.ok?).to be false | ||
expect(response.correlation_id).to be_nil | ||
expect(response.tests).to be_empty | ||
end | ||
end | ||
|
||
context "when response is OK but JSON is malformed" do | ||
let(:http_response) do | ||
double( | ||
"http_response", | ||
ok?: true, | ||
payload: "not json" | ||
) | ||
end | ||
|
||
before do | ||
expect(Datadog.logger).to receive(:error).with(/Failed to parse skippable tests response payload/) | ||
end | ||
|
||
it "parses the response" do | ||
expect(response.ok?).to be true | ||
expect(response.correlation_id).to be_nil | ||
expect(response.tests).to be_empty | ||
end | ||
end | ||
|
||
context "when response is OK but JSON has different format" do | ||
let(:http_response) do | ||
double( | ||
"http_response", | ||
ok?: true, | ||
payload: { | ||
"attributes" => { | ||
"suite" => "test_suite_name", | ||
"name" => "test_name", | ||
"parameters" => "string", | ||
"configurations" => { | ||
"os.platform" => "linux", | ||
"os.version" => "bionic", | ||
"os.architecture" => "amd64", | ||
"runtime.vendor" => "string", | ||
"runtime.architecture" => "amd64" | ||
} | ||
} | ||
}.to_json | ||
) | ||
end | ||
|
||
it "parses the response" do | ||
expect(response.ok?).to be true | ||
expect(response.correlation_id).to be_nil | ||
expect(response.tests).to be_empty | ||
end | ||
end | ||
end | ||
|
||
context "when there is no api" do | ||
let(:api) { nil } | ||
|
||
it "returns an empty response" do | ||
expect(response.ok?).to be false | ||
expect(response.correlation_id).to be_nil | ||
expect(response.tests).to be_empty | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters