t2-server 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +1 -0
  3. data/.ruby-env +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +7 -1
  7. data/CHANGES.rdoc +49 -0
  8. data/README.rdoc +10 -8
  9. data/bin/t2-delete-runs +0 -3
  10. data/lib/t2-server-cli.rb +16 -9
  11. data/lib/t2-server/exceptions.rb +7 -19
  12. data/lib/t2-server/net/connection.rb +14 -6
  13. data/lib/t2-server/net/credentials.rb +12 -1
  14. data/lib/t2-server/net/parameters.rb +3 -3
  15. data/lib/t2-server/port.rb +12 -29
  16. data/lib/t2-server/run.rb +54 -35
  17. data/lib/t2-server/server.rb +3 -4
  18. data/lib/t2-server/xml.rb +0 -1
  19. data/lib/t2-server/xml/methods.rb +97 -4
  20. data/t2-server.gemspec +4 -1
  21. data/test/helpers/fake-run.rb +47 -0
  22. data/test/helpers/test-cache.rb +49 -0
  23. data/test/helpers/test-xml.rb +36 -0
  24. data/test/helpers/timezone.rb +39 -0
  25. data/test/mocked-server-responses/.gitattributes +1 -0
  26. data/test/mocked-server-responses/get-admin.raw +6 -0
  27. data/test/mocked-server-responses/get-rest-policy-runlimit.raw +6 -0
  28. data/test/mocked-server-responses/get-rest-policy.raw +6 -0
  29. data/test/mocked-server-responses/get-rest-run-input-expected.raw +6 -0
  30. data/test/mocked-server-responses/get-rest-run-input.raw +6 -0
  31. data/test/mocked-server-responses/get-rest-run-interaction-feed-0.raw +11 -0
  32. data/test/mocked-server-responses/get-rest-run-interaction-feed-1.raw +92 -0
  33. data/test/mocked-server-responses/get-rest-run-interaction-feed-2.raw +80 -0
  34. data/test/mocked-server-responses/get-rest-run-name.raw +6 -0
  35. data/test/mocked-server-responses/get-rest-run-output-list-errors.raw +6 -0
  36. data/test/mocked-server-responses/get-rest-run-output.raw +6 -0
  37. data/test/mocked-server-responses/get-rest-run-security-permissions.raw +6 -0
  38. data/test/mocked-server-responses/get-rest-run-security.raw +6 -0
  39. data/test/mocked-server-responses/get-rest-run.raw +6 -0
  40. data/test/mocked-server-responses/get-rest-runs.raw +6 -0
  41. data/test/mocked-server-responses/get-rest.raw +6 -0
  42. data/test/mocked-server-responses/log.txt +1 -0
  43. data/test/mocked-server-responses/mocks.rb +107 -0
  44. data/test/mocked-server-responses/options-admin-allownew.raw +7 -0
  45. data/test/tc_admin.rb +52 -24
  46. data/test/tc_admin_live.rb +66 -0
  47. data/test/tc_connection.rb +87 -0
  48. data/test/tc_connection_exceptions.rb +86 -0
  49. data/test/tc_credentials.rb +73 -0
  50. data/test/tc_interaction.rb +182 -0
  51. data/test/{tc_misc.rb → tc_misc_live.rb} +3 -1
  52. data/test/tc_params.rb +82 -4
  53. data/test/tc_perms.rb +54 -101
  54. data/test/tc_perms_live.rb +150 -0
  55. data/test/tc_ports.rb +192 -0
  56. data/test/tc_run.rb +333 -350
  57. data/test/tc_run_live.rb +453 -0
  58. data/test/{tc_secure.rb → tc_secure_live.rb} +30 -29
  59. data/test/tc_server.rb +115 -42
  60. data/test/tc_server_live.rb +92 -0
  61. data/test/tc_server_version.rb +19 -0
  62. data/test/tc_xml_messages.rb +201 -0
  63. data/test/ts_t2server.rb +37 -43
  64. data/test/workflows/secure/heater-pk.pem +24 -18
  65. data/test/workflows/secure/user-cert.p12 +0 -0
  66. data/version.yml +1 -1
  67. metadata +136 -29
  68. data/lib/t2-server/xml/fragments.rb +0 -78
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2010-2014 The University of Manchester, UK.
1
+ # Copyright (c) 2014 The University of Manchester, UK.
2
2
  #
3
3
  # All rights reserved.
4
4
  #
@@ -30,428 +30,411 @@
30
30
  #
31
31
  # Author: Robert Haines
32
32
 
33
+ require 'mocked-server-responses/mocks'
33
34
  require 't2-server'
34
35
 
