t2-server 1.1.0 → 1.2.0

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