datatrue_client 1.0.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/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +179 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/datatrue_client.gemspec +28 -0
- data/documentation/jenkins_datatrue_test_result_summary.png +0 -0
- data/exe/datatrue_client +168 -0
- data/lib/datatrue_client.rb +6 -0
- data/lib/datatrue_client/bridge.rb +111 -0
- data/lib/datatrue_client/test_run.rb +79 -0
- data/lib/datatrue_client/version.rb +3 -0
- metadata +141 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a8a86b5463191029289d22ea6e5cde9fbcbb754e
|
4
|
+
data.tar.gz: 21d719983091ebfe5640e6ca553807782832f265
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 22532cb7a2f05c25b300e94d174076b283a535b62b13b5b2573fa50caa113fa1e687fe36e15f29096477b9f73beb212ea5fc4808f199fed99606af966ce8cf2e
|
7
|
+
data.tar.gz: 9a9fd0d9cb6d57976f024c27f3a96019ee2e0b591438adadeb77c1ba03b9029ff62bf9b182eb30279e42b36588c58f11799347d8658b4e13dddf47761783f964
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Lens10 Pty Ltd
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
# DataTrue API client
|
2
|
+
|
3
|
+
DataTrue is a SaaS platform to audit, monitor and validate tags, dataLayers and data collected from websites. The [DataTrue Test Builder chrome extension](https://chrome.google.com/webstore/detail/datatrue-test-builder/oghoceohpfhokhcoomihkobmpbcljall?hl=en) can quickly create test interactions with websites using our library of 100+ tag templates or custom tags. DataTrue works across complex AJAX interactions (e.g. using [AngularJS](https://angularjs.org/)), iframe content and multiple domains.
|
4
|
+
|
5
|
+
This ruby client allows you to trigger DataTrue tests from a Continuous Integration tool such as [Jenkins](https://jenkins.io/), [Teamcity](https://www.jetbrains.com/teamcity/), [Travis CI](https://travis-ci.org/), [Codeship](https://codeship.com/) and others. If you’re practicing Continuous Delivery, it can be used to trigger a test of your application as soon as changes are released.
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
You will need a DataTrue account ([free sign-up](https://datatrue.com/?utm_source=github&utm_medium=listing&utm_campaign=API_Client)) to use this gem. To get your API key go to the [Accounts page](https://datatrue.com/accounts/?utm_source=github&utm_medium=listing&utm_campaign=API_Client), select your account and click on "Generate API Key".
|
10
|
+
|
11
|
+
The next steps assume you have a test suite created in DataTrue. Read our [Knowledge Base](https://support.datatrue.com/hc/en-us/categories/200080049-Knowledge-Base?utm_source=github&utm_medium=listing&utm_campaign=API_Client) to find-out [how to quickly create a single-page test](https://support.datatrue.com/hc/en-us/articles/213538568-1-Use-Quick-Start-to-create-a-single-page-test?utm_source=github&utm_medium=listing&utm_campaign=API_Client).
|
12
|
+
|
13
|
+
Install the gem on the system you want to trigger your tests from:
|
14
|
+
|
15
|
+
$ gem install datatrue_client
|
16
|
+
|
17
|
+
Alternatively, if you want to include the client as part of your ruby application, you can add this line to your Gemfile:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem 'datatrue_client', :group => [:test, :development]
|
21
|
+
```
|
22
|
+
|
23
|
+
### Command-line usage
|
24
|
+
|
25
|
+
Use the [DataTrue API wizard](https://datatrue.com/?utm_source=github&utm_medium=listing&utm_campaign=API_Client) to select your test(s) or test suite along with other options. Paste the command-line in your terminal to see it in action; e.g.:
|
26
|
+
|
27
|
+
```
|
28
|
+
datatrue_client run 1539 -a rtTlaqucG9RrTg1G2L1O0u -t suite \
|
29
|
+
-v HOSTNAME=datatrue.com,GTMID=GTM-ABCXYZ \
|
30
|
+
-e 543,544
|
31
|
+
|
32
|
+
datatrue_client: job=5e9316aa116b4a6fe5dfebda68accd60 created for test="DataTrue Public pages"
|
33
|
+
datatrue_client: test_run_id=52454 step=1 total_steps=7 result=running
|
34
|
+
datatrue_client: test_run_id=52454 step=1 total_steps=7 result=passed
|
35
|
+
...
|
36
|
+
datatrue_client: test_run_id=52454 step=7 total_steps=7 result=passed
|
37
|
+
datatrue_client: test_run_id=52454 finished result=passed.
|
38
|
+
```
|
39
|
+
|
40
|
+
The exit status of the application will change according to test results:
|
41
|
+
* `0`: test run successful, result=passed.
|
42
|
+
* `1`: test run successful, result=failed.
|
43
|
+
* `-1`: generic test run error. See output detail.
|
44
|
+
* `-2`: authentication or authorisation error. Check your API key and test identifiers.
|
45
|
+
* `-3`: quota exceeded. You have used-up all your subscription allowance for this period.
|
46
|
+
|
47
|
+
If you want to ignore the exit status, use the shell's `||` operator; e.g.: `datatrue_client [options] || true`. This will ensure that the exit status is always `0`.
|
48
|
+
|
49
|
+
`datatrue_client <command> [command-arguments] -a <api_key> [command-options]`
|
50
|
+
|
51
|
+
_Commands_:
|
52
|
+
|
53
|
+
* `run`: triggers a new run of tests or a test suite and waits for it to finish.
|
54
|
+
|
55
|
+
```text
|
56
|
+
datatrue_client run <suite_id | test_id_1,test_id_2,...> -a <api_key>
|
57
|
+
[-t | --type=suite|test] [-v | --variables foo=bar,thunder=flash]
|
58
|
+
[-e | --email-users '1,2,3...'] [-o | --output [filename]] [-s | --silent]
|
59
|
+
```
|
60
|
+
|
61
|
+
* `trigger`: triggers a new run of tests or a test suite and exits immediately.
|
62
|
+
|
63
|
+
```text
|
64
|
+
datatrue_client trigger <suite_id | test_id_1,test_id_2,...> -a <api_key>
|
65
|
+
[-t | --type=suite|test] [-v | --variables foo=bar,thunder=flash]
|
66
|
+
[-s | --silent]
|
67
|
+
```
|
68
|
+
|
69
|
+
_Options_:
|
70
|
+
|
71
|
+
* `-a` or `--api-key`: The DataTrue API key. Overrides the API key provided as an environment variable.
|
72
|
+
* `-t` or `--type`: The type of test to be run. Valid options are `test` or `suite`.
|
73
|
+
* `-v` or `--variables`: Variables provided to the test. These can be used to change behaviour of your test, provide credentials and more.
|
74
|
+
* `-e` or `--email-users`: Comma-separated list of user identifiers who will receive an email with the test results.
|
75
|
+
* `-o` or `--output`: write the test results as a JUnit XML report that can be used to integrate DataTrue test results with other test tools (e.g. Jenkins). If no filename is provided the client will create a `<job_id>.xml`.
|
76
|
+
* `-s` or `--silent`: suppress all application output.
|
77
|
+
|
78
|
+
#### Environment variables
|
79
|
+
|
80
|
+
* `DATATRUE_API_KEY`: your DataTrue API key. The `-a` option takes precedence.
|
81
|
+
|
82
|
+
### Usage in a Ruby application
|
83
|
+
|
84
|
+
Trigger a test run:
|
85
|
+
|
86
|
+
```
|
87
|
+
test_run = DatatrueClient::TestRun.new({
|
88
|
+
host: 'localhost:3000',
|
89
|
+
scheme: 'http',
|
90
|
+
api_key: '_AHQZRHZ3kD0kpa0Al-SJg', # please remember to generate your own key on datatrue.com
|
91
|
+
|
92
|
+
test_run: {
|
93
|
+
test_class: 'TestScenario',
|
94
|
+
test_id: 1
|
95
|
+
},
|
96
|
+
variables: {
|
97
|
+
key: value
|
98
|
+
},
|
99
|
+
|
100
|
+
polling_interval: 2, # in seconds, 2 by default
|
101
|
+
polling_timeout: 120 # in seconds, 60 by default
|
102
|
+
})
|
103
|
+
```
|
104
|
+
|
105
|
+
Query progress:
|
106
|
+
|
107
|
+
```
|
108
|
+
test_run.query_progress
|
109
|
+
|
110
|
+
# returns the progress hash
|
111
|
+
#
|
112
|
+
# {
|
113
|
+
# time: 1463359905,
|
114
|
+
# status: "working",
|
115
|
+
# uuid: "a1f7868b1db44d38c16585ce37e4ac3f",
|
116
|
+
# num: 4,
|
117
|
+
# total: 5,
|
118
|
+
# progress: {
|
119
|
+
# percentage: 80,
|
120
|
+
# tests: [
|
121
|
+
# {
|
122
|
+
# id: 1,
|
123
|
+
# name: "Test name",
|
124
|
+
# state: "running",
|
125
|
+
# steps_completed: 4,
|
126
|
+
# steps: [
|
127
|
+
# {
|
128
|
+
# name: "Step name",
|
129
|
+
# running: false,
|
130
|
+
# pending: false,
|
131
|
+
# error: nil,
|
132
|
+
# tags: [
|
133
|
+
# { name: "Tag name', enabled: true, valid: true },
|
134
|
+
# ...
|
135
|
+
# ]
|
136
|
+
# },
|
137
|
+
# ...
|
138
|
+
# ]
|
139
|
+
# },
|
140
|
+
# ...
|
141
|
+
# ]
|
142
|
+
# }
|
143
|
+
# }
|
144
|
+
```
|
145
|
+
|
146
|
+
Poll progress (blocks until the run is finished or timed out):
|
147
|
+
|
148
|
+
`test_run.poll_progress`
|
149
|
+
|
150
|
+
### Jenkins Integration
|
151
|
+
|
152
|
+
The DataTrue client can output test results in the [JUnit format](https://github.com/windyroad/JUnit-Schema/blob/master/JUnit.xsd) which can then be parsed by the [Jenkins JUnit plugin](https://wiki.jenkins-ci.org/display/JENKINS/JUnit+Plugin) and incorporated into your test results.
|
153
|
+
|
154
|
+
Here's an example of what the results look like in Jenkins v1.6.
|
155
|
+
|
156
|
+
<img src="documentation/jenkins_datatrue_test_result_summary.png?raw=true" alt="DataTrue test result summary in Jenkins" height="400"/>
|
157
|
+
|
158
|
+
|
159
|
+
## Support
|
160
|
+
|
161
|
+
Our [support website](https://support.datatrue.com/?utm_source=github&utm_medium=listing&utm_campaign=API_Client) has more detailed information about DataTrue and the API client.
|
162
|
+
|
163
|
+
If you believe you have found a bug, please [reach-out using the support website](https://support.datatrue.com/hc/en-us/requests/new?utm_source=github&utm_medium=listing&utm_campaign=API_Client) or through support@datatrue.com.
|
164
|
+
|
165
|
+
## Contributing
|
166
|
+
|
167
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/Lens10/datatrue_client.
|
168
|
+
|
169
|
+
|
170
|
+
### Development
|
171
|
+
|
172
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
173
|
+
|
174
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
175
|
+
|
176
|
+
|
177
|
+
## License
|
178
|
+
|
179
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "datatrue_client"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'datatrue_client/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "datatrue_client"
|
8
|
+
spec.version = DatatrueClient::VERSION
|
9
|
+
spec.authors = ["Ziyu Wang"]
|
10
|
+
spec.email = ["odduid@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Ruby wrapper for DataTrue REST API.}
|
13
|
+
spec.description = %q{This ruby client allows you to trigger DataTrue tests from a Continuous Integration tool such as Jenkins, Teamcity, Travis CI, Codeship and others. If you’re practicing Continuous Delivery, it can be used to trigger a test of your application as soon as changes are released.}
|
14
|
+
spec.homepage = "https://datatrue.com"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.11"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
25
|
+
spec.add_development_dependency "webmock", "~> 2.0", ">= 2.0.1"
|
26
|
+
|
27
|
+
spec.add_dependency "rest-client", "~> 1.6"
|
28
|
+
end
|
Binary file
|
data/exe/datatrue_client
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "optparse"
|
5
|
+
require 'ostruct'
|
6
|
+
require "datatrue_client"
|
7
|
+
|
8
|
+
COMMANDS = ['run', 'trigger']
|
9
|
+
TYPES = ['test', 'suite']
|
10
|
+
|
11
|
+
def parse(args)
|
12
|
+
# The options specified on the command line will be collected in *options*.
|
13
|
+
options = OpenStruct.new
|
14
|
+
options.variables = {}
|
15
|
+
options.email_user_ids = []
|
16
|
+
options.silent = false
|
17
|
+
|
18
|
+
opt_parser = OptionParser.new do |opts|
|
19
|
+
opts.banner = "Usage: datatrue_client command(#{COMMANDS.join('|')}) id [options]"
|
20
|
+
|
21
|
+
opts.separator ""
|
22
|
+
opts.separator "The run command triggers a new run of test or test suite and waits for it to finish. The trigger command triggers a new run of test or test suite and exits immediately. Below are common options for run and trigger:"
|
23
|
+
|
24
|
+
opts.on("-a", "--api-key [KEY]",
|
25
|
+
"The DataTrue API key.",
|
26
|
+
"Overrides the API key provided as an environment variable.") do |key|
|
27
|
+
options.api_key = key
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on("-t", "--type TYPE", TYPES,
|
31
|
+
"The type of test to be run (#{TYPES.join(', ')})") do |t|
|
32
|
+
case t
|
33
|
+
when 'test'
|
34
|
+
options.type = 'TestScenario'
|
35
|
+
when 'suite'
|
36
|
+
options.type = 'Suite'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on("--host [HOST]", "API host") do |h|
|
41
|
+
options.host = h
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.on("--scheme [SCHEME]", "API host scheme") do |s|
|
45
|
+
options.scheme = s
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on("--variables [key=value,...]", Array,
|
49
|
+
"Variables provided to the test.",
|
50
|
+
"These can be used to change behaviour of your test, provide credentials and more.") do |list|
|
51
|
+
(list || []).each do |variable|
|
52
|
+
pair = variable.split('=')
|
53
|
+
options.variables[pair[0].to_sym] = pair[1]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
opts.on("--email-users [1,2,...]", Array,
|
58
|
+
"Comma-separated list of user ids who will receive an email with the test results.") do |list|
|
59
|
+
(list || []).each do |id|
|
60
|
+
options.email_user_ids << Integer(id)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
opts.on("-s", "--silent", "Suppress all application output.") do |s|
|
65
|
+
options.silent = s
|
66
|
+
end
|
67
|
+
|
68
|
+
opts.separator ""
|
69
|
+
opts.separator "Specific options for run:"
|
70
|
+
|
71
|
+
opts.on("--timeout [TIMEOUT]", "Time to wait before the run finishes.") do |t|
|
72
|
+
options.polling_timeout = t
|
73
|
+
end
|
74
|
+
|
75
|
+
opts.separator ""
|
76
|
+
opts.separator "Common options:"
|
77
|
+
|
78
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
79
|
+
puts opts
|
80
|
+
exit
|
81
|
+
end
|
82
|
+
|
83
|
+
opts.on_tail("--version", "Show version") do
|
84
|
+
puts DatatrueClient::VERSION
|
85
|
+
exit
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
opt_parser.parse!(args)
|
90
|
+
options
|
91
|
+
end
|
92
|
+
|
93
|
+
def datatrue_print(message)
|
94
|
+
puts "datatrue_client: #{message}"
|
95
|
+
end
|
96
|
+
|
97
|
+
def process_result(details)
|
98
|
+
if details[:status] == 'completed'
|
99
|
+
if details[:progress]['tests'].all? { |result| ['success', 'validated'].include? result['state'] }
|
100
|
+
status = 'passed'
|
101
|
+
else
|
102
|
+
status = 'failed'
|
103
|
+
end
|
104
|
+
else
|
105
|
+
status = details[:status]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
begin
|
110
|
+
options = parse(ARGV)
|
111
|
+
command = ARGV.shift
|
112
|
+
id = ARGV.shift
|
113
|
+
|
114
|
+
# Check mandatory inputs
|
115
|
+
if command.nil? || !COMMANDS.include?(command)
|
116
|
+
datatrue_print "missing or invalid command. Run 'datatrue_client --help' for instructions."
|
117
|
+
exit
|
118
|
+
end
|
119
|
+
if id.nil?
|
120
|
+
datatrue_print "missing id."
|
121
|
+
exit
|
122
|
+
end
|
123
|
+
if options.type.nil?
|
124
|
+
datatrue_print "missing type. Possible types #{TYPES.join(', ')}."
|
125
|
+
exit
|
126
|
+
end
|
127
|
+
|
128
|
+
datatrue_print_progress = Proc.new do |progress, details|
|
129
|
+
datatrue_print %{
|
130
|
+
test_run_id=#{details[:options]['test_run_id']}
|
131
|
+
step=#{details[:num]}
|
132
|
+
total_steps=#{details[:total]}
|
133
|
+
result=#{process_result(details)}
|
134
|
+
}.gsub(/\s+/, ' ').strip
|
135
|
+
end
|
136
|
+
|
137
|
+
test_run = DatatrueClient::TestRun.new({
|
138
|
+
host: options.host,
|
139
|
+
scheme: options.scheme,
|
140
|
+
api_key: options.api_key || ENV['DATATRUE_API_KEY'],
|
141
|
+
|
142
|
+
test_run: {
|
143
|
+
test_class: options.type,
|
144
|
+
test_id: Integer(id),
|
145
|
+
email_users: options.email_user_ids
|
146
|
+
},
|
147
|
+
variables: options.variables,
|
148
|
+
|
149
|
+
polling_timeout: options.polling_timeout ? Integer(options.polling_timeout) : nil
|
150
|
+
})
|
151
|
+
datatrue_print "job=#{test_run.job_id} created for test=\"#{test_run.title}\"" unless options.silent
|
152
|
+
|
153
|
+
if command == 'run'
|
154
|
+
res = test_run.poll_progress(options.silent ? nil : datatrue_print_progress)
|
155
|
+
process_result(res) == 'passed' ? exit : exit(1)
|
156
|
+
else
|
157
|
+
exit
|
158
|
+
end
|
159
|
+
rescue RestClient::Unauthorized => e
|
160
|
+
datatrue_print e.message
|
161
|
+
exit(-2)
|
162
|
+
rescue DatatrueClient::QuotaExceeded => e
|
163
|
+
datatrue_print e.message
|
164
|
+
exit(-3)
|
165
|
+
rescue => e
|
166
|
+
datatrue_print e.message
|
167
|
+
exit(-1)
|
168
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
require 'rest-client'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module DatatrueClient
|
6
|
+
|
7
|
+
# Abstracts HTTP details of DataTrueClient commands, all methods are synchronous
|
8
|
+
class Bridge
|
9
|
+
attr_accessor :host, :scheme
|
10
|
+
|
11
|
+
def initialize(options={})
|
12
|
+
@host = options[:host] || 'datatrue.com'
|
13
|
+
@scheme = options[:scheme] || 'https'
|
14
|
+
@api_key = options[:api_key]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Creates and queues a DataTrue test run
|
18
|
+
# @param payload [Hash]
|
19
|
+
# payload = {
|
20
|
+
# test_run: {
|
21
|
+
# test_class: 'TestScenario',
|
22
|
+
# test_id: '1',
|
23
|
+
# email_users: [1, ...]
|
24
|
+
# },
|
25
|
+
# variables: {
|
26
|
+
# name: value,
|
27
|
+
# ...
|
28
|
+
# }
|
29
|
+
# }
|
30
|
+
# @return [Hash] data about created test run, including job_id
|
31
|
+
def create_test_run(payload)
|
32
|
+
post("test_runs", payload)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Queries test run progress
|
36
|
+
# @param job_id [String] test run job id
|
37
|
+
# @return [Hash] data about progress
|
38
|
+
# {
|
39
|
+
# time: 1463359905,
|
40
|
+
# status: "working",
|
41
|
+
# uuid: "a1f7868b1db44d38c16585ce37e4ac3f",
|
42
|
+
# num: 4,
|
43
|
+
# total: 5,
|
44
|
+
# progress: {
|
45
|
+
# percentage: 80,
|
46
|
+
# tests: [
|
47
|
+
# {
|
48
|
+
# id: 1,
|
49
|
+
# name: "Test name",
|
50
|
+
# state: "running",
|
51
|
+
# steps_completed: 4,
|
52
|
+
# steps: [
|
53
|
+
# {
|
54
|
+
# name: "Step name",
|
55
|
+
# running: false,
|
56
|
+
# pending: false,
|
57
|
+
# error: nil,
|
58
|
+
# tags: [
|
59
|
+
# { name: "Tag name', enabled: true, valid: true },
|
60
|
+
# ...
|
61
|
+
# ]
|
62
|
+
# },
|
63
|
+
# ...
|
64
|
+
# ]
|
65
|
+
# },
|
66
|
+
# ...
|
67
|
+
# ]
|
68
|
+
# }
|
69
|
+
# }
|
70
|
+
def test_run_progress(job_id)
|
71
|
+
get("test_runs/progress/#{job_id}")
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def url(path)
|
77
|
+
Addressable::URI.parse("#{scheme}://#{host}/ci_api/#{path}?api_key=#{@api_key}").normalize.to_str
|
78
|
+
end
|
79
|
+
|
80
|
+
# Sends a GET request to url(path)
|
81
|
+
# @param path [String] the request path
|
82
|
+
# @return [Hash] parsed response body as a hash
|
83
|
+
def get(path)
|
84
|
+
parse_response RestClient.get(url(path), { accept: :json })
|
85
|
+
end
|
86
|
+
|
87
|
+
# Sends a POST request to url(path)
|
88
|
+
# @param path [String] the request path
|
89
|
+
# @param payload [Hash] data which will be converted to json and send in request body
|
90
|
+
# @return [Hash] parsed response body as a hash
|
91
|
+
def post(path, payload)
|
92
|
+
res = RestClient.post url(path), payload.to_json, { content_type: :json, accept: :json }
|
93
|
+
parse_response(res)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Parses json string to a hash and tries to convert keys to symbols
|
97
|
+
# @param res [String] RestClient response / json string
|
98
|
+
# @return [Hash] parsed hash
|
99
|
+
def parse_response(res)
|
100
|
+
hash = JSON.parse(res)
|
101
|
+
|
102
|
+
# convert keys to symbols
|
103
|
+
hash.keys.each do |key|
|
104
|
+
hash[(key.to_sym rescue key) || key] = hash.delete(key)
|
105
|
+
end
|
106
|
+
|
107
|
+
hash
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "datatrue_client/bridge"
|
2
|
+
|
3
|
+
module DatatrueClient
|
4
|
+
class TimeoutError < StandardError; end
|
5
|
+
class QuotaExceeded < StandardError; end
|
6
|
+
|
7
|
+
class TestRun
|
8
|
+
attr_reader :job_id, :title, :progress
|
9
|
+
attr_accessor :polling_timeout, :polling_interval
|
10
|
+
|
11
|
+
# @param options [Hash]
|
12
|
+
# options = {
|
13
|
+
# polling_interval: 0.1,
|
14
|
+
# polling_timeout: 1
|
15
|
+
# }
|
16
|
+
# options will also be passed to `Bridge.new` and `Bridge#create_test_run`,
|
17
|
+
# see `Bridge` for other possible option keys
|
18
|
+
def initialize(options={})
|
19
|
+
@options = options
|
20
|
+
@bridge = Bridge.new(options)
|
21
|
+
|
22
|
+
@polling_timeout = options[:polling_timeout] || 60
|
23
|
+
@polling_interval = options[:polling_interval] || 2
|
24
|
+
|
25
|
+
create
|
26
|
+
end
|
27
|
+
|
28
|
+
# Queries test run progress
|
29
|
+
# @return [Hash] data about progress
|
30
|
+
def query_progress
|
31
|
+
@bridge.test_run_progress(job_id)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Keeps querying progress until progress status is `complete`
|
35
|
+
# @param print_progress [Proc] called with current progress percentage and details
|
36
|
+
def poll_progress(print_progress=nil)
|
37
|
+
start_time = DateTime.now
|
38
|
+
|
39
|
+
loop do
|
40
|
+
res = query_progress
|
41
|
+
@progress = progress_percentage(res)
|
42
|
+
print_progress.call(@progress, res) if print_progress
|
43
|
+
|
44
|
+
return res if res[:status] == 'completed'
|
45
|
+
|
46
|
+
if elapsed_milliseconds(start_time, DateTime.now) >= @polling_timeout * 1000
|
47
|
+
raise TimeoutError.new("Polling progress timed out after #{@polling_timeout} seconds")
|
48
|
+
|
49
|
+
break
|
50
|
+
else
|
51
|
+
sleep @polling_interval
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def create
|
59
|
+
res = @bridge.create_test_run(@options)
|
60
|
+
@job_id = res[:job_id]
|
61
|
+
@title = res[:title]
|
62
|
+
end
|
63
|
+
|
64
|
+
def progress_percentage(progress_res)
|
65
|
+
if progress_res[:status] == 'queued'
|
66
|
+
0
|
67
|
+
elsif progress_res[:status] == 'completed'
|
68
|
+
raise QuotaExceeded.new(progress_res[:error]) if progress_res[:error]
|
69
|
+
100
|
70
|
+
else
|
71
|
+
progress_res[:progress].nil? ? 0 : progress_res[:progress][:percentage]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def elapsed_milliseconds(start_time, end_time)
|
76
|
+
((end_time - start_time) * 24 * 60 * 60 * 1000).to_i
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
metadata
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: datatrue_client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ziyu Wang
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-06-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.11'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.11'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: webmock
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 2.0.1
|
65
|
+
type: :development
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - "~>"
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '2.0'
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 2.0.1
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rest-client
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '1.6'
|
82
|
+
type: :runtime
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '1.6'
|
89
|
+
description: This ruby client allows you to trigger DataTrue tests from a Continuous
|
90
|
+
Integration tool such as Jenkins, Teamcity, Travis CI, Codeship and others. If you’re
|
91
|
+
practicing Continuous Delivery, it can be used to trigger a test of your application
|
92
|
+
as soon as changes are released.
|
93
|
+
email:
|
94
|
+
- odduid@gmail.com
|
95
|
+
executables:
|
96
|
+
- datatrue_client
|
97
|
+
extensions: []
|
98
|
+
extra_rdoc_files: []
|
99
|
+
files:
|
100
|
+
- ".gitignore"
|
101
|
+
- ".rspec"
|
102
|
+
- ".travis.yml"
|
103
|
+
- Gemfile
|
104
|
+
- LICENSE.txt
|
105
|
+
- README.md
|
106
|
+
- Rakefile
|
107
|
+
- bin/console
|
108
|
+
- bin/setup
|
109
|
+
- datatrue_client.gemspec
|
110
|
+
- documentation/jenkins_datatrue_test_result_summary.png
|
111
|
+
- exe/datatrue_client
|
112
|
+
- lib/datatrue_client.rb
|
113
|
+
- lib/datatrue_client/bridge.rb
|
114
|
+
- lib/datatrue_client/test_run.rb
|
115
|
+
- lib/datatrue_client/version.rb
|
116
|
+
homepage: https://datatrue.com
|
117
|
+
licenses:
|
118
|
+
- MIT
|
119
|
+
metadata: {}
|
120
|
+
post_install_message:
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
requirements: []
|
135
|
+
rubyforge_project:
|
136
|
+
rubygems_version: 2.4.8
|
137
|
+
signing_key:
|
138
|
+
specification_version: 4
|
139
|
+
summary: Ruby wrapper for DataTrue REST API.
|
140
|
+
test_files: []
|
141
|
+
has_rdoc:
|