t2-server 0.9.3 → 1.0.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.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright (c) 2010-2012 The University of Manchester, UK.
2
+ # Copyright (c) 2010-2013 The University of Manchester, UK.
3
3
  #
4
4
  # All rights reserved.
5
5
  #
@@ -39,18 +39,18 @@ include T2Server::CLI
39
39
  # set up options
40
40
  inputs = {}
41
41
  files = {}
42
- options = {}
43
- conn_params, creds = register_options("Usage: t2-run-workflow [options] " +
42
+ options = {:screds => [], :interactions => :show}
43
+ conn_params, creds = register_options("Usage: t2-run-workflow [options] "\
44
44
  "server-address") do |opt|
45
45
  opt.separator " Where server-address is the full URI of the server to"
46
46
  opt.separator " connect to, e.g.: http://example.com:8080/taverna"
47
47
  opt.separator " and [options] can be:"
48
- opt.on("-w WORKFLOW", "--workflow=WORKFLOW", "The workflow to run. If " +
49
- "this is not specified then the workflow is read from standard " +
48
+ opt.on("-w WORKFLOW", "--workflow=WORKFLOW", "The workflow to run. If "\
49
+ "this is not specified then the workflow is read from standard "\
50
50
  "input") do |val|
51
51
  options[:wkf_file] = val.chomp
52
52
  end
53
- opt.on("-i INPUT:VALUE", "--input=INPUT:VALUE", "Set input port INPUT to " +
53
+ opt.on("-i INPUT:VALUE", "--input=INPUT:VALUE", "Set input port INPUT to "\
54
54
  "VALUE") do |val|
55
55
  input, value = val.chomp.split(':', 2)
56
56
  inputs[input] = value
@@ -60,35 +60,78 @@ conn_params, creds = register_options("Usage: t2-run-workflow [options] " +
60
60
  input, filename = val.chomp.split(':', 2)
61
61
  files[input] = filename
62
62
  end
63
- opt.on("-e EXPIRY", "--expiry=EXPIRY", "Set the expiry date/time of this " +
63
+ opt.on("-I LEVEL", "--interactions=LEVEL", "Show, open or ignore any "\
64
+ "workflow interactions. LEVEL can be 'show' (the default), which simply "\
65
+ "lists the interaction URI in the terminal; 'open', which will open the "\
66
+ "interaction in a Web browser; or 'none', which will not check for "\
67
+ "interactions from the workflow at all. This should only be set to "\
68
+ "'none' if you are sure the workflow has no interactions or if you will "\
69
+ "be handling them in some other way.") do |val|
70
+ levels = [:show, :open, :none]
71
+ level = val.downcase.to_sym
72
+ options[:interactions] = levels.include?(level) ? level : :show
73
+ end
74
+ opt.on("-e EXPIRY", "--expiry=EXPIRY", "Set the expiry date/time of this "\
64
75
  "run") do |val|
65
76
  options[:expiry] = Time.parse(val.chomp)
66
77
  end
67
- opt.on("-b BACLAVA", "--baclava-in=BACLAVA", "Set baclava file for input " +
78
+ opt.on("-N NAME", "--name=NAME", "Give this run a name. Supported in "\
79
+ "Taverna Server versions 2.5.0 and up") do |val|
80
+ options[:name] = val.chomp
81
+ end
82
+ opt.on("-c URI::USER:PASS", "--credential=URI::USER:PASS",
83
+ "Provide a credential for a secure remote service. NOTE :: between URI "\
84
+ "and credential") do |val|
85
+ uri, cred = val.chomp.split('::', 2)
86
+ user, pass = cred.chomp.split(':', 2)
87
+ options[:screds] << [uri, user, pass]
88
+ end
89
+ opt.on("-b BACLAVA", "--baclava-in=BACLAVA", "Set baclava file for input "\
68
90
  "port values") do |val|
69
91
  inputs[:baclava] = val
70
92
  end
71
- opt.on("-o", "--baclava-out=BACLAVA", "Return outputs in baclava format." +
93
+ opt.on("-o", "--baclava-out=BACLAVA", "Return outputs in baclava format."\
72
94
  " A filename may be specified or 'out.xml' is used") do |val|
73
95
  options[:baclava_out] = val.chomp
74
96
  end
75
- opt.on("-n", "--no-wait", "Do not wait for workflow to finish, return " +
97
+ opt.on("-n", "--no-wait", "Do not wait for workflow to finish, return "\
76
98
  "once it has started running") do |val|
77
99
  options[:no_wait] = true
78
100
  end
79
- opt.on("-r", "--output-refs", "Return URIs that point to the data items " +
101
+ opt.on("-r", "--output-refs", "Return URIs that point to the data items "\
80
102
  "of the output rather than the data items themselves.") do |val|
81
103
  options[:output_refs] = val
82
104
  end
83
- opt.on("-D", "--delete", "Delete the run from the server when it is " +
84
- "complete. By default the run and its results are preserved. Note that " +
105
+ opt.on("-D", "--delete", "Delete the run from the server when it is "\
106
+ "complete. By default the run and its results are preserved. Note that "\
85
107
  "the run will still be deleted when its expiry time is reached") do |val|
86
108
  options[:delete] = val
87
109
  end
88
- opt.on("-z", "--zip=FILE", "Get the entire working directory of the run " +
110
+ opt.on("-z", "--zip=FILE", "Get the entire working directory of the run "\
89
111
  "in zip format and save it to the provided filename.") do |val|
90
112
  options[:zip_out] = val.chomp
91
113
  end
114
+ opt.on("-x", "--exitcode", "Return the exitcode of the run.") do
115
+ options[:exitcode] = true
116
+ end
117
+ opt.on("--stderr", 'Return the "standard error" output of the run.') do
118
+ options[:stderr] = true
119
+ end
120
+ opt.on("--stdout", 'Return the "standard out" output of the run.') do
121
+ options[:stdout] = true
122
+ end
123
+ end
124
+
125
+ if options[:interactions] == :open
126
+ begin
127
+ require 'launchy'
128
+ rescue LoadError
129
+ puts "\n****\nTo support opening interactions in your Web browser the "\
130
+ "launchy gem must be installed:\n\n$ gem install launchy\n\n"\
131
+ "Interaction URIs will be listed here instead. Please copy and paste "\
132
+ "them into your Web browser to display them.\n****\n\n"
133
+ options[:interactions] = :show
134
+ end
92
135
  end
93
136
 
94
137
  # read and check server address
@@ -107,6 +150,12 @@ begin
107
150
  puts "Created run with identifier: #{run.identifier}"
108
151
  puts "Created at #{run.create_time}"
109
152
 
153
+ # set run name
154
+ if options[:name]
155
+ run.name = options[:name]
156
+ puts "Run name set to '#{run.name}'"
157
+ end
158
+
110
159
  # set run expiry
111
160
  if options[:expiry]
112
161
  run.expiry=(options[:expiry])
@@ -135,43 +184,56 @@ begin
135
184
  end
136
185
  end
137
186
 
187
+ # set remote service credentials
188
+ options[:screds].each do |list|
189
+ run.add_password_credential(list[0], list[1], list[2])
190
+ end
191
+
138
192
  # output baclava?
139
193
  run.request_baclava_output if options[:baclava_out]
140
194
 
141
- # start run and wait until it is finished
142
- run.start
195
+ # try to start run
196
+ unless run.start
197
+ puts "Run could not be started because the server is already running "\
198
+ "its configured maximum number of runs. Please try again later."
199
+ run.delete
200
+ exit 1
201
+ end
143
202
  puts "Started at #{run.start_time}"
144
203
 
145
204
  # bail out if user doesn't want to wait
146
205
  exit 0 if options[:no_wait]
147
206
 
148
- # otherwise wait
149
- print "Running"
207
+ # otherwise wait, but list or open notifications if there are any
208
+ print "Running."
150
209
  until run.finished?
151
210
  sleep(1)
211
+ unless options[:interactions] == :none
212
+ run.notifications(:new_requests).each do |note|
213
+ if options[:interactions] == :open
214
+ Launchy.open note.uri
215
+ else
216
+ puts "\n#{note.uri}\n"
217
+ end
218
+ end
219
+ end
152
220
  print "."
153
221
  $stdout.flush
154
222
  end
155
223
  puts "\nFinished at #{run.finish_time}"
156
224
 
157
225
  # get outputs
158
- stdout = run.stdout
159
- stderr = run.stderr
160
226
  exitcd = run.exitcode
161
- puts "Exitcode: #{exitcd}"
162
- if stdout != "" then puts "Stdout:\n#{stdout}" end
163
- if stderr != "" then puts "Stderr:\n#{stderr}" end
227
+ puts "Exitcode: #{exitcd}" if options[:exitcode] || exitcd != 0
228
+ puts "Stdout:\n#{run.stdout}" if options[:stdout]
229
+ puts "Stderr:\n#{run.stderr}" if options[:stderr]
164
230
 
165
231
  if exitcd == 0
166
232
  if options[:baclava_out]
167
- File.open(options[:baclava_out], "w") do |file|
168
- file.syswrite(run.baclava_output)
169
- end
233
+ run.baclava_output(options[:baclava_out])
170
234
  puts "Baclava file written to '#{options[:baclava_out]}'"
171
235
  elsif options[:zip_out]
172
- File.open(options[:zip_out],"w") do |file|
173
- file.syswrite(run.zip_output)
174
- end
236
+ run.zip_output(options[:zip_out])
175
237
  puts "Zip file written to '#{options[:zip_out]}'"
176
238
  else
177
239
  # go through the outputs and print them out
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Copyright (c) 2010-2012 The University of Manchester, UK.
2
+ # Copyright (c) 2010-2013 The University of Manchester, UK.
3
3
  #
4
4
  # All rights reserved.
5
5
  #
@@ -38,15 +38,16 @@ require 'hirb'
38
38
  include T2Server::CLI
39
39
 
40
40
  # set up options
41
- options = {}
41
+ options = { :list => 0 }
42
42
  conn_params, creds = register_options("Usage: t2-server-info [options] " +
43
43
  "server-address") do |opt|
44
44
  opt.separator " Where server-address is the full URI of the server to"
45
45
  opt.separator " connect to, e.g.: http://example.com:8080/taverna"
46
46
  opt.separator " and [options] can be:"
47
47
 
48
- opt.on("-l", "--list", "List details for the runs on this server.") do
49
- options[:list] = true
48
+ opt.on("-l", "--list", "List details for the runs on this server. Repeat "\
49
+ "(e.g. -ll or -lll) to increase the amount of detail shown.") do
50
+ options[:list] += 1
50
51
  end
51
52
  end
52
53
 
@@ -61,14 +62,30 @@ begin
61
62
  puts " Run limit: #{server.run_limit(creds)}"
62
63
  runs = server.runs(creds)
63
64
  puts "No. of runs: #{runs.length}"
64
- if options[:list] && runs.length > 0
65
- puts (Hirb::Helpers::ObjectTable.render runs,
66
- :fields=>[:identifier, :status, :expiry],
67
- :headers=>{:identifier=>'Run ID', :status=>'Status',
68
- :expiry=>'Expiry time (local)'},
69
- :filters=>{:expiry=>[:strftime, "%H:%M:%S %d/%m/%Y"]},
70
- :max_fields=>{:expiry=>19},
71
- :description=>false)
65
+ if options[:list] > 0 && runs.length > 0
66
+ if options[:list] == 1
67
+ fields = [:identifier]
68
+ headers = {:identifier => 'Run ID'}
69
+ lengths = {}
70
+ elsif options[:list] == 2
71
+ fields = [:identifier, :status, :expiry]
72
+ headers = {:identifier => 'Run ID', :status => 'Status',
73
+ :expiry => 'Expiry time (local)'}
74
+ lengths = {:status => 11, :expiry => 19}
75
+ else
76
+ fields = [:identifier, :name, :status, :expiry]
77
+ headers = {:identifier => 'Run ID', :name => "Name",
78
+ :status => 'Status', :expiry => 'Expiry time (local)'}
79
+ lengths = {:identifier => 11, :name => 25, :status => 11,
80
+ :expiry => 19}
81
+ end
82
+
83
+ puts Hirb::Helpers::ObjectTable.render(runs,
84
+ :fields => fields,
85
+ :headers => headers,
86
+ :filters => {:expiry => [:strftime, "%H:%M:%S %d/%m/%Y"]},
87
+ :max_fields => lengths,
88
+ :description => false)
72
89
  end
73
90
  end
74
91
  rescue RuntimeError => e
@@ -0,0 +1,184 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright (c) 2010-2013 The University of Manchester, UK.
3
+ #
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ #
9
+ # * Redistributions of source code must retain the above copyright notice,
10
+ # this list of conditions and the following disclaimer.
11
+ #
12
+ # * Redistributions in binary form must reproduce the above copyright notice,
13
+ # this list of conditions and the following disclaimer in the documentation
14
+ # and/or other materials provided with the distribution.
15
+ #
16
+ # * Neither the names of The University of Manchester nor the names of its
17
+ # contributors may be used to endorse or promote products derived from this
18
+ # software without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ # POSSIBILITY OF SUCH DAMAGE.
31
+ #
32
+ # Author: Robert Haines
33
+
34
+ require 'rubygems'
35
+ require 't2-server-cli'
36
+ require 'hirb'
37
+
38
+ include T2Server::CLI
39
+
40
+ # Set up options and workflow inputs.
41
+ inputs = {}
42
+ files = {}
43
+ options = {:number => 5, :backoff => 0, :screds => []}
44
+ conn_params, creds = register_options("Usage: t2-server-stress [options] "\
45
+ "server-address") do |opt|
46
+ opt.separator " Where server-address is the full URI of the server to"
47
+ opt.separator " connect to, e.g.: http://example.com:8080/taverna"
48
+ opt.separator " and [options] can be:"
49
+
50
+ opt.on("-n NUMBER", "--number=NUMBER", "Number of concurrent runs. "\
51
+ "Default 5") do |val|
52
+ options[:number] = val.chomp.to_i
53
+ end
54
+ opt.on("-b NUMBER", "--backoff=NUMBER", "Time (in seconds) to back off "\
55
+ "before starting next run. Default 0") do |val|
56
+ options[:backoff] = val.chomp.to_i
57
+ end
58
+ opt.on("-w WORKFLOW", "--workflow=WORKFLOW", "The workflow to run. If "\
59
+ "this is not specified then the workflow is read from standard "\
60
+ "input") do |val|
61
+ options[:wkf_file] = val.chomp
62
+ end
63
+ opt.on("-i INPUT:VALUE", "--input=INPUT:VALUE", "Set input port INPUT to "\
64
+ "VALUE") do |val|
65
+ input, value = val.chomp.split(':', 2)
66
+ inputs[input] = value
67
+ end
68
+ opt.on("-f INPUT:FILE", "--input-file=INPUT:FILE",
69
+ "Set input port INPUT to use the contents of FILE as its input") do |val|
70
+ input, filename = val.chomp.split(':', 2)
71
+ files[input] = filename
72
+ end
73
+ opt.on("-K", "--keep-runs",
74
+ "Do not delete the runs at the end of the test") do
75
+ options[:keep] = true
76
+ end
77
+ opt.on("-c URI::USER:PASS", "--credential=URI::USER:PASS",
78
+ "Provide a credential for a secure remote service. NOTE :: between URI "\
79
+ "and credential") do |val|
80
+ uri, cred = val.chomp.split('::', 2)
81
+ user, pass = cred.chomp.split(':', 2)
82
+ options[:screds] << [uri, user, pass]
83
+ end
84
+ end
85
+
86
+ # Read and check server address and credentials.
87
+ uri, creds = parse_address(ARGV.shift, creds)
88
+
89
+ # Read workflow and ensure that it is not empty.
90
+ if options[:wkf_file]
91
+ wkf = IO.read(options[:wkf_file])
92
+ else
93
+ wkf = ARGF.read
94
+ end
95
+ exit 1 if wkf == ""
96
+
97
+ # Connect to server and check it's in a good state.
98
+ server = T2Server::Server.new(uri, conn_params)
99
+ puts "\nConnected to server at #{server.uri}"
100
+
101
+ current_runs = server.runs(creds)
102
+ unless current_runs.length == 0
103
+ puts "\nServer already has runs on it. Please clear out all runs before "\
104
+ "running the stress tests."
105
+ exit 1
106
+ end
107
+
108
+ run_limit = server.run_limit(creds)
109
+ unless run_limit >= options[:number]
110
+ puts "\nYou have asked for more concurrent runs than this server has been "\
111
+ "configured to allow. Please set the number to #{run_limit} or less."
112
+ exit 1
113
+ end
114
+
115
+ puts "\nInitializing #{options[:number]} runs and setting inputs."
116
+ runs = []
117
+ options[:number].times do
118
+ server.create_run(wkf, creds) do |run|
119
+ # Set inputs.
120
+ run.input_ports.each_value do |port|
121
+ input = port.name
122
+ if inputs.include? input
123
+ port.value = inputs[input]
124
+ elsif files.include? input
125
+ port.file = files[input]
126
+ else
127
+ puts "Input '#{input}' has not been given, exiting."
128
+ run.delete
129
+ exit 1
130
+ end
131
+ end
132
+
133
+ options[:screds].each do |list|
134
+ run.add_password_credential(list[0], list[1], list[2])
135
+ end
136
+
137
+ runs << run
138
+ end
139
+ end
140
+
141
+ puts "\nStarting runs with #{options[:backoff]} seconds back-off time between."
142
+
143
+ w_start = Time.now
144
+ runs.each do |run|
145
+ r_start = Time.now
146
+ while !run.start
147
+ puts "Server has reached configured maximum of concurrently running "\
148
+ "runs. Backing off for 10 seconds before retrying..."
149
+ sleep(10)
150
+ end
151
+ r_started = Time.now
152
+ puts "Run started at #{r_started} and took #{r_started - r_start} seconds to start."
153
+ sleep options[:backoff] if options[:backoff] > 0
154
+ end
155
+
156
+ puts "\nWaiting for runs to finish."
157
+
158
+ while runs.count { |run| run.finished? } < options[:number] do
159
+ sleep(5)
160
+ end
161
+ w_end = Time.now
162
+
163
+ puts "\nRuns finished.\n\nRun times:"
164
+
165
+ total = 0
166
+ runs.each do |run|
167
+ time = run.finish_time - run.start_time
168
+ total += time
169
+ puts time
170
+ end
171
+
172
+ average = total / options[:number]
173
+ puts "\nAverage time: #{average}"
174
+ w_time = w_end - w_start
175
+ puts "Wallclock time: #{w_time}"
176
+
177
+ unless options[:keep]
178
+ puts "\nDeleting runs."
179
+ runs.each do |run|
180
+ run.delete
181
+ end
182
+ end
183
+
184
+ puts "\nDone."