35
- # A class to test data streaming.
36
- class TestCache
37
- attr_reader :data
38
-
39
- def initialize
40
- @data = ""
41
- end
42
-
43
- def write(data)
44
- @data += data
45
- data.size
46
- end
47
-
48
- def size
49
- return @data.size
50
- end
51
- end
36
+ require 'helpers/timezone'
37
+ require 'helpers/test-cache'
52
38
 
53
39
  class TestRun < Test::Unit::TestCase
40
+ include T2Server::Mocks
41
+
42
+ WKF_PASS = "test/workflows/pass_through.t2flow"
43
+
44
+ # Some expiry times, mangled to work in different timezones.
45
+ TIME_STR = "2014-05-08 17:41:57 #{timezone}00" # Ruby time format
46
+ TIME_RET = "2014-05-08T17:41:57.00#{timezone}:00" # Server return format
47
+ TIME_SET = "2014-05-08T17:41:57.00#{timezone}00" # Server update format
48
+
49
+ # Need to lock down the run UUID so recorded server responses make sense.
50
+ RUN_UUID = "a341b87f-25cc-4dfd-be36-f5b073a6ba74"
51
+ RUN_PATH = "/rest/runs/#{RUN_UUID}"
52
+ RUN_LSTN = "#{RUN_PATH}/listeners/io/properties"
53
+
54
+ def setup
55
+ # Register common mocks.
56
+ mock("/rest/", :accept => "application/xml", :output => "get-rest.raw")
57
+ mock("/rest/policy", :accept => "application/xml",
58
+ :output => "get-rest-policy.raw")
59
+ mock("/rest/runs", :method => :post, :credentials => $userinfo,
60
+ :status => 201,
61
+ :location => "https://localhost/taverna#{RUN_PATH}")
62
+ mock(RUN_PATH, :accept => "application/xml", :credentials => $userinfo,
63
+ :output => "get-rest-run.raw")
64
+ mock("#{RUN_PATH}/input", :accept => "application/xml",
65
+ :credentials => $userinfo, :output => "get-rest-run-input.raw")
66
+ mock("#{RUN_PATH}/security", :accept => "application/xml",
67
+ :credentials => $userinfo, :output => "get-rest-run-security.raw")
68
+
69
+ @run = T2Server::Run.create($uri, WKF_PASS, $creds, $conn_params)
70
+ end
54
71
 
55
72
  # Test run connection
56
73
  def test_run_create_and_delete
57
- assert_nothing_raised(T2Server::ConnectionError) do
58
- run = T2Server::Run.create($uri, $wkf_pass, $creds, $conn_params)
59
- assert_equal(run.status, :initialized)
60
- assert(run.delete)
61
- assert(run.deleted?)
62
- assert_equal(run.status, :deleted)
63
- assert_nothing_raised(T2Server::AttributeNotFoundError) do
64
- assert(run.delete) # Should still return true, not raise 404
65
- end
66
- assert(run.delete) # Should still return true
74
+ status = mock("#{RUN_PATH}/status", :accept => "text/plain",
75
+ :credentials => $userinfo, :body => "Finished")
76
+ del = mock(RUN_PATH, :method => :delete, :status => [204, 404, 404],
77
+ :credentials => $userinfo)
78
+
79
+ assert @run.finished?
80
+ refute @run.deleted?
81
+
82
+ assert @run.delete
83
+ assert @run.deleted?
84
+ refute @run.finished?
85
+ assert_nothing_raised(T2Server::AttributeNotFoundError) do
86
+ assert @run.delete # Should still return true, not raise 404
67
87
  end
88
+ assert @run.delete # Should still return true
89
+
90
+ assert_equal :deleted, @run.status
91
+ assert_not_equal :finished, @run.status
92
+
93
+ assert_requested status, :times => 1
94
+ assert_requested del, :times => 3
68
95
  end
69
96
 
70
- # Test misc run functions
71
- def test_status_codes
72
- T2Server::Run.create($uri, $wkf_pass, $creds, $conn_params) do |run|
97
+ # Test run naming.
98
+ def test_run_naming
99
+ mock("#{RUN_PATH}/name", :accept => "text/plain", :status => 200,
100
+ :credentials => $userinfo, :output => "get-rest-run-name.raw")
73
101
 
74
- # test mkdir
75
- assert(run.mkdir("test"))
102
+ # Read initial name.
103
+ assert @run.name.length > 0
104
+ assert_equal "Workflow1", @run.name
76
105
 
