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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/assets/javascripts/helpers.coffee +27 -0
  4. data/assets/javascripts/index.coffee +75 -0
  5. data/{app/js → assets/javascripts}/models.coffee +41 -69
  6. data/assets/javascripts/tasksets.coffee +400 -0
  7. data/{app/js → assets/javascripts}/vendor/backbone-min.js +0 -0
  8. data/{app/js → assets/javascripts}/vendor/backbone-min.map +0 -0
  9. data/{app/js → assets/javascripts}/vendor/backbone.js +0 -0
  10. data/assets/javascripts/vendor/handlebars-v1.3.0.js +2746 -0
  11. data/{app/js → assets/javascripts}/vendor/jquery-1.10.2.js +0 -0
  12. data/{app/js → assets/javascripts}/vendor/jquery-1.10.2.min.js +0 -0
  13. data/{app/js → assets/javascripts}/vendor/jquery-1.10.2.min.map +0 -0
  14. data/{app/js → assets/javascripts}/vendor/moment.min.js +0 -0
  15. data/{app/js → assets/javascripts}/vendor/underscore-min.js +0 -0
  16. data/{app/js → assets/javascripts}/vendor/underscore-min.map +0 -0
  17. data/{app/js → assets/javascripts}/vendor/underscore.js +0 -0
  18. data/assets/stylesheets/application.sass +188 -0
  19. data/lib/rrrspec/web/api.rb +61 -0
  20. data/lib/rrrspec/web/app.rb +9 -30
  21. data/lib/rrrspec/web/configuration.rb +1 -0
  22. data/lib/rrrspec/web/persistent_models.rb +7 -2
  23. data/lib/rrrspec/web/version.rb +1 -1
  24. data/rrrspec-web.gemspec +9 -7
  25. data/spec/rrrspec/web/api_spec.rb +278 -47
  26. data/tasks/assets.rake +3 -6
  27. data/views/index.haml +4 -14
  28. data/views/taskset.haml +61 -68
  29. data/views/user.haml +2 -2
  30. metadata +108 -84
  31. data/app/css/application.sass +0 -124
  32. data/app/css/vendor/bootstrap-theme.css +0 -384
  33. data/app/css/vendor/bootstrap-theme.min.css +0 -1
  34. data/app/css/vendor/bootstrap.css +0 -6805
  35. data/app/css/vendor/bootstrap.min.css +0 -9
  36. data/app/js/index.coffee +0 -51
  37. data/app/js/tasksets.coffee +0 -305
  38. data/app/js/vendor/bootstrap.js +0 -1999
  39. data/app/js/vendor/bootstrap.min.js +0 -6
  40. data/app/js/vendor/mustache.js +0 -551
@@ -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
@@ -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
@@ -1,5 +1,5 @@
1
1
  require 'sinatra/base'
2
- require 'sinatra/assetpack'
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
@@ -1,6 +1,7 @@
1
1
  module RRRSpec
2
2
  module Web
3
3
  class WebConfiguration < RRRSpec::Configuration
4
+ attr_accessor :execute_log_text_path
4
5
  attr_accessor :persistence_db
5
6
 
6
7
  def initialize
@@ -4,8 +4,13 @@ module RRRSpec
4
4
  module Server
5
5
  module Persistence
6
6
  class Taskset
7
- scope :recent, order('finished_at DESC')
8
- scope :has_failed_slaves, includes(:slaves).where(slaves: {status: 'failure_exit'})
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)
@@ -1,5 +1,5 @@
1
1
  module RRRSpec
2
2
  module Web
3
- VERSION = "0.2.0"
3
+ VERSION = "0.2.1"
4
4
  end
5
5
  end
@@ -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.add_dependency "activerecord", "~> 3.0"
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-assetpack"
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::API do
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 = Configuration.new
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
- worker_log # Create worker_log
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
- slave # Create slave
54
+
48
55
  taskset.add_slave(slave)
49
56
  slave.append_log('slave log body')
50
- trial = Trial.create(task, slave)
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 "GET /v1/tasksets/actives" do
64
- before { ActiveTaskset.add(taskset) }
76
+ describe Web::API do
77
+ include Rack::Test::Methods
65
78
 
66
- it 'returns the active tasksets' do
67
- get "/v1/tasksets/actives"
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
- describe "GET /v1/tasksets/recents" do
74
- context 'there are 11 tasksets' do
75
- before do
76
- 11.times { Server::Persistence::Taskset.create() }
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
- it 'returns the recent 10 tasksets' do
80
- get "/v1/tasksets/recents"
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).size).to eq(10)
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 "GET /v1/tasksets/:key" do
88
- context 'with the taskset persisted' do
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
- it 'returns the taskset' do
94
- get "/v1/tasksets/#{taskset.key}"
95
- expect(last_response.status).to eq(200)
96
- expect(JSON.parse(last_response.body)).to eq(
97
- JSON.parse(JSON.generate(Server::Persistence::Taskset.first.as_full_json)).update("is_full" => true)
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
- context 'with the taskset not persisted' do
103
- it 'returns 404' do
104
- get "/v1/tasksets/#{taskset.key}"
105
- expect(last_response.status).to eq(404)
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
- describe "GET /v1/batch/tasks/:key" do
111
- it 'returns all tasks in the taskset' do
112
- get "/v1/batch/tasks/#{taskset.key}"
113
- expect(last_response.status).to eq(200)
114
- expect(JSON.parse(last_response.body)).to eq([JSON.parse(task.to_json)])
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