test-rescue-agent 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test-rescue-agent'
4
+ TestRescueAgent::TestRunner.run
@@ -0,0 +1,3 @@
1
+ require 'test_rescue_agent/rspec_configuration'
2
+ require 'test_rescue_agent/cucumber_configuration'
3
+ require 'test_rescue_agent/test_runner'
@@ -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: []