77
- # set input, start, check state and wait
78
- assert_nothing_raised(T2Server::AttributeNotFoundError) do
79
- run.input_port("IN").value = "Hello, World!"
80
- end
81
- assert_equal(run.input_port("IN").value, "Hello, World!")
82
-
83
- # test correct/incorrect status codes
84
- assert_equal(run.status, :initialized)
85
- assert_raise(T2Server::RunStateError) { run.wait }
86
- assert_nothing_raised(T2Server::RunStateError) { run.start }
87
- assert(run.running?)
88
- assert_equal(run.status, :running)
89
- assert_nothing_raised(T2Server::RunStateError) { run.wait }
90
- assert_equal(run.status, :finished)
91
- assert_raise(T2Server::RunStateError) { run.start }
92
-
93
- # exitcode and output
94
- assert_instance_of(Fixnum, run.exitcode)
95
- assert_equal(run.output_port("OUT").value, "Hello, World!")
96
- assert_equal(run.output_port("wrong!"), nil)
97
-
98
- # get zip file
99
- assert_nothing_raised(T2Server::T2ServerError) do
100
- zip_out = run.zip_output
101
- assert_not_equal(zip_out, "")
102
- end
106
+ # Set a new name.
107
+ name = "No input or output"
103
108
 
104
- # test streaming zip data
105
- assert_nothing_raised(T2Server::T2ServerError) do
106
- zip_cache = TestCache.new
107
- run.zip_output(zip_cache)
108
- end
109
+ mock("#{RUN_PATH}/name", :method => :put, :body => name,
110
+ :status => 200, :credentials => $userinfo)
109
111
 
110
- # show getting a zip file of a singleton port does nothing
111
- assert_nothing_raised(T2Server::T2ServerError) do
112
- assert_nil(run.output_port("OUT").zip)
112
+ assert @run.name = name
113
113
 
114
- zip_cache = TestCache.new
115
- run.output_port("OUT").zip(zip_cache)
116
- assert_equal(zip_cache.data, "")
117
- end
114
+ # Set a name that is too long. The mock should only see the first 48
115
+ # characters.
116
+ long_name = "0123456789012345678901234567890123456789ABCDEFGHIJ"
118
117
 
119
- # deletion
120
- assert(run.delete)
121
- end
122
- end
118
+ mock("#{RUN_PATH}/name", :method => :put, :body => long_name[0...48],
119
+ :status => 200, :credentials => $userinfo)
123
120
 
124
- # Test run naming. This is different for different versions of server.
125
- def test_run_naming
126
- T2Server::Server.new($uri, $conn_params) do |server|
127
- server.create_run($wkf_no_io, $creds) do |run|
128
- if server.version >= "2.5.0"
129
- # Read initial name.
130
- assert(run.name.length > 0)
131
- assert_equal("Workflow1", run.name[0...9])
132
-
133
- # Set a new name and test.
134
- name = "No input or output"
135
- assert(run.name = name)
136
- assert(run.name.length == 18)
137
- assert_equal(name, run.name)
138
-
139
- # Set a name that is too long
140
- long_name = "0123456789012345678901234567890123456789ABCDEFGHIJ"
141
- assert(run.name = long_name)
142
- assert(run.name.length == 48)
143
- assert_equal(long_name[0...48], run.name)
144
- else
145
- # Read initial name.
146
- assert(run.name.length == 0)
147
- assert_equal("", run.name)
148
-
149
- # "Set" a new name and test.
150
- assert(run.name = "test")
151
- assert(run.name.length == 0)
152
- assert_equal("", run.name)
153
- end
154
- end
155
- end
121
+ assert @run.name = long_name
156
122
  end
157
123
 
158
- # Test run with no input or output. Also, pre-load workflow into a String.
159
- def test_run_no_ports
160
- workflow = File.read($wkf_no_io)
161
-
162
- T2Server::Run.create($uri, workflow, $creds, $conn_params) do |run|
163
- assert_nothing_raised { run.input_ports }
164
- assert_nothing_raised { run.start }
165
- assert(run.running?)
166
- run.wait
167
- assert_nothing_raised { run.output_ports }
168
- assert(run.delete)
169
- end
124
+ def test_get_expiry
125
+ mock("#{RUN_PATH}/expiry", :accept => "text/plain", :body => TIME_RET,
126
+ :status => 200, :credentials => $userinfo)
127
+
128
+ exp = @run.expiry
129
+ assert exp.instance_of?(Time)
170
130
  end
171
131
 
