rrrspec-web 0.2.0 → 0.2.1

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.
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