Add negative functional tests where a non-admin user invokes create or setup actions
[arvados.git] / services / api / test / functional / arvados / v1 / jobs_controller_test.rb
1 require 'test_helper'
2
3 class Arvados::V1::JobsControllerTest < ActionController::TestCase
4
5   test "submit a job" do
6     authorize_with :active
7     post :create, job: {
8       script: "hash",
9       script_version: "master",
10       script_parameters: {}
11     }
12     assert_response :success
13     assert_not_nil assigns(:object)
14     new_job = JSON.parse(@response.body)
15     assert_not_nil new_job['uuid']
16     assert_not_nil new_job['script_version'].match(/^[0-9a-f]{40}$/)
17   end
18
19   test "normalize output and log uuids when creating job" do
20     authorize_with :active
21     post :create, job: {
22       script: "hash",
23       script_version: "master",
24       script_parameters: {},
25       started_at: Time.now,
26       finished_at: Time.now,
27       running: false,
28       success: true,
29       output: 'd41d8cd98f00b204e9800998ecf8427e+0+K@xyzzy',
30       log: 'd41d8cd98f00b204e9800998ecf8427e+0+K@xyzzy'
31     }
32     assert_response :success
33     assert_not_nil assigns(:object)
34     new_job = JSON.parse(@response.body)
35     assert_equal 'd41d8cd98f00b204e9800998ecf8427e+0', new_job['log']
36     assert_equal 'd41d8cd98f00b204e9800998ecf8427e+0', new_job['output']
37     version = new_job['script_version']
38
39     # Make sure version doesn't get mangled by normalize
40     assert_not_nil version.match(/^[0-9a-f]{40}$/)
41     put :update, {
42       id: new_job['uuid'],
43       job: {
44         log: new_job['log']
45       }
46     }
47     assert_equal version, JSON.parse(@response.body)['script_version']
48   end
49
50   test "cancel a running job" do
51     # We need to verify that "cancel" creates a trigger file, so first
52     # let's make sure there is no stale trigger file.
53     begin
54       File.unlink(Rails.configuration.crunch_refresh_trigger)
55     rescue Errno::ENOENT
56     end
57
58     authorize_with :active
59     put :update, {
60       id: jobs(:running).uuid,
61       job: {
62         cancelled_at: 4.day.ago
63       }
64     }
65     assert_response :success
66     assert_not_nil assigns(:object)
67     job = JSON.parse(@response.body)
68     assert_not_nil job['uuid']
69     assert_not_nil job['cancelled_at']
70     assert_not_nil job['cancelled_by_user_uuid']
71     assert_not_nil job['cancelled_by_client_uuid']
72     assert_equal(true, Time.parse(job['cancelled_at']) > 1.minute.ago,
73                  'server should correct bogus cancelled_at ' +
74                  job['cancelled_at'])
75     assert_equal(true,
76                  File.exists?(Rails.configuration.crunch_refresh_trigger),
77                  'trigger file should be created when job is cancelled')
78
79     put :update, {
80       id: jobs(:running).uuid,
81       job: {
82         cancelled_at: nil
83       }
84     }
85     job = JSON.parse(@response.body)
86     assert_not_nil job['cancelled_at'], 'un-cancelled job stays cancelled'
87   end
88
89   test "update a job without failing script_version check" do
90     authorize_with :admin
91     put :update, {
92       id: jobs(:uses_nonexistent_script_version).uuid,
93       job: {
94         owner_uuid: users(:admin).uuid
95       }
96     }
97     assert_response :success
98     put :update, {
99       id: jobs(:uses_nonexistent_script_version).uuid,
100       job: {
101         owner_uuid: users(:active).uuid
102       }
103     }
104     assert_response :success
105   end
106
107   test "search jobs by uuid with >= query" do
108     authorize_with :active
109     get :index, {
110       filters: [['uuid', '>=', 'zzzzz-8i9sb-pshmckwoma9plh7']]
111     }
112     assert_response :success
113     found = assigns(:objects).collect(&:uuid)
114     assert_equal true, !!found.index('zzzzz-8i9sb-pshmckwoma9plh7')
115     assert_equal false, !!found.index('zzzzz-8i9sb-4cf0nhn6xte809j')
116   end
117
118   test "search jobs by uuid with <= query" do
119     authorize_with :active
120     get :index, {
121       filters: [['uuid', '<=', 'zzzzz-8i9sb-pshmckwoma9plh7']]
122     }
123     assert_response :success
124     found = assigns(:objects).collect(&:uuid)
125     assert_equal true, !!found.index('zzzzz-8i9sb-pshmckwoma9plh7')
126     assert_equal true, !!found.index('zzzzz-8i9sb-4cf0nhn6xte809j')
127   end
128
129   test "search jobs by uuid with >= and <= query" do
130     authorize_with :active
131     get :index, {
132       filters: [['uuid', '>=', 'zzzzz-8i9sb-pshmckwoma9plh7'],
133               ['uuid', '<=', 'zzzzz-8i9sb-pshmckwoma9plh7']]
134     }
135     assert_response :success
136     found = assigns(:objects).collect(&:uuid)
137     assert_equal found, ['zzzzz-8i9sb-pshmckwoma9plh7']
138   end
139
140   test "search jobs by uuid with < query" do
141     authorize_with :active
142     get :index, {
143       filters: [['uuid', '<', 'zzzzz-8i9sb-pshmckwoma9plh7']]
144     }
145     assert_response :success
146     found = assigns(:objects).collect(&:uuid)
147     assert_equal false, !!found.index('zzzzz-8i9sb-pshmckwoma9plh7')
148     assert_equal true, !!found.index('zzzzz-8i9sb-4cf0nhn6xte809j')
149   end
150
151   test "search jobs by uuid with like query" do
152     authorize_with :active
153     get :index, {
154       filters: [['uuid', 'like', '%hmckwoma9pl%']]
155     }
156     assert_response :success
157     found = assigns(:objects).collect(&:uuid)
158     assert_equal found, ['zzzzz-8i9sb-pshmckwoma9plh7']
159   end
160
161   test "search jobs by uuid with 'in' query" do
162     authorize_with :active
163     get :index, {
164       filters: [['uuid', 'in', ['zzzzz-8i9sb-4cf0nhn6xte809j',
165                                 'zzzzz-8i9sb-pshmckwoma9plh7']]]
166     }
167     assert_response :success
168     found = assigns(:objects).collect(&:uuid)
169     assert_equal found.sort, ['zzzzz-8i9sb-4cf0nhn6xte809j',
170                               'zzzzz-8i9sb-pshmckwoma9plh7']
171   end
172
173   test "search jobs by started_at with < query" do
174     authorize_with :active
175     get :index, {
176       filters: [['started_at', '<', Time.now.to_s]]
177     }
178     assert_response :success
179     found = assigns(:objects).collect(&:uuid)
180     assert_equal true, !!found.index('zzzzz-8i9sb-pshmckwoma9plh7')
181   end
182
183   test "search jobs by started_at with > query" do
184     authorize_with :active
185     get :index, {
186       filters: [['started_at', '>', Time.now.to_s]]
187     }
188     assert_response :success
189     assert_equal 0, assigns(:objects).count
190   end
191
192   test "search jobs by started_at with >= query on metric date" do
193     authorize_with :active
194     get :index, {
195       filters: [['started_at', '>=', '2014-01-01']]
196     }
197     assert_response :success
198     found = assigns(:objects).collect(&:uuid)
199     assert_equal true, !!found.index('zzzzz-8i9sb-pshmckwoma9plh7')
200   end
201
202   test "search jobs by started_at with >= query on metric date and time" do
203     authorize_with :active
204     get :index, {
205       filters: [['started_at', '>=', '2014-01-01 01:23:45']]
206     }
207     assert_response :success
208     found = assigns(:objects).collect(&:uuid)
209     assert_equal true, !!found.index('zzzzz-8i9sb-pshmckwoma9plh7')
210   end
211
212   test "search jobs with 'any' operator" do
213     authorize_with :active
214     get :index, {
215       where: { any: ['contains', 'pshmckw'] }
216     }
217     assert_response :success
218     found = assigns(:objects).collect(&:uuid)
219     assert_equal true, !!found.index('zzzzz-8i9sb-pshmckwoma9plh7')
220   end
221
222   test "search jobs by nonexistent column with < query" do
223     authorize_with :active
224     get :index, {
225       filters: [['is_borked', '<', 'fizzbuzz']]
226     }
227     assert_response 422
228   end
229 end