172
- # Test run with list inputs
173
- def test_run_list_input
174
- T2Server::Run.create($uri, $wkf_lists, $creds, $conn_params) do |run|
175
- many = [[["boo"]], [["", "Hello"]], [], [[], ["test"], []]]
176
- single = [1, 2, 3, 4, 5]
177
- single_out = single.map { |v| v.to_s } # Taverna outputs strings!
178
-
179
- run.input_port("SINGLE_IN").value = single
180
- run.input_port("MANY_IN").value = many
181
- assert_nothing_raised { run.start }
182
- assert(run.running?)
183
- run.wait
184
-
185
- assert_equal(run.output_port("MANY").value, many)
186
- assert_equal(run.output_port("SINGLE").value, single_out)
187
-
188
- # get zip file of a single port and test streaming
189
- assert_nothing_raised(T2Server::T2ServerError) do
190
- zip_out = run.output_port("MANY").zip
191
- assert_not_equal(zip_out, "")
192
- end
132
+ def test_update_expiry
133
+ exp = mock("#{RUN_PATH}/expiry", :method => :put, :accept => "*/*",
134
+ :status => 200, :body => TIME_SET, :credentials => $userinfo)
193
135
 
194
- assert_nothing_raised(T2Server::T2ServerError) do
195
- zip_cache = TestCache.new
196
- run.output_port("MANY").zip(zip_cache)
197
- end
136
+ @run.expiry = TIME_STR
137
+ @run.expiry = Time.parse(TIME_STR)
198
138
 
199
- assert(run.delete)
200
- end
139
+ assert_requested exp, :times => 2
201
140
  end
202
141
 
203
- # Test run with a list and file input, and check that provenance is not on
204
- def test_run_list_and_file
205
- T2Server::Run.create($uri, $wkf_l_v, $creds, $conn_params) do |run|
206
- list = ["one", 2, :three]
207
- list_out = list.map { |v| v.to_s }
142
+ # Upload workflow as a string, then test getting it back.
143
+ def test_get_workflow
144
+ workflow = File.read(WKF_PASS)
208
145
 
209
- run.input_port("list_in").value = list
210
- run.input_port("singleton_in").file = $file_input
211
- assert_nothing_raised { run.start }
212
- assert(run.running?)
213
- run.wait
146
+ wkf = mock("#{RUN_PATH}/workflow", :body => workflow,
147
+ :accept => "application/xml", :credentials => $userinfo)
214
148
 
215
- assert_equal(run.output_port("list_out").value, list_out)
216
- assert_equal(run.output_port("singleton_out").value, "Hello, World!")
149
+ # Download twice to check it's only actually retrieved once.
150
+ assert_equal workflow, @run.workflow
151
+ assert_equal workflow, @run.workflow
217
152
 
218
- # Get the log file
219
- assert_nothing_raised(T2Server::T2ServerError) do
220
- assert_not_equal(run.log, "")
221
- end
153
+ assert_requested wkf, :times => 1
154
+ end
222
155
 
223
- assert_nothing_raised(T2Server::T2ServerError) do
224
- log_cache = TestCache.new
225
- run.log(log_cache)
226
- assert_not_equal(log_cache.size, 0)
227
- end
156
+ def test_mkdir
157
+ dir = "test"
158
+ location = "#{RUN_PATH}/wd/#{dir}"
159
+ mock("#{RUN_PATH}/wd", :method => :post, :accept => "*/*", :status => 201,
160
+ :credentials => $userinfo, :location => location)
228
161
 
229
- assert_raise(T2Server::AccessForbiddenError) do
230
- run.provenance
231
- end
162
+ assert @run.mkdir(dir)
163
+ end
232
164
 
233
- assert(run.delete)
234
- end
165
+ def test_listeners
166
+ mock("#{RUN_LSTN}/exitcode", :accept => "text/plain", :body => "0",
167
+ :credentials => $userinfo)
168
+ mock("#{RUN_LSTN}/stdout", :accept => "text/plain", :body => "Out",
169
+ :credentials => $userinfo)
170
+ mock("#{RUN_LSTN}/stderr", :accept => "text/plain", :body => "Error",
171
+ :credentials => $userinfo)
172
+
173
+ # Check the exitcode is parsed into a number and other things not mangled.
174
+ exit = @run.exitcode
175
+ assert_equal 0, exit
176
+ assert_instance_of(Fixnum, exit)
177
+ assert_equal "Out", @run.stdout
178
+ assert_equal "Error", @run.stderr
235
179
  end
236
180
 
