test-rescue-agent 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/test-rescue +4 -0
- data/lib/test-rescue-agent.rb +3 -0
- data/lib/test_rescue_agent/cucumber_configuration.rb +40 -0
- data/lib/test_rescue_agent/rspec_configuration.rb +62 -0
- data/lib/test_rescue_agent/test_rescue_client.rb +96 -0
- data/lib/test_rescue_agent/test_rescue_client/file_run.rb +23 -0
- data/lib/test_rescue_agent/test_rescue_client/file_run_exception.rb +17 -0
- data/lib/test_rescue_agent/test_rescue_client/suite_run.rb +19 -0
- data/lib/test_rescue_agent/test_rescue_client/test_run.rb +20 -0
- data/lib/test_rescue_agent/test_runner.rb +18 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6f948ce1f72d8f7d993bc034a71551c3407dd312216f0c9b7e2037c30698a576
|
4
|
+
data.tar.gz: 5254ae06d79886f4809acf6dc3bcb33fa2365b84aa07ef98464f51f613843e30
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ace19be132cbf1a16fe65ca102494a80c4905ca90482e1352a63ad424d80b5951e9cd2f62294baaae71da618811b7cdebdc82a865f9891eb349d32ec102088d2
|
7
|
+
data.tar.gz: a636c268910ea7e1526962870d338e1c539b8bed9a573ddef98d8057050c7c8c54119a9208575e59def4dec723187d56823beec809a0fe5238d9ead9f0520781
|
data/bin/test-rescue
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
return unless ENV["SUITE_RUN_ID"] && ENV["TEST_RESCUE_TYPE"] == "cucumber"
|
2
|
+
|
3
|
+
require 'test_rescue_agent/test_rescue_client'
|
4
|
+
require 'cucumber'
|
5
|
+
|
6
|
+
client = TestRescueAgent::TestRescueClient.new(
|
7
|
+
repository_id: ENV["REPOSITORY_ID"],
|
8
|
+
endpoint: ENV["TEST_RESCUE_ENDPOINT"],
|
9
|
+
secret: ENV["TEST_RESCUE_SECRET"],
|
10
|
+
api_key: ENV["TEST_RESCUE_API_KEY"]
|
11
|
+
)
|
12
|
+
|
13
|
+
at_exit do
|
14
|
+
client.complete_file_run(ENV["SUITE_RUN_ID"], ENV["FILE_RUN_ID"])
|
15
|
+
end
|
16
|
+
|
17
|
+
start = nil
|
18
|
+
Before do
|
19
|
+
start = Time.now
|
20
|
+
end
|
21
|
+
|
22
|
+
After do |scenario|
|
23
|
+
failure_details = nil
|
24
|
+
if scenario.failed?
|
25
|
+
failure_details = [
|
26
|
+
scenario.exception.message.lines,
|
27
|
+
scenario.exception.backtrace
|
28
|
+
].flatten.join("\n")
|
29
|
+
end
|
30
|
+
duration = Time.now - start
|
31
|
+
client.create_test_run(
|
32
|
+
ENV["SUITE_RUN_ID"],
|
33
|
+
ENV["FILE_RUN_ID"],
|
34
|
+
description: scenario.name,
|
35
|
+
location: scenario.location.to_s,
|
36
|
+
result: scenario.passed?,
|
37
|
+
failure_details: failure_details,
|
38
|
+
duration: duration
|
39
|
+
)
|
40
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
return unless ENV["SUITE_RUN_ID"] && ENV["TEST_RESCUE_TYPE"] == "rspec"
|
2
|
+
|
3
|
+
require 'test_rescue_agent/test_rescue_client'
|
4
|
+
require 'rspec'
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
def test_rescue_client
|
8
|
+
test_rescue_client = TestRescueAgent::TestRescueClient.new(
|
9
|
+
repository_id: ENV["REPOSITORY_ID"],
|
10
|
+
endpoint: ENV["TEST_RESCUE_ENDPOINT"],
|
11
|
+
secret: ENV["TEST_RESCUE_SECRET"],
|
12
|
+
api_key: ENV["TEST_RESCUE_API_KEY"]
|
13
|
+
)
|
14
|
+
end
|
15
|
+
config.color = true
|
16
|
+
config.tty = true
|
17
|
+
|
18
|
+
module TestRescueRSpecReporter
|
19
|
+
def notify_non_example_exception(exception, context_description)
|
20
|
+
example = RSpec::Core::Example.new(RSpec::Core::AnonymousExampleGroup, context_description, {})
|
21
|
+
presenter = RSpec::Core::Formatters::ExceptionPresenter.new(exception, example, indentation: 0)
|
22
|
+
failure_details = [presenter.colorized_message_lines, presenter.colorized_formatted_backtrace].flatten.join("\n")
|
23
|
+
|
24
|
+
test_rescue_client.create_file_run_exception(
|
25
|
+
ENV["SUITE_RUN_ID"],
|
26
|
+
ENV["FILE_RUN_ID"],
|
27
|
+
description: example.full_description,
|
28
|
+
location: example.location,
|
29
|
+
failure_details: failure_details,
|
30
|
+
)
|
31
|
+
super(exception, context_description)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module RSpec::Core
|
36
|
+
class Reporter
|
37
|
+
prepend TestRescueRSpecReporter
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
at_exit do
|
42
|
+
test_rescue_client.complete_file_run(ENV["SUITE_RUN_ID"], ENV["FILE_RUN_ID"])
|
43
|
+
end
|
44
|
+
|
45
|
+
config.after(:each) do |example|
|
46
|
+
failure_details = nil
|
47
|
+
if example.exception
|
48
|
+
presenter = RSpec::Core::Formatters::ExceptionPresenter.new(example.exception, example)
|
49
|
+
failure_details = [presenter.colorized_message_lines, presenter.colorized_formatted_backtrace].flatten.join("\n")
|
50
|
+
end
|
51
|
+
duration = Time.now - example.execution_result.started_at
|
52
|
+
test_rescue_client.create_test_run(
|
53
|
+
ENV["SUITE_RUN_ID"],
|
54
|
+
ENV["FILE_RUN_ID"],
|
55
|
+
description: example.full_description,
|
56
|
+
location: example.location,
|
57
|
+
result: !example.exception,
|
58
|
+
failure_details: failure_details,
|
59
|
+
duration: duration
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'test_rescue_agent/test_rescue_client/suite_run'
|
2
|
+
require 'test_rescue_agent/test_rescue_client/file_run'
|
3
|
+
require 'test_rescue_agent/test_rescue_client/file_run_exception'
|
4
|
+
require 'test_rescue_agent/test_rescue_client/test_run'
|
5
|
+
require 'httparty'
|
6
|
+
begin
|
7
|
+
require 'webmock'
|
8
|
+
rescue LoadError
|
9
|
+
end
|
10
|
+
|
11
|
+
module TestRescueAgent
|
12
|
+
class TestRescueClient
|
13
|
+
def initialize(options={})
|
14
|
+
@endpoint = options[:endpoint]
|
15
|
+
@repository_id = options[:repository_id]
|
16
|
+
@api_key = options[:api_key]
|
17
|
+
@secret = options[:secret]
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_suite_run(sha:)
|
21
|
+
response = post('/suite_runs', suite_run: {
|
22
|
+
head_branch: 'master',
|
23
|
+
sha: sha,
|
24
|
+
title: 'Collect Pull Request Title from GitHub'
|
25
|
+
})
|
26
|
+
TestRescueClient::SuiteRun.new(self, JSON.parse(response.body))
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_file_run(suite_run_id, attributes)
|
30
|
+
response = post("/suite_runs/#{suite_run_id}/file_runs", file_run: attributes)
|
31
|
+
TestRescueClient::FileRun.new(self, JSON.parse(response.body))
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_file_run_exception(suite_run_id, file_run_id, attributes)
|
35
|
+
response = post("/suite_runs/#{suite_run_id}/file_runs/#{file_run_id}/exceptions", file_run_exception: attributes)
|
36
|
+
TestRescueClient::FileRunException.new(self, JSON.parse(response.body))
|
37
|
+
end
|
38
|
+
|
39
|
+
def claim_file_run(suite_run_id, container_id)
|
40
|
+
response = post("/suite_runs/#{suite_run_id}/file_runs/claim", container_id: container_id)
|
41
|
+
json = JSON.parse(response.body)
|
42
|
+
TestRescueClient::FileRun.new(self, json) if json
|
43
|
+
end
|
44
|
+
|
45
|
+
def complete_file_run(suite_run_id, file_run_id)
|
46
|
+
update_file_run(suite_run_id, file_run_id, {completed_at: Time.now.iso8601})
|
47
|
+
end
|
48
|
+
|
49
|
+
def update_file_run(suite_run_id, file_run_id, attributes)
|
50
|
+
patch("/suite_runs/#{suite_run_id}/file_runs/#{file_run_id}", file_run: attributes)
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_test_run(suite_run_id, file_run_id, attributes)
|
54
|
+
response = post("/suite_runs/#{suite_run_id}/file_runs/#{file_run_id}/test_runs", test_run: attributes)
|
55
|
+
TestRescueClient::TestRun.new(self, JSON.parse(response.body))
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def headers
|
61
|
+
{
|
62
|
+
'Content-Type' => 'application/json',
|
63
|
+
'Accept' => 'application/json',
|
64
|
+
'X-Api-Key' => @api_key,
|
65
|
+
'X-Api-Secret' => @secret
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
def handle_webmock
|
70
|
+
instance = WebMock::Config.instance
|
71
|
+
if instance.allow.nil?
|
72
|
+
instance.allow = 'www.testrescue.com'
|
73
|
+
elsif instance.allow.is_a?(Array)
|
74
|
+
instance.allow.push('www.testrescue.com') unless instance.allow.include?('www.testrescue.com')
|
75
|
+
else
|
76
|
+
WebMock::Config.instance.allow = [WebMock::Config.instance.allow, 'www.testrescue.com']
|
77
|
+
end
|
78
|
+
rescue NameError
|
79
|
+
# no problem. webmock not being resident means this code wasn't needed anyway
|
80
|
+
rescue
|
81
|
+
# TODO: report this to sentry, but still try to move on
|
82
|
+
end
|
83
|
+
|
84
|
+
def post(path, body)
|
85
|
+
handle_webmock
|
86
|
+
url = "#{@endpoint}/repositories/#{@repository_id}#{path}"
|
87
|
+
HTTParty.post(url, body: body.to_json, headers: headers)
|
88
|
+
end
|
89
|
+
|
90
|
+
def patch(path, body)
|
91
|
+
handle_webmock
|
92
|
+
url = "#{@endpoint}/repositories/#{@repository_id}#{path}"
|
93
|
+
HTTParty.patch(url, body: body.to_json, headers: headers)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module TestRescueAgent
|
2
|
+
class TestRescueClient
|
3
|
+
class FileRun
|
4
|
+
attr_reader :id, :path, :description, :suite_run_id, :test_file_id, :created_at, :updated_at, :command
|
5
|
+
|
6
|
+
def initialize(client, attributes={})
|
7
|
+
@client = client
|
8
|
+
@id = attributes["id"]
|
9
|
+
@path = attributes["path"]
|
10
|
+
@description = attributes["description"]
|
11
|
+
@suite_run_id = attributes["suite_run_id"]
|
12
|
+
@test_file_id = attributes["test_file_id"]
|
13
|
+
@created_at = attributes["created_at"]
|
14
|
+
@updated_at = attributes["updated_at"]
|
15
|
+
@command = attributes["command"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_test_run(attributes)
|
19
|
+
@client.create_test_run(suite_run_id, id, attributes)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module TestRescueAgent
|
2
|
+
class TestRescueClient
|
3
|
+
class FileRunException
|
4
|
+
attr_reader :id, :suite_run_id, :file_run_id, :description, :location, :failure_details
|
5
|
+
|
6
|
+
def initialize(client, attributes={})
|
7
|
+
@client = client
|
8
|
+
@id = attributes["id"]
|
9
|
+
@suite_run_id = attributes["suite_run_id"]
|
10
|
+
@file_run_id = attributes["file_run_id"]
|
11
|
+
@description = attributes["description"]
|
12
|
+
@location = attributes["location"]
|
13
|
+
@failure_details = attributes["failure_details"]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module TestRescueAgent
|
2
|
+
class TestRescueClient
|
3
|
+
class SuiteRun
|
4
|
+
attr_reader :id, :repository_id, :created_at, :updated_at
|
5
|
+
|
6
|
+
def initialize(client, attributes={})
|
7
|
+
@client = client
|
8
|
+
@id = attributes["id"]
|
9
|
+
@repository_id = attributes["repository_id"]
|
10
|
+
@created_at = attributes["created_at"]
|
11
|
+
@updated_at = attributes["updated_at"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_file_run(attributes)
|
15
|
+
@client.create_file_run(id, attributes)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module TestRescueAgent
|
2
|
+
class TestRescueClient
|
3
|
+
class TestRun
|
4
|
+
attr_reader :id, :file_run_id, :test_id, :description, :location, :result, :failure_details, :created_at, :updated_at
|
5
|
+
|
6
|
+
def initialize(client, attributes={})
|
7
|
+
@client = client
|
8
|
+
@id = attributes["id"]
|
9
|
+
@file_run_id = attributes["file_run_id"]
|
10
|
+
@test_id = attributes["test_id"]
|
11
|
+
@description = attributes["description"]
|
12
|
+
@location = attributes["location"]
|
13
|
+
@result = attributes["result"]
|
14
|
+
@failure_details = attributes["failure_details"]
|
15
|
+
@created_at = attributes["created_at"]
|
16
|
+
@updated_at = attributes["updated_at"]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'test_rescue_agent/test_rescue_client'
|
2
|
+
|
3
|
+
module TestRescueAgent
|
4
|
+
class TestRunner
|
5
|
+
def self.run
|
6
|
+
client = TestRescueAgent::TestRescueClient.new(
|
7
|
+
repository_id: ENV["REPOSITORY_ID"],
|
8
|
+
endpoint: ENV["TEST_RESCUE_ENDPOINT"],
|
9
|
+
secret: ENV["TEST_RESCUE_SECRET"],
|
10
|
+
api_key: ENV["TEST_RESCUE_API_KEY"]
|
11
|
+
)
|
12
|
+
while file_run = client.claim_file_run(ENV["SUITE_RUN_ID"], ENV["CONTAINER_ID"])
|
13
|
+
puts "running \"#{file_run.command}\""
|
14
|
+
`#{file_run.command}`
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: test-rescue-agent
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryan Fogle
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-04-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: httparty
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: |
|
42
|
+
Test Rescue is a massively parallelized continuous testing platform,
|
43
|
+
(http://www.testrescue.com). Test Rescue provides you with large scale
|
44
|
+
Test automation execution performance by parallelizing each individual
|
45
|
+
test in its own container automatically provisioned and run in the cloud.
|
46
|
+
Results are provided live as your tests complete.
|
47
|
+
Test Rescue provides you with deep information about the performance
|
48
|
+
of your test suite as it runs. The Test Rescue Agent is a Gem, hosted on
|
49
|
+
https://github.com/fogle/test-rescue-agent/
|
50
|
+
email: support@testrescue.com
|
51
|
+
executables:
|
52
|
+
- test-rescue
|
53
|
+
extensions: []
|
54
|
+
extra_rdoc_files: []
|
55
|
+
files:
|
56
|
+
- bin/test-rescue
|
57
|
+
- lib/test-rescue-agent.rb
|
58
|
+
- lib/test_rescue_agent/cucumber_configuration.rb
|
59
|
+
- lib/test_rescue_agent/rspec_configuration.rb
|
60
|
+
- lib/test_rescue_agent/test_rescue_client.rb
|
61
|
+
- lib/test_rescue_agent/test_rescue_client/file_run.rb
|
62
|
+
- lib/test_rescue_agent/test_rescue_client/file_run_exception.rb
|
63
|
+
- lib/test_rescue_agent/test_rescue_client/suite_run.rb
|
64
|
+
- lib/test_rescue_agent/test_rescue_client/test_run.rb
|
65
|
+
- lib/test_rescue_agent/test_runner.rb
|
66
|
+
homepage: https://github.com/fogle/test-rescue-agent
|
67
|
+
licenses:
|
68
|
+
- MIT
|
69
|
+
metadata: {}
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 2.0.0
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 1.3.1
|
84
|
+
requirements: []
|
85
|
+
rubygems_version: 3.0.3
|
86
|
+
signing_key:
|
87
|
+
specification_version: 4
|
88
|
+
summary: Test Rescue Ruby Agent
|
89
|
+
test_files: []
|