rrrspec-web 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/assets/javascripts/helpers.coffee +27 -0
- data/assets/javascripts/index.coffee +75 -0
- data/{app/js → assets/javascripts}/models.coffee +41 -69
- data/assets/javascripts/tasksets.coffee +400 -0
- data/{app/js → assets/javascripts}/vendor/backbone-min.js +0 -0
- data/{app/js → assets/javascripts}/vendor/backbone-min.map +0 -0
- data/{app/js → assets/javascripts}/vendor/backbone.js +0 -0
- data/assets/javascripts/vendor/handlebars-v1.3.0.js +2746 -0
- data/{app/js → assets/javascripts}/vendor/jquery-1.10.2.js +0 -0
- data/{app/js → assets/javascripts}/vendor/jquery-1.10.2.min.js +0 -0
- data/{app/js → assets/javascripts}/vendor/jquery-1.10.2.min.map +0 -0
- data/{app/js → assets/javascripts}/vendor/moment.min.js +0 -0
- data/{app/js → assets/javascripts}/vendor/underscore-min.js +0 -0
- data/{app/js → assets/javascripts}/vendor/underscore-min.map +0 -0
- data/{app/js → assets/javascripts}/vendor/underscore.js +0 -0
- data/assets/stylesheets/application.sass +188 -0
- data/lib/rrrspec/web/api.rb +61 -0
- data/lib/rrrspec/web/app.rb +9 -30
- data/lib/rrrspec/web/configuration.rb +1 -0
- data/lib/rrrspec/web/persistent_models.rb +7 -2
- data/lib/rrrspec/web/version.rb +1 -1
- data/rrrspec-web.gemspec +9 -7
- data/spec/rrrspec/web/api_spec.rb +278 -47
- data/tasks/assets.rake +3 -6
- data/views/index.haml +4 -14
- data/views/taskset.haml +61 -68
- data/views/user.haml +2 -2
- metadata +108 -84
- data/app/css/application.sass +0 -124
- data/app/css/vendor/bootstrap-theme.css +0 -384
- data/app/css/vendor/bootstrap-theme.min.css +0 -1
- data/app/css/vendor/bootstrap.css +0 -6805
- data/app/css/vendor/bootstrap.min.css +0 -9
- data/app/js/index.coffee +0 -51
- data/app/js/tasksets.coffee +0 -305
- data/app/js/vendor/bootstrap.js +0 -1999
- data/app/js/vendor/bootstrap.min.js +0 -6
- data/app/js/vendor/mustache.js +0 -551
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,188 @@
|
|
1
|
+
@import "bootstrap"
|
2
|
+
|
3
|
+
body
|
4
|
+
padding-top: 20px
|
5
|
+
|
6
|
+
dl
|
7
|
+
@extend .dl-horizontal
|
8
|
+
|
9
|
+
.log
|
10
|
+
@extend .pre-scrollable
|
11
|
+
word-wrap: normal
|
12
|
+
white-space: pre
|
13
|
+
overflow-x: scroll
|
14
|
+
|
15
|
+
.tasksets
|
16
|
+
ul
|
17
|
+
list-style-type: none
|
18
|
+
padding-left: 0
|
19
|
+
|
20
|
+
li
|
21
|
+
display: inline-block
|
22
|
+
|
23
|
+
.taskset-status
|
24
|
+
width: 7em
|
25
|
+
text-transform: uppercase
|
26
|
+
.username
|
27
|
+
width: 8em
|
28
|
+
padding-right: 2em
|
29
|
+
|
30
|
+
.taskset
|
31
|
+
@extend .container
|
32
|
+
|
33
|
+
.head, .tasks, .worker-logs, .slaves
|
34
|
+
@extend .panel
|
35
|
+
@extend .panel-default
|
36
|
+
|
37
|
+
> .panel-heading
|
38
|
+
cursor: pointer
|
39
|
+
font-size: large
|
40
|
+
&:hover
|
41
|
+
color: darken(#428bca, 15%)
|
42
|
+
border-color: #428bca
|
43
|
+
|
44
|
+
.tasks-list, .worker-logs-list, .slaves-list
|
45
|
+
> *
|
46
|
+
padding: 0
|
47
|
+
|
48
|
+
.list-group-item > *
|
49
|
+
padding: 10px 15px
|
50
|
+
|
51
|
+
.head
|
52
|
+
.panel-heading
|
53
|
+
.name
|
54
|
+
font-size: x-large
|
55
|
+
overflow: hidden
|
56
|
+
text-overflow: ellipsis
|
57
|
+
white-space: nowrap
|
58
|
+
float: left
|
59
|
+
width: 80%
|
60
|
+
|
61
|
+
.status
|
62
|
+
font-size: large
|
63
|
+
width: 20%
|
64
|
+
text-transform: uppercase
|
65
|
+
float: left
|
66
|
+
|
67
|
+
.running
|
68
|
+
@extend .label-primary
|
69
|
+
.succeeded
|
70
|
+
@extend .label-success
|
71
|
+
.cancelled
|
72
|
+
@extend .label-warning
|
73
|
+
.failed
|
74
|
+
@extend .label-danger
|
75
|
+
|
76
|
+
.progressbars
|
77
|
+
.spec-progress
|
78
|
+
@extend .progress
|
79
|
+
.spec-progress-bar
|
80
|
+
@extend .progress-bar
|
81
|
+
.passed-spec-bar
|
82
|
+
@extend .progress-bar
|
83
|
+
@extend .progress-bar-success
|
84
|
+
.pending-spec-bar
|
85
|
+
@extend .progress-bar
|
86
|
+
@extend .progress-bar-warning
|
87
|
+
.failed-spec-bar
|
88
|
+
@extend .progress-bar
|
89
|
+
@extend .progress-bar-danger
|
90
|
+
.example-progress
|
91
|
+
@extend .progress
|
92
|
+
.passed-example-bar
|
93
|
+
@extend .progress-bar
|
94
|
+
@extend .progress-bar-success
|
95
|
+
.pending-example-bar
|
96
|
+
@extend .progress-bar
|
97
|
+
@extend .progress-bar-warning
|
98
|
+
.failed-example-bar
|
99
|
+
@extend .progress-bar
|
100
|
+
@extend .progress-bar-danger
|
101
|
+
|
102
|
+
.tasks
|
103
|
+
.tasks-heading
|
104
|
+
@extend .panel-heading
|
105
|
+
|
106
|
+
.tasks-list
|
107
|
+
@extend .list-group
|
108
|
+
|
109
|
+
.tasks-list-header, .tasks-list-item-header
|
110
|
+
list-style-type: none
|
111
|
+
|
112
|
+
li
|
113
|
+
display: inline-block
|
114
|
+
|
115
|
+
.taskstatus, .trial-count, .estimate-sec
|
116
|
+
width: 6em
|
117
|
+
text-align: center
|
118
|
+
|
119
|
+
.trial-count, .estimate-sec
|
120
|
+
@extend .pull-right
|
121
|
+
|
122
|
+
.file
|
123
|
+
text-align: left
|
124
|
+
text-overflow: ellipsis
|
125
|
+
|
126
|
+
.tasks-list-item-header
|
127
|
+
cursor: pointer
|
128
|
+
|
129
|
+
.running .tasks-list-item-header
|
130
|
+
background-color: #f5f5f5
|
131
|
+
&:hover
|
132
|
+
background-color: darken(#f5f5f5, 20%)
|
133
|
+
.passed .tasks-list-item-header
|
134
|
+
background-color: #dff0d8
|
135
|
+
&:hover
|
136
|
+
background-color: darken(#dff0d8, 20%)
|
137
|
+
.pending .tasks-list-item-header
|
138
|
+
background-color: #fcf8e3
|
139
|
+
&:hover
|
140
|
+
background-color: darken(#fcf8e3, 20%)
|
141
|
+
.failed .tasks-list-item-header
|
142
|
+
background-color: #f2dede
|
143
|
+
&:hover
|
144
|
+
background-color: darken(#f2dede, 20%)
|
145
|
+
|
146
|
+
.tasks-list-item-header
|
147
|
+
.taskstatus
|
148
|
+
text-transform: uppercase
|
149
|
+
|
150
|
+
.trials-list-heading
|
151
|
+
@extend .panel-heading
|
152
|
+
|
153
|
+
.worker-logs
|
154
|
+
.worker-logs-heading
|
155
|
+
@extend .panel-heading
|
156
|
+
|
157
|
+
.worker-logs-list
|
158
|
+
@extend .list-group
|
159
|
+
|
160
|
+
.worker-logs-list-item-header
|
161
|
+
cursor: pointer
|
162
|
+
&:hover
|
163
|
+
color: darken(#428bca, 15%)
|
164
|
+
text-decoration: underline
|
165
|
+
|
166
|
+
.slaves
|
167
|
+
.slaves-heading
|
168
|
+
@extend .panel-heading
|
169
|
+
|
170
|
+
.slaves-list
|
171
|
+
@extend .list-group
|
172
|
+
|
173
|
+
.slaves-list-item-header
|
174
|
+
cursor: pointer
|
175
|
+
&:hover
|
176
|
+
color: darken(#428bca, 15%)
|
177
|
+
text-decoration: underline
|
178
|
+
|
179
|
+
.exit-status
|
180
|
+
@extend .pull-right
|
181
|
+
text-transform: uppercase
|
182
|
+
|
183
|
+
.normal_exit .slaves-list-item-header
|
184
|
+
background-color: #dff0d8
|
185
|
+
.timeout_exit .slaves-list-item-header
|
186
|
+
background-color: #fcf8e3
|
187
|
+
.failure_exit .slaves-list-item-header
|
188
|
+
background-color: #f2dede
|
data/lib/rrrspec/web/api.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'grape'
|
2
2
|
require 'api-pagination'
|
3
|
+
require 'oj'
|
3
4
|
|
4
5
|
module RRRSpec
|
5
6
|
module Web
|
@@ -51,5 +52,65 @@ module RRRSpec
|
|
51
52
|
end
|
52
53
|
end
|
53
54
|
end
|
55
|
+
|
56
|
+
module OjFormatter
|
57
|
+
def self.call(object, env)
|
58
|
+
Oj.dump(object, mode: :compat, time_format: :ruby)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class APIv2 < Grape::API
|
63
|
+
version 'v2', using: :path
|
64
|
+
format :json
|
65
|
+
formatter :json, OjFormatter
|
66
|
+
|
67
|
+
rescue_from(ActiveRecord::RecordNotFound) do
|
68
|
+
[404, {}, ['']]
|
69
|
+
end
|
70
|
+
|
71
|
+
# For Index
|
72
|
+
|
73
|
+
get '/tasksets/actives' do
|
74
|
+
ActiveTaskset.list
|
75
|
+
end
|
76
|
+
|
77
|
+
get '/tasksets/recents' do
|
78
|
+
paginate(RRRSpec::Server::Persistence::Taskset.recent).map(&:as_json_for_index)
|
79
|
+
end
|
80
|
+
|
81
|
+
# For Result Page
|
82
|
+
|
83
|
+
# Notice that this method takes taskset key.
|
84
|
+
params { requires :taskset_key, type: String }
|
85
|
+
get '/tasksets/:taskset_key' do
|
86
|
+
RRRSpec::Server::Persistence::Taskset.includes(tasks: :trials).where(key: params[:taskset_key]).first!.as_json_for_result_page
|
87
|
+
end
|
88
|
+
|
89
|
+
params { requires :taskset_id, type: Integer }
|
90
|
+
get '/tasksets/:taskset_id/log' do
|
91
|
+
{ 'log' => RRRSpec::Server::Persistence::Taskset.find(params[:taskset_id]).log.to_s }
|
92
|
+
end
|
93
|
+
|
94
|
+
params { requires :task_id, type: Integer }
|
95
|
+
get '/tasks/:task_id/trials' do
|
96
|
+
RRRSpec::Server::Persistence::Task.find(params[:task_id]).trials.map(&:as_json_for_result_page)
|
97
|
+
end
|
98
|
+
|
99
|
+
params { requires :trial_id, type: Integer }
|
100
|
+
get '/trials/:trial_id/outputs' do
|
101
|
+
trial = RRRSpec::Server::Persistence::Trial.find(params[:trial_id])
|
102
|
+
{ 'stdout' => trial.stdout.to_s, 'stderr' => trial.stderr.to_s }
|
103
|
+
end
|
104
|
+
|
105
|
+
params { requires :taskset_id, type: Integer }
|
106
|
+
get '/tasksets/:taskset_id/worker_logs' do
|
107
|
+
RRRSpec::Server::Persistence::Taskset.find(params[:taskset_id]).worker_logs.map(&:as_json_for_result_page)
|
108
|
+
end
|
109
|
+
|
110
|
+
params { requires :taskset_id, type: Integer }
|
111
|
+
get '/tasksets/:taskset_id/slaves' do
|
112
|
+
RRRSpec::Server::Persistence::Taskset.includes(slaves: :trials).find(params[:taskset_id]).slaves.map(&:as_json_for_result_page)
|
113
|
+
end
|
114
|
+
end
|
54
115
|
end
|
55
116
|
end
|
data/lib/rrrspec/web/app.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'sinatra/base'
|
2
|
-
require 'sinatra/
|
2
|
+
require 'sinatra/asset_pipeline'
|
3
3
|
require 'haml'
|
4
4
|
require 'sass'
|
5
5
|
require 'coffee-script'
|
@@ -7,40 +7,19 @@ require 'coffee-script'
|
|
7
7
|
module RRRSpec
|
8
8
|
module Web
|
9
9
|
class App < Sinatra::Base
|
10
|
+
set :assets_precompile, %w(application.css tasksets.js index.js)
|
11
|
+
set :assets_prefix, [
|
12
|
+
"#{Gem::Specification.find_by_name('bootstrap-sass').gem_dir}/vendor/assets",
|
13
|
+
File.expand_path('../../../../assets', __FILE__),
|
14
|
+
]
|
15
|
+
|
16
|
+
register Sinatra::AssetPipeline
|
17
|
+
|
10
18
|
configure do
|
11
19
|
set :root, File.expand_path(File.join(__FILE__, '..', '..', '..', '..'))
|
12
20
|
set :haml, :format => :html5
|
13
21
|
end
|
14
22
|
|
15
|
-
register Sinatra::AssetPack
|
16
|
-
|
17
|
-
assets do
|
18
|
-
JSLIBS = [
|
19
|
-
'/js/vendor/jquery-1.10.2.min.js',
|
20
|
-
'/js/vendor/underscore-min.js',
|
21
|
-
'/js/vendor/backbone-min.js',
|
22
|
-
'/js/vendor/mustache.js',
|
23
|
-
'/js/vendor/bootstrap.min.js',
|
24
|
-
'/js/vendor/moment.min.js',
|
25
|
-
'/js/models.js',
|
26
|
-
]
|
27
|
-
|
28
|
-
CSSLIBS = [
|
29
|
-
'/css/vendor/bootstrap.min.css',
|
30
|
-
'/css/vendor/bootstrap-theme.min.css',
|
31
|
-
]
|
32
|
-
|
33
|
-
js :tasksets, JSLIBS + ["/js/tasksets.js"]
|
34
|
-
js :index, JSLIBS + ["/js/index.js"]
|
35
|
-
css :application, CSSLIBS + ["/css/application.css"]
|
36
|
-
|
37
|
-
js_compression :jsmin
|
38
|
-
css_compression :simple
|
39
|
-
|
40
|
-
prebuild true
|
41
|
-
cache_dynamic_assets true
|
42
|
-
end
|
43
|
-
|
44
23
|
get('/') { haml :index }
|
45
24
|
get('/tasksets/*') { haml :taskset }
|
46
25
|
end
|
@@ -4,8 +4,13 @@ module RRRSpec
|
|
4
4
|
module Server
|
5
5
|
module Persistence
|
6
6
|
class Taskset
|
7
|
-
|
8
|
-
|
7
|
+
def self.recent
|
8
|
+
order('finished_at DESC')
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.has_failed_slaves
|
12
|
+
includes(:slaves).where(slaves: {status: 'failure_exit'})
|
13
|
+
end
|
9
14
|
|
10
15
|
def as_json_with_no_relation
|
11
16
|
as_json(except: :id)
|
data/lib/rrrspec/web/version.rb
CHANGED
data/rrrspec-web.gemspec
CHANGED
@@ -24,24 +24,26 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.require_paths = ["lib"]
|
25
25
|
|
26
26
|
spec.add_development_dependency "bundler", "~> 1.4"
|
27
|
-
spec.add_development_dependency "rake"
|
28
|
-
spec.add_development_dependency "rspec"
|
29
|
-
spec.add_development_dependency "rack-test"
|
30
27
|
spec.add_development_dependency "database_cleaner", "~> 1.2.0"
|
31
|
-
spec.add_development_dependency "sqlite3"
|
32
|
-
spec.add_development_dependency "mysql2"
|
33
28
|
spec.add_development_dependency "guard-livereload"
|
29
|
+
spec.add_development_dependency "mysql2"
|
34
30
|
spec.add_development_dependency "rack-livereload"
|
35
|
-
spec.
|
31
|
+
spec.add_development_dependency "rack-test"
|
32
|
+
spec.add_development_dependency "rake"
|
33
|
+
spec.add_development_dependency "rspec"
|
34
|
+
spec.add_development_dependency "sqlite3"
|
35
|
+
spec.add_dependency "activerecord", "~> 4.0.2"
|
36
36
|
spec.add_dependency "activesupport"
|
37
37
|
spec.add_dependency "api-pagination"
|
38
|
+
spec.add_dependency "bootstrap-sass"
|
38
39
|
spec.add_dependency "coffee-script", "~> 2.2.0"
|
39
40
|
spec.add_dependency "grape"
|
40
41
|
spec.add_dependency "haml", "~> 4.0.3"
|
41
42
|
spec.add_dependency "kaminari", "~> 0.15.0"
|
43
|
+
spec.add_dependency "oj"
|
42
44
|
spec.add_dependency "rrrspec-client"
|
43
45
|
spec.add_dependency "rrrspec-server"
|
44
46
|
spec.add_dependency "sass"
|
45
47
|
spec.add_dependency "sinatra", "~> 1.4.3"
|
46
|
-
spec.add_dependency "sinatra-
|
48
|
+
spec.add_dependency "sinatra-asset-pipeline"
|
47
49
|
end
|
@@ -1,16 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
module RRRSpec
|
4
|
-
describe Web
|
5
|
-
include Rack::Test::Methods
|
6
|
-
|
7
|
-
def app
|
8
|
-
Web::API
|
9
|
-
end
|
10
|
-
|
4
|
+
describe "Web" do
|
11
5
|
before do
|
12
|
-
RRRSpec.configuration =
|
6
|
+
RRRSpec.configuration = Web::WebConfiguration.new
|
13
7
|
RRRSpec.configuration.redis = @redis
|
8
|
+
RRRSpec.configuration.execute_log_text_path = Dir.mktmpdir
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
FileUtils.remove_entry_secure(RRRSpec.configuration.execute_log_text_path)
|
14
13
|
end
|
15
14
|
|
16
15
|
let(:taskset) do
|
@@ -23,96 +22,328 @@ module RRRSpec
|
|
23
22
|
Task.create(taskset, 10, 'spec/test_spec.rb')
|
24
23
|
end
|
25
24
|
|
26
|
-
let(:worker) do
|
25
|
+
let!(:worker) do
|
27
26
|
Worker.create('default')
|
28
27
|
end
|
29
28
|
|
30
|
-
let(:worker_log) do
|
29
|
+
let!(:worker_log) do
|
31
30
|
WorkerLog.create(worker, taskset)
|
32
31
|
end
|
33
32
|
|
34
|
-
let(:slave) do
|
33
|
+
let!(:slave) do
|
35
34
|
Slave.create
|
36
35
|
end
|
37
36
|
|
37
|
+
let(:trial) do
|
38
|
+
Trial.create(task, slave)
|
39
|
+
end
|
40
|
+
|
41
|
+
def taskset_id
|
42
|
+
RRRSpec::Server::Persistence::Taskset.by_redis_model(taskset).first!.id
|
43
|
+
end
|
44
|
+
|
38
45
|
before do
|
39
|
-
worker # Create worker
|
40
46
|
taskset.add_task(task)
|
41
47
|
taskset.enqueue_task(task)
|
48
|
+
|
42
49
|
ActiveTaskset.add(taskset)
|
43
|
-
|
50
|
+
|
44
51
|
worker_log.set_rsync_finished_time
|
45
52
|
worker_log.append_log('worker_log log body')
|
46
53
|
worker_log.set_setup_finished_time
|
47
|
-
|
54
|
+
|
48
55
|
taskset.add_slave(slave)
|
49
56
|
slave.append_log('slave log body')
|
50
|
-
|
57
|
+
|
51
58
|
trial.start
|
52
59
|
trial.finish('pending', 'stdout body', 'stderr body', 10, 2, 0)
|
60
|
+
|
53
61
|
task.update_status('pending')
|
62
|
+
taskset.append_log('taskset log body')
|
63
|
+
|
54
64
|
taskset.incr_succeeded_count
|
55
65
|
taskset.finish_task(task)
|
56
66
|
taskset.update_status('succeeded')
|
57
67
|
taskset.set_finished_time
|
68
|
+
|
58
69
|
ActiveTaskset.remove(taskset)
|
70
|
+
|
59
71
|
slave.update_status('normal_exit')
|
72
|
+
|
60
73
|
worker_log.set_finished_time
|
61
74
|
end
|
62
75
|
|
63
|
-
describe
|
64
|
-
|
76
|
+
describe Web::API do
|
77
|
+
include Rack::Test::Methods
|
65
78
|
|
66
|
-
|
67
|
-
|
68
|
-
expect(last_response.status).to eq(200)
|
69
|
-
expect(JSON.parse(last_response.body)).to eq(JSON.parse(ActiveTaskset.list.to_json))
|
79
|
+
def app
|
80
|
+
Web::API
|
70
81
|
end
|
71
|
-
end
|
72
82
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
83
|
+
describe "GET /v1/tasksets/actives" do
|
84
|
+
before { ActiveTaskset.add(taskset) }
|
85
|
+
|
86
|
+
it 'returns the active tasksets' do
|
87
|
+
get "/v1/tasksets/actives"
|
88
|
+
expect(last_response.status).to eq(200)
|
89
|
+
expect(JSON.parse(last_response.body)).to eq(JSON.parse(ActiveTaskset.list.to_json))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "GET /v1/tasksets/recents" do
|
94
|
+
context 'there are 11 tasksets' do
|
95
|
+
before do
|
96
|
+
11.times { Server::Persistence::Taskset.create() }
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'returns the recent 10 tasksets' do
|
100
|
+
get "/v1/tasksets/recents"
|
101
|
+
expect(last_response.status).to eq(200)
|
102
|
+
expect(JSON.parse(last_response.body).size).to eq(10)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "GET /v1/tasksets/:key" do
|
108
|
+
context 'with the taskset persisted' do
|
109
|
+
before do
|
110
|
+
Server::Persister.persist(taskset)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'returns the taskset' do
|
114
|
+
get "/v1/tasksets/#{taskset.key}"
|
115
|
+
expect(last_response.status).to eq(200)
|
116
|
+
expect(JSON.parse(last_response.body)).to eq(
|
117
|
+
JSON.parse(JSON.generate(Server::Persistence::Taskset.first.as_full_json)).update("is_full" => true)
|
118
|
+
)
|
119
|
+
end
|
77
120
|
end
|
78
121
|
|
79
|
-
|
80
|
-
|
122
|
+
context 'with the taskset not persisted' do
|
123
|
+
it 'returns 404' do
|
124
|
+
get "/v1/tasksets/#{taskset.key}"
|
125
|
+
expect(last_response.status).to eq(404)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "GET /v1/batch/tasks/:key" do
|
131
|
+
it 'returns all tasks in the taskset' do
|
132
|
+
get "/v1/batch/tasks/#{taskset.key}"
|
81
133
|
expect(last_response.status).to eq(200)
|
82
|
-
expect(JSON.parse(last_response.body)
|
134
|
+
expect(JSON.parse(last_response.body)).to eq([JSON.parse(task.to_json)])
|
83
135
|
end
|
84
136
|
end
|
85
137
|
end
|
86
138
|
|
87
|
-
describe
|
88
|
-
|
139
|
+
describe Web::APIv2 do
|
140
|
+
include Rack::Test::Methods
|
141
|
+
|
142
|
+
def app
|
143
|
+
Web::APIv2
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "GET /v2/tasksets/actives" do
|
147
|
+
before { ActiveTaskset.add(taskset) }
|
148
|
+
|
149
|
+
it 'returns the active tasksets' do
|
150
|
+
get "/v2/tasksets/actives"
|
151
|
+
expect(last_response.status).to eq(200)
|
152
|
+
expect(JSON.parse(last_response.body)).to eq([
|
153
|
+
{ 'key' => taskset.key },
|
154
|
+
])
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe "GET /v2/tasksets/recents" do
|
159
|
+
context 'there are 11 tasksets' do
|
160
|
+
before do
|
161
|
+
11.times { Server::Persistence::Taskset.create() }
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'returns the recent 10 tasksets' do
|
165
|
+
get "/v2/tasksets/recents"
|
166
|
+
expect(last_response.status).to eq(200)
|
167
|
+
expect(JSON.parse(last_response.body).size).to eq(10)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
shared_context 'the taskset is persisted' do
|
89
173
|
before do
|
90
174
|
Server::Persister.persist(taskset)
|
91
175
|
end
|
176
|
+
end
|
92
177
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
178
|
+
describe 'GET /v2/tasksets/:taskset_key' do
|
179
|
+
context "when the taskset is persisted" do
|
180
|
+
include_context 'the taskset is persisted'
|
181
|
+
|
182
|
+
it 'returns a taskset in JSON' do
|
183
|
+
get "/v2/tasksets/#{taskset.key}"
|
184
|
+
expect(last_response.status).to eq(200)
|
185
|
+
expect(JSON.parse(last_response.body)).to eq({
|
186
|
+
"created_at" => taskset.created_at.iso8601,
|
187
|
+
"finished_at" => taskset.finished_at.iso8601,
|
188
|
+
"id" => 1,
|
189
|
+
"key" => taskset.key,
|
190
|
+
"max_trials" => 3,
|
191
|
+
"max_workers" => 3,
|
192
|
+
"rsync_name" => "testuser",
|
193
|
+
"setup_command" => "echo 1",
|
194
|
+
"slave_command" => "echo 2",
|
195
|
+
"status" => "succeeded",
|
196
|
+
"tasks" => [
|
197
|
+
{
|
198
|
+
"id" => 1,
|
199
|
+
"key" => task.key,
|
200
|
+
"status" => "pending",
|
201
|
+
"spec_path" => "spec/test_spec.rb",
|
202
|
+
"estimate_sec" => 10,
|
203
|
+
"trials" => [
|
204
|
+
{
|
205
|
+
"id" => 1,
|
206
|
+
"key" => trial.key,
|
207
|
+
"task_id" => 1,
|
208
|
+
"slave_id" => 1,
|
209
|
+
"started_at" => trial.started_at.iso8601,
|
210
|
+
"finished_at" => trial.finished_at.iso8601,
|
211
|
+
"status" => "pending",
|
212
|
+
"passed" => 10,
|
213
|
+
"pending" => 2,
|
214
|
+
"failed" => 0
|
215
|
+
},
|
216
|
+
],
|
217
|
+
},
|
218
|
+
],
|
219
|
+
"taskset_class" => "default",
|
220
|
+
"worker_type" => "default",
|
221
|
+
})
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context "when the taskset is not persisted" do
|
226
|
+
it "returns 404" do
|
227
|
+
get "/v2/tasksets/#{taskset.key}"
|
228
|
+
expect(last_response.status).to eq(404)
|
229
|
+
end
|
99
230
|
end
|
100
231
|
end
|
101
232
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
233
|
+
describe 'GET /v2/tasksets/:taskset_id/log' do
|
234
|
+
context "when the taskset is persisted" do
|
235
|
+
include_context 'the taskset is persisted'
|
236
|
+
|
237
|
+
it 'returns a string in JSON' do
|
238
|
+
get "/v2/tasksets/#{taskset_id}/log"
|
239
|
+
expect(last_response.status).to eq(200)
|
240
|
+
expect(JSON.parse(last_response.body)).to eq({
|
241
|
+
'log' => 'taskset log body',
|
242
|
+
})
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context "when the taskset is not persisted" do
|
247
|
+
it "returns 404" do
|
248
|
+
get "/v2/tasksets/0/log"
|
249
|
+
expect(last_response.status).to eq(404)
|
250
|
+
end
|
106
251
|
end
|
107
252
|
end
|
108
|
-
end
|
109
253
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
254
|
+
describe 'GET /v2/tasks/:task_id/trials' do
|
255
|
+
context "when the taskset is persisted" do
|
256
|
+
include_context 'the taskset is persisted'
|
257
|
+
|
258
|
+
it 'returns trials in JSON' do
|
259
|
+
get "/v2/tasks/#{taskset_id}/trials"
|
260
|
+
expect(last_response.status).to eq(200)
|
261
|
+
expect(JSON.parse(last_response.body)).to eq([
|
262
|
+
{
|
263
|
+
"id" => 1,
|
264
|
+
"key" => trial.key,
|
265
|
+
"task_id" => 1,
|
266
|
+
"slave_id" => 1,
|
267
|
+
"started_at" => trial.started_at.iso8601,
|
268
|
+
"finished_at" => trial.finished_at.iso8601,
|
269
|
+
"status" => "pending",
|
270
|
+
"passed" => 10,
|
271
|
+
"pending" => 2,
|
272
|
+
"failed" => 0,
|
273
|
+
},
|
274
|
+
])
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
context "when the taskset is not persisted" do
|
279
|
+
it "returns 404" do
|
280
|
+
get "/v2/tasksets/#{taskset.key}/trials"
|
281
|
+
expect(last_response.status).to eq(404)
|
282
|
+
end
|
283
|
+
end
|
115
284
|
end
|
285
|
+
|
286
|
+
describe 'GET /v2/tasksets/:taskset_id/worker_logs' do
|
287
|
+
context "when the taskset is persisted" do
|
288
|
+
include_context 'the taskset is persisted'
|
289
|
+
|
290
|
+
it 'returns worker logs in JSON' do
|
291
|
+
get "/v2/tasksets/#{taskset_id}/worker_logs"
|
292
|
+
expect(last_response.status).to eq(200)
|
293
|
+
expect(JSON.parse(last_response.body)).to eq([
|
294
|
+
{
|
295
|
+
"id" => 1,
|
296
|
+
"worker_name" => "rrrspec:worker:testhostname",
|
297
|
+
"started_at" => worker_log.started_at.iso8601,
|
298
|
+
"rsync_finished_at" => worker_log.rsync_finished_at.iso8601,
|
299
|
+
"setup_finished_at" => worker_log.setup_finished_at.iso8601,
|
300
|
+
"rspec_finished_at" => worker_log.finished_at.iso8601,
|
301
|
+
"log" => "worker_log log body",
|
302
|
+
},
|
303
|
+
])
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
context "when the taskset is not persisted" do
|
308
|
+
it "returns 404" do
|
309
|
+
get "/v2/tasksets/0/worker_logs"
|
310
|
+
expect(last_response.status).to eq(404)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
describe 'GET /v2/tasksets/:taskset_id/slaves' do
|
316
|
+
context "when the taskset is persisted" do
|
317
|
+
include_context 'the taskset is persisted'
|
318
|
+
|
319
|
+
it 'returns slaves in JSON' do
|
320
|
+
get "/v2/tasksets/#{taskset_id}/slaves"
|
321
|
+
expect(last_response.status).to eq(200)
|
322
|
+
expect(JSON.parse(last_response.body)).to eq([
|
323
|
+
{
|
324
|
+
"id" => 1,
|
325
|
+
"name" => slave.key,
|
326
|
+
"status" => "normal_exit",
|
327
|
+
"trials" => [
|
328
|
+
{
|
329
|
+
"id" => 1,
|
330
|
+
"key" => trial.key,
|
331
|
+
},
|
332
|
+
],
|
333
|
+
"log" => "slave log body",
|
334
|
+
},
|
335
|
+
])
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
context "when the taskset is not persisted" do
|
340
|
+
it "returns 404" do
|
341
|
+
get "/v2/tasksets/0/slaves"
|
342
|
+
expect(last_response.status).to eq(404)
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
116
347
|
end
|
117
348
|
end
|
118
349
|
end
|