237
- # Test run with xml input
238
- def test_run_xml_input
239
- T2Server::Run.create($uri, $wkf_xml, $creds, $conn_params) do |run|
240
- run.input_port("xml").value =
241
- "<hello><yes>hello</yes><no>everybody</no><yes>world</yes></hello>"
242
- run.input_port("xpath").value = "//yes"
243
- run.start
244
- run.wait
245
- assert_equal(run.output_port("nodes").value, ["hello", "world"])
246
- assert(run.delete)
181
+ def test_full_run
182
+ data = "Hello"
183
+
184
+ in_exp = mock("#{RUN_PATH}/input/expected", :accept => "application/xml",
185
+ :credentials => $userinfo, :output => "get-rest-run-input-expected.raw")
186
+ mock("#{RUN_PATH}/input/input/IN", :method => :put, :accept => "*/*",
187
+ :status => 200, :credentials => $userinfo)
188
+ mock("#{RUN_PATH}/status", :method => :put, :body => "Operating",
189
+ :status => 200, :credentials => $userinfo)
190
+
191
+ # Re-mock status to fake up a running run.
192
+ status = mock("#{RUN_PATH}/status", :accept => "text/plain",
193
+ :status => 200, :credentials => $userinfo,
194
+ :body => ["Initialized", "Initialized", "Operating", "Operating",
195
+ "Operating", "Finished"])
196
+
197
+ out = mock("#{RUN_PATH}/output", :accept => "application/xml",
198
+ :credentials => $userinfo, :output => "get-rest-run-output.raw")
199
+ mock("#{RUN_PATH}/wd/out/OUT", :accept => "application/octet-stream",
200
+ :status => 200, :credentials => $userinfo, :body => data)
201
+
202
+ assert_nothing_raised(T2Server::AttributeNotFoundError) do
203
+ @run.input_port("IN").value = data
247
204
  end
248
- end
205
+ assert_equal data, @run.input_port("IN").value
249
206
 
250
- # Test run with file input. Also pass workflow as File object. Also test
251
- # toggling provenance on and then off again.
252
- def test_run_file_input
253
- workflow = File.open($wkf_pass, "r")
207
+ # Need to start the run to trigger input upload, then don't wait between
208
+ # mocked polling of status.
209
+ @run.start
254
210
 
255
- T2Server::Run.create($uri, $wkf_pass, $creds, $conn_params) do |run|
211
+ assert @run.running?
256
212
 
257
- assert_nothing_raised(T2Server::AttributeNotFoundError) do
258
- run.input_port("IN").file = $file_input
259
- run.generate_provenance
260
- run.generate_provenance(false)
261
- end
262
- refute run.generate_provenance?
213
+ @run.wait(0)
263
214
 
264
- run.start
265
- assert(run.running?)
266
- assert_nothing_raised(T2Server::RunStateError) { run.wait }
267
- assert_equal(run.output_port("OUT").value, "Hello, World!")
215
+ assert @run.finished?
268
216
 
269
- assert_raise(T2Server::AccessForbiddenError) do
270
- run.provenance
271
- end
217
+ outputs = @run.output_ports
218
+ assert_equal 1, outputs.length
219
+
220
+ assert_equal data, @run.output_port("OUT").value
272
221
 
273
- assert(run.delete)
222
+ # No network access should occur on the next call.
223
+ assert_nothing_raised(WebMock::NetConnectNotAllowedError) do
224
+ assert_nil @run.output_port("wrong!")
274
225
  end
275
226
 
276
- workflow.close
227
+ assert_requested status, :times => 6
228
+ assert_requested in_exp, :times => 1
229
+ assert_requested out, :times => 1
277
230
  end
278
231
 
279
- # Test run that returns list of lists, some empty, using baclava for input
280
- # Also test provenance output works with baclava input
281
- def test_baclava_input
282
- T2Server::Run.create($uri, $wkf_lists, $creds, $conn_params) do |run|
283
- assert_nothing_raised(T2Server::AttributeNotFoundError) do
284
- run.baclava_input = $list_input
285
- run.generate_provenance
286
- end
232
+ def test_output_no_errors
233
+ status = mock("#{RUN_PATH}/status", :accept => "text/plain",
234
+ :status => 200, :credentials => $userinfo,
235
+ :body => ["Operating", "Finished"])
236
+ out = mock("#{RUN_PATH}/output", :accept => "application/xml",
237
+ :credentials => $userinfo, :output => "get-rest-run-output.raw")
287
238
 
288
- if run.server.version >= "2.5.3"
289
- assert(run.generate_provenance?)
290
- else
291
- refute(run.generate_provenance?)
292
- end
239
+ # Status :running
240
+ refute @run.error?
293
241
 
294
- assert_equal(run.input_ports.keys.sort, ["MANY_IN", "SINGLE_IN"])
295
- assert_equal(run.input_port("MANY_IN").depth, 3)
296
- assert_equal(run.input_port("SINGLE_IN").depth, 1)
297
- assert(run.baclava_input?)
298
- assert(run.input_port("SINGLE_IN").baclava?)
299
- assert(run.input_port("SINGLE_IN").set?)
300
-
301
- run.start
302
- assert(run.running?)
303
- assert_nothing_raised(T2Server::RunStateError) { run.wait }
304
- assert_equal(run.output_ports.keys.sort, ["MANY", "SINGLE"])
305
- assert_equal(run.output_port("SINGLE").value, [])
306
- assert(!run.output_port("SINGLE").empty?)
307
- assert_equal(run.output_port("MANY").value,
308
- [[["boo"]], [["", "Hello"]], [], [[], ["test"], []]])
309
- assert_equal(run.output_port("MANY").total_size, 12)
310
- assert(run.output_port("MANY")[1][0][0].empty?)
311
- assert_equal(run.output_port("MANY")[1][0][1].value(1..3), "ell")
312
- assert_raise(NoMethodError) { run.output_port("SINGLE")[0].value }
313
-
314
- # Grab provenance
315
- if run.server.version >= "2.5.3"
316
- assert_nothing_raised(T2Server::AccessForbiddenError) do
317
- prov = run.provenance
318
- assert_not_equal(prov, "")
319
- end
320
- else
321
- assert_raise(T2Server::AccessForbiddenError) do
322
- prov = run.provenance
323
- assert_equal(prov, "")
324
- end
325
- end
242
+ # Status :finished
243
+ refute @run.error?
326
244
 
327
- assert(run.delete)
328
- end
245
+ assert_requested status, :times => 2
246
+ assert_requested out, :times => 1
329
247
  end
330
248
 
331
- # Test run with baclava output
332
- def test_baclava_output
333
- T2Server::Run.create($uri, $wkf_pass, $creds, $conn_params) do |run|
334
- run.input_port("IN").value = "Some input..."
335
- assert_nothing_raised(T2Server::AttributeNotFoundError) do
336
- run.generate_baclava_output
337
- end
338
- assert(run.generate_baclava_output?)
249
+ def test_output_with_errors
250
+ status = mock("#{RUN_PATH}/status", :accept => "text/plain",
251
+ :status => 200, :credentials => $userinfo,
252
+ :body => ["Operating", "Finished"])
253
+ out = mock("#{RUN_PATH}/output", :accept => "application/xml",
254
+ :credentials => $userinfo,
255
+ :output => "get-rest-run-output-list-errors.raw")
339
256
 
340
- run.start
341
- assert(run.running?)
342
- assert_nothing_raised(T2Server::RunStateError) { run.wait }
257
+ # Status :running
258
+ refute @run.error?
343
259
 
344
- # Test normal and streamed output
345
- assert_nothing_raised(T2Server::AccessForbiddenError) do
346
- output = run.baclava_output
260
+ # Status :finished
261
+ assert @run.error?
347
262
 
348
- out_stream = ""
349
- run.baclava_output do |chunk|
350
- out_stream += chunk
351
- end
352
- assert_equal(output, out_stream)
353
- end
263
+ assert_requested status, :times => 2
264
+ assert_requested out, :times => 1
265
+ end
266
+
267
+ def test_getting_output
268
+ mock("#{RUN_PATH}/status", :accept => "text/plain", :status => 200,
269
+ :credentials => $userinfo, :body => "Finished")
270
+ out = mock("#{RUN_PATH}/output", :accept => "application/xml",
271
+ :credentials => $userinfo, :output => "get-rest-run-output.raw")
272
+ mock("#{RUN_PATH}/wd/out/OUT", :accept => "application/octet-stream",
273
+ :status => 200, :credentials => $userinfo,
274
+ :body => mocked_file("log.txt"))
275
+
276
+ data = File.read("test/mocked-server-responses/log.txt")
354
277
 
355
- assert(run.delete)
278
+ assert_equal data, @run.output_port("OUT").value
279
+
280
+ out_stream = TestCache.new
281
+ assert_equal data.length, @run.output_port("OUT").stream_value(out_stream)
282
+ assert_equal data, out_stream.data
283
+
284
+ out_stream = ""
285
+ @run.output_port("OUT").value do |chunk|
286
+ out_stream += chunk
356
287
  end
288
+ assert_equal data, out_stream
289
+
290
+ assert_requested out, :times => 1
357
291
  end
358
292
 
359
- # Test partial result download and provenance streaming
360
- def test_result_download
361
- T2Server::Run.create($uri, $wkf_pass, $creds, $conn_params) do |run|
362
- assert_nothing_raised(T2Server::AttributeNotFoundError) do
363
- file = run.upload_file($file_strs)
364
- run.input_port("IN").remote_file = file
365
- run.generate_provenance(true)
366
- end
293
+ def test_output_range
294
+ range = 5..30
295
+ data = File.read("test/mocked-server-responses/log.txt")[range]
367
296
 
368
- if run.server.version >= "2.5.3"
369
- assert(run.generate_provenance?)
370
- else
371
- refute(run.generate_provenance?)
372
- end
297
+ mock("#{RUN_PATH}/status", :accept => "text/plain", :status => 200,
298
+ :credentials => $userinfo, :body => "Finished")
299
+ out = mock("#{RUN_PATH}/output", :accept => "application/xml",
300
+ :credentials => $userinfo, :output => "get-rest-run-output.raw")
301
+ mock("#{RUN_PATH}/wd/out/OUT", :accept => "application/octet-stream",
302
+ :status => 206, :credentials => $userinfo, :body => data)
373
303
 
374
- run.start
375
- run.wait
304
+ assert_equal data, @run.output_port("OUT").value(range)
376
305
 
377
- # Get total data size (without downloading the data).
378
- assert_equal(run.output_port("OUT").total_size, 100)
379
- assert_equal(run.output_port("OUT").size, 100)
306
+ out_stream = ""
307
+ @run.output_port("OUT").value(range) do |chunk|
308
+ out_stream += chunk
309
+ end
310
+ assert_equal data, out_stream
380
311
 
381
- # Stream just the first 10 bytes.
382
- stream = ""
383
- run.output_port("OUT").value(0...10) do |chunk|
384
- stream += chunk
385
- end
386
- assert_equal(stream, "123456789\n")
312
+ assert_requested out, :times => 1
313
+ end
387
314
 
388
- # Get just the second 10 bytes.
389
- assert_equal(run.output_port("OUT").value(10...20),
390
- "223456789\n")
315
+ def test_output_list
316
+ output_0_ref = "wd/out/OUT/1"
317
+ output_0_value = "String0"
318
+ output_4_ref = "wd/out/OUT/5.error"
319
+ output_4_value = "Processor 'Sometimes_Fails' - Port 'out': Line 6: java.lang.RuntimeException: Fails every four runs!\n"
320
+ status = mock("#{RUN_PATH}/status", :accept => "text/plain",
321
+ :status => 200, :credentials => $userinfo, :body => "Finished")
322
+ out = mock("#{RUN_PATH}/output", :accept => "application/xml",
323
+ :credentials => $userinfo,
324
+ :output => "get-rest-run-output-list-errors.raw")
325
+ out_0 = mock("#{RUN_PATH}/#{output_0_ref}", :status => 200,
326
+ :accept => "application/octet-stream", :credentials => $userinfo,
327
+ :body => output_0_value)
328
+ out_4 = mock("#{RUN_PATH}/#{output_4_ref}", :status => 200,
329
+ :accept => "application/octet-stream", :credentials => $userinfo,
330
+ :body => output_4_value)
331
+
332
+ output = @run.output_port("OUT")
333
+
334
+ assert_equal 1, output.depth
335
+ assert_equal 40, output.size.length
336
+ assert_equal 40, output.type.length
337
+ assert_equal 40, output.reference.length
338
+
339
+ assert_equal output_0_value.size, output[0].size
340
+ assert_equal "text/plain", output[0].type
341
+ assert_equal "https://localhost/taverna#{RUN_PATH}/#{output_0_ref}",
342
+ output[0].reference.to_s
343
+ assert_equal output_0_value, output[0].value
344
+
345
+ output_0_stream = TestCache.new
346
+ assert_equal output_0_value.size, output[0].stream_value(output_0_stream)
347
+ assert_equal output_0_value, output_0_stream.data
348
+
349
+ assert_equal output_4_value.size, output[4].size
350
+ assert_equal "application/x-error", output[4].type
351
+ assert_equal "https://localhost/taverna#{RUN_PATH}/#{output_4_ref}",
352
+ output[4].reference.to_s
353
+ assert_equal output_4_value, output[4].value
354
+
355
+ output_4_stream = TestCache.new
356
+ assert_equal output_4_value.size, output[4].stream_value(output_4_stream)
357
+ assert_equal output_4_value, output_4_stream.data
358
+
359
+ assert_requested status, :times => 1
360
+ assert_requested out, :times => 1
361
+ end
391
362
 
392
- # Stream the first 20 bytes.
393
- stream = ""
394
- run.output_port("OUT").value(0...20) do |chunk|
395
- stream += chunk
363
+ def test_log
364
+ log = mock("#{RUN_PATH}/wd/logs/detail.log", :accept => "text/plain",
365
+ :status => 200, :credentials => $userinfo,
366
+ :body => mocked_file("log.txt"))
367
+
368
+ # Should be an error if a parameter and a block are passed in here.
369
+ assert_raise(ArgumentError) do
370
+ @run.log("log.txt") do |chunk|
371
+ # ...
396
372
  end
397
- assert_equal(stream, "123456789\n223456789\n")
373
+ end
398
374
 
399
- # Get a bad range - should return the first 10 bytes.
400
- assert_equal(run.output_port("OUT").value(-10...10),
401
- "123456789\n")
375
+ assert_nothing_raised(ArgumentError) do
376
+ log_str = @run.log
402
377
 
403
- # Stream the lot and check total length. There should be two chunks.
404
- stream = ""
405
- run.output_port("OUT").value do |chunk|
406
- stream += chunk
407
- end
408
- assert_equal(stream.length, 100)
409
-
410
- # Now get the lot and check its size.
411
- out = run.output_port("OUT").value
412
- assert_equal(out.length, 100)
413
-
414
- # test streaming provenance data
415
- if run.server.version >= "2.5.3"
416
- assert_nothing_raised(T2Server::AccessForbiddenError) do
417
- prov_cache = TestCache.new
418
- prov_size = run.provenance(prov_cache)
419
- assert_not_equal(prov_size, 0)
420
- assert_not_equal(prov_cache.data, "")
421
- end
422
- else
423
- assert_raise(T2Server::AccessForbiddenError) do
424
- prov_cache = TestCache.new
425
- prov_size = run.provenance(prov_cache)
426
- assert_equal(prov_size, 0)
427
- assert_equal(prov_cache.data, "")
428
- end
378
+ assert_not_equal(log_str, "")
379
+
380
+ log_stream = ""
381
+ @run.log do |chunk|
382
+ log_stream += chunk
429
383
  end
384
+ assert_equal log_str, log_stream
430
385
 
431
- assert(run.delete)
386
+ log_cache = TestCache.new
387
+ @run.log(log_cache)
388
+ assert_not_equal 0, log_cache.size
389
+ assert_equal log_str, log_cache.data
432
390
  end
391
+
392
+ assert_requested log, :times => 3
433
393
  end
434
394
 
435
- # test error handling
436
- def test_always_fail
437
- T2Server::Run.create($uri, $wkf_fail, $creds, $conn_params) do |run|
438
- run.start
439
- run.wait
440
- assert_not_nil(run.output_port("OUT").value)
441
- assert(run.output_port("OUT").error?)
442
- assert(run.delete)
395
+ def test_create_start_finish_times
396
+ %w(create start finish).each do |time|
397
+ mock("#{RUN_PATH}/#{time}Time", :accept => "text/plain", :body => TIME_RET,
398
+ :credentials => $userinfo)
399
+
400
+ t = @run.send("#{time}_time".to_sym)
401
+ assert t.instance_of?(Time)
402
+ assert TIME_STR, t.to_s
443
403
  end
444
404
  end
445
405
 
446
- def test_errors
447
- T2Server::Run.create($uri, $wkf_errors, $creds, $conn_params) do |run|
448
- run.start
449
- assert(!run.error?)
450
- run.wait
451
- assert_not_nil(run.output_port("OUT").value)
452
- assert(run.output_port("OUT").error?)
453
- assert(run.error?)
454
- assert(run.delete)
406
+ def test_bad_state
407
+ # Re-mock status to fake up an already running run.
408
+ status = mock("#{RUN_PATH}/status", :accept => "text/plain",
409
+ :status => 200, :credentials => $userinfo, :body => "Operating")
410
+
411
+ assert_raise(T2Server::RunStateError) do
412
+ @run.start
455
413
  end
456
414
  end
415
+
416
+ def test_upload_file
417
+ filename = "in.txt"
418
+ mock("#{RUN_PATH}/wd/#{filename}", :method => :put, :accept => "*/*",
419
+ :status => 201, :credentials => $userinfo,
420
+ :location => "https://localhost/taverna#{RUN_PATH}/wd/#{filename}")
421
+
422
+ file = @run.upload_file("test/workflows/#{filename}")
423
+
424
+ assert_equal filename, file
425
+ end
426
+
427
+ def test_upload_data
428
+ filename = "in.txt"
429
+ location = "https://localhost/taverna#{RUN_PATH}/wd/#{filename}"
430
+ data = File.new("test/workflows/#{filename}")
431
+
432
+ mock("#{RUN_PATH}/wd/#{filename}", :method => :put, :accept => "*/*",
433
+ :status => 201, :credentials => $userinfo, :location => location)
434
+
435
+ file = @run.upload_data(data, filename)
436
+
437
+ assert_equal location, file.to_s
438
+ end
439
+
457
440
  end