ruby-cute 0.12 → 0.24

Sign up to get free protection for your applications and to get access to all the features.
data/lib/cute/g5k_api.rb CHANGED
@@ -24,7 +24,7 @@ module Cute
24
24
  # - {Cute::G5K::Unauthorized} it means that there is an authentication problem.
25
25
  # - {Cute::G5K::EventTimeout} this exception is triggered by the methods that wait for events such as:
26
26
  # job submission and environment deployment.
27
- class Error < Exception
27
+ class Error < StandardError
28
28
  attr_accessor :orig # Original exception
29
29
 
30
30
  def initialize(message = nil, object = nil)
@@ -63,6 +63,7 @@ module Cute
63
63
  #
64
64
  # end
65
65
  class BadRequest < Error
66
+ attr_accessor :inner_url, :inner_code, :inner_title, :inner_message
66
67
  end
67
68
 
68
69
  # It wraps all Restclient exceptions with http codes: 403, 405,406, 412, 415, 500, 502, 503 and 504.
@@ -205,7 +206,8 @@ module Cute
205
206
  # @param user [String] user if authentication is needed
206
207
  # @param pass [String] password if authentication is needed
207
208
  # @param on_error [Symbol] option to deactivate the {Cute::G5K::RequestFailed RequestFailed} exceptions
208
- def initialize(uri,api_version,user,pass,on_error)
209
+ # @param timeout [Integer] timeout for Rest request
210
+ def initialize(uri,api_version,user,pass,on_error,timeout)
209
211
  @user = user
210
212
  @pass = pass
211
213
  @api_version = api_version.nil? ? "stable" : api_version
@@ -217,9 +219,8 @@ module Cute
217
219
  @endpoint = "https://#{user_escaped}:#{pass_escaped}@#{uri.split("https://")[1]}"
218
220
  end
219
221
 
220
- machine =`uname -ov`.chop
221
222
  @user_agent = "ruby-cute/#{VERSION} Ruby/#{RUBY_VERSION}"
222
- @api = RestClient::Resource.new(@endpoint, :timeout => 30,:verify_ssl => false)
223
+ @api = RestClient::Resource.new(@endpoint, :timeout => timeout,:verify_ssl => false)
223
224
  # some versions of restclient do not verify by default SSL certificates , :verify_ssl => true)
224
225
  # SSL verify is disabled due to Grid'5000 API certificate problem
225
226
  @on_error = on_error
@@ -239,6 +240,12 @@ module Cute
239
240
  # @return [Hash] the HTTP response
240
241
  # @param path [String] this complements the URI to address to a specific resource
241
242
  def get_json(path)
243
+ return G5KJSON.parse(get_raw(path))
244
+ end
245
+
246
+ # @return [String] the HTTP response
247
+ # @param path [String] this complements the URI to address to a specific resource
248
+ def get_raw(path)
242
249
  retries = 0
243
250
  begin
244
251
  r = resource(path).get(:content_type => "application/json",
@@ -253,7 +260,7 @@ module Cute
253
260
  end
254
261
  handle_exception(e)
255
262
  end
256
- return G5KJSON.parse(r)
263
+ return r
257
264
  end
258
265
 
259
266
  # Creates a resource on the server
@@ -314,7 +321,7 @@ module Cute
314
321
  end
315
322
 
316
323
  # Issues a Cute::G5K exception according to the http status code
317
- def handle_exception(e, req = nil)
324
+ def handle_exception(e, _req = nil)
318
325
  puts("Error: #{$!}")
319
326
  puts("Backtrace:\n\t"+e.backtrace.join("\n\t"))
320
327
  if e.respond_to? :http_code
@@ -332,11 +339,24 @@ module Cute
332
339
  case e.http_code
333
340
 
334
341
  when 400
335
- raise BadRequest.new("Bad request", e)
342
+ br = BadRequest.new("Bad request (error 400): #{e.http_body}", e)
343
+ if e.http_body =~ /^Request to ([^ ]*) failed with status 400: (.*)$/m
344
+ br.inner_url = $1
345
+ json = $2
346
+ begin
347
+ d = JSON::parse(json)
348
+ br.inner_code = d['code']
349
+ br.inner_title = d['title']
350
+ br.inner_message = d['message']
351
+ rescue JSON::ParserError
352
+ # Ignore error
353
+ end
354
+ end
355
+ raise br
336
356
  when 404
337
- raise NotFound.new("Resource not found", e)
357
+ raise NotFound.new("Resource not found (error 404): #{e.http_body}", e)
338
358
  when 401
339
- raise Unauthorized.new("Authentication problem",e)
359
+ raise Unauthorized.new("Authentication problem (error 401): #{e.http_body}",e)
340
360
  else
341
361
  if @on_error == :ignore
342
362
  return nil
@@ -549,6 +569,7 @@ module Cute
549
569
  # @option params [String] :password Password to access the REST API
550
570
  # @option params [Symbol] :on_error Set to :ignore if you want to ignore {Cute::G5K::RequestFailed ResquestFailed} exceptions.
551
571
  # @option params [Boolean] :debug Activate the debug mode
572
+ # @option params [Integer] :timeout Set the timeout in sec, default is 30 sec
552
573
  def initialize(params={})
553
574
  config = {}
554
575
  default_file = "#{ENV['HOME']}/.grid5000_api.yml"
@@ -567,9 +588,10 @@ module Cute
567
588
  @api_version = params[:version] || config["version"] || "stable"
568
589
  @logger = nil
569
590
  @debug = params[:debug] || false
591
+ @timeout = params[:timeout] || 30
570
592
 
571
593
  begin
572
- @g5k_connection = G5KRest.new(@uri,@api_version,@user,@pass,params[:on_error])
594
+ @g5k_connection = G5KRest.new(@uri,@api_version,@user,@pass,params[:on_error], @timeout)
573
595
  rescue => e
574
596
 
575
597
  msg_create_file = ""
@@ -695,7 +717,9 @@ module Cute
695
717
  # @param site [String] a valid Grid'5000 site name
696
718
  # @param uid [String] user name in Grid'5000
697
719
  # @param states [Array] or [String] jobs state: running, waiting (multiple states can be specified)
698
- def get_jobs(site, uid = nil, states = nil)
720
+ # @param details [String] pass "resources=yes to the query to get the list of resources
721
+ # @param recurse [String] after fetching the list of jobs, fetch details about each job individualy
722
+ def get_jobs(site, uid = nil, states = nil, details = false, recurse = true)
699
723
 
700
724
  parameters = []
701
725
  if states then
@@ -703,12 +727,18 @@ module Cute
703
727
  parameters.push("state=#{states.join(",")}")
704
728
  end
705
729
  parameters.push("user=#{uid}") if uid
706
- parameters.push("limit=25") if (states.nil? and uid.nil?)
730
+ parameters.push("limit=1000000")
731
+ parameters.push("resources=yes") if details
707
732
 
733
+ info(debug_cmd(api_uri("/sites/#{site}/jobs?#{parameters.join("&")}"),"GET"), :debug)
708
734
  jobs = @g5k_connection.get_json(api_uri("/sites/#{site}/jobs?#{parameters.join("&")}")).items
709
- jobs.map{ |j| @g5k_connection.get_json(j.rel_self)}
710
- # This request sometime is could take a little long when all jobs are requested
711
- # The API return by default 50 the limit was set to 25 (e.g., 23 seconds).
735
+ if recurse
736
+ jobs.map! do |j|
737
+ info(debug_cmd(j.rel_self, "GET"), :debug)
738
+ @g5k_connection.get_json(j.rel_self)
739
+ end
740
+ end
741
+ jobs.to_a
712
742
  end
713
743
 
714
744
  # @return [Hash] the last 50 deployments performed in a Grid'5000 site
@@ -970,6 +1000,7 @@ module Cute
970
1000
  # @option opts [String] :cmd The command to execute when the job starts (e.g. ./my-script.sh).
971
1001
  # @option opts [String] :cluster Valid Grid'5000 cluster
972
1002
  # @option opts [String] :queue A specific job queue
1003
+ # @option opts [String] :project A specific OAR project
973
1004
  # @option opts [Array] :subnets 1) prefix_size, 2) number of subnets
974
1005
  # @option opts [String] :env Environment name for {http://kadeploy3.gforge.inria.fr/ Kadeploy}
975
1006
  # @option opts [String] :vlan VLAN type and number: kavlan-local, kavlan, kavlan-topo, etc
@@ -984,12 +1015,12 @@ module Cute
984
1015
  # checking valid options
985
1016
  valid_opts = [:site, :cluster, :switches, :cpus, :cores, :nodes, :walltime, :cmd,
986
1017
  :type, :name, :subnets, :env, :vlan, :num_vlan,:properties, :resources,
987
- :reservation, :wait, :keys, :queue, :env_user]
1018
+ :reservation, :wait, :keys, :queue, :project, :env_user]
988
1019
  unre_opts = opts.keys - valid_opts
989
1020
  raise ArgumentError, "Unrecognized option #{unre_opts}" unless unre_opts.empty?
990
1021
 
991
1022
  nodes = opts.fetch(:nodes, 1)
992
- walltime = opts.fetch(:walltime, '01:00:00')
1023
+ walltime = opts[:walltime]
993
1024
  site = opts[:site]
994
1025
  type = opts.fetch(:type, [])
995
1026
  name = opts.fetch(:name, 'rubyCute job')
@@ -1007,6 +1038,7 @@ module Cute
1007
1038
  type = [type] if type.is_a?(Symbol)
1008
1039
  keys = opts[:keys]
1009
1040
  queue = opts[:queue]
1041
+ project = opts[:project]
1010
1042
  vlan = opts[:vlan]
1011
1043
  num_vlan = opts.fetch(:num_vlan, 1)
1012
1044
 
@@ -1021,14 +1053,11 @@ module Cute
1021
1053
  raise ArgumentError, "VLAN type not available in site #{site}" unless available_vlans.include?(vlan)
1022
1054
  end
1023
1055
 
1024
- raise 'At least nodes, time and site must be given' if [nodes, walltime, site].any? { |x| x.nil? }
1056
+ raise 'At least nodes and site must be given' if [nodes, site].any? { |x| x.nil? }
1025
1057
 
1026
- raise 'nodes should be an integer or a string containing either ALL or BEST' unless (nodes.is_a?(Fixnum) or ["ALL","BEST"].include?(nodes))
1058
+ raise 'nodes should be an integer or a string containing either ALL or BEST' unless (nodes.is_a?(Integer) or ["ALL","BEST"].include?(nodes))
1027
1059
 
1028
- secs = walltime.to_secs
1029
- walltime = walltime.to_time
1030
-
1031
- command = "sleep #{secs}" if command.nil?
1060
+ command = "sleep infinity" if command.nil?
1032
1061
 
1033
1062
  if resources == ""
1034
1063
  resources = "/switch=#{switches}" unless switches.nil?
@@ -1037,14 +1066,16 @@ module Cute
1037
1066
  resources += "/core=#{cores}" unless cores.nil?
1038
1067
 
1039
1068
  if cluster
1040
- resources = (cluster.is_a?(Fixnum) ? "/cluster=#{cluster}" : "{cluster='#{cluster}'}") + resources
1069
+ resources = (cluster.is_a?(Integer) ? "/cluster=#{cluster}" : "{cluster='#{cluster}'}") + resources
1041
1070
  end
1042
1071
 
1043
1072
  resources = "{type='#{vlan}'}/vlan=#{num_vlan}+" + resources unless vlan.nil?
1044
1073
  resources = "slash_#{subnets[0]}=#{subnets[1]}+" + resources unless subnets.nil?
1045
1074
  end
1046
1075
 
1047
- resources += ",walltime=#{walltime}" unless resources.include?("walltime")
1076
+ if walltime
1077
+ resources += ",walltime=#{walltime}" unless resources.include?("walltime")
1078
+ end
1048
1079
 
1049
1080
  payload = {
1050
1081
  'resources' => resources,
@@ -1052,12 +1083,13 @@ module Cute
1052
1083
  'command' => command
1053
1084
  }
1054
1085
 
1055
- info "Reserving resources: #{resources} (type: #{type}) (in #{site})"
1086
+ info "Reserving resources: #{resources} (types: #{type.join(' ')}) (in #{site})"
1056
1087
 
1057
1088
  payload['properties'] = properties unless properties.nil?
1058
1089
  payload['types'] = type.map{ |t| t.to_s} unless type.nil?
1059
1090
  type.map!{|t| t.to_sym} unless type.nil?
1060
1091
  payload['queue'] = queue if queue
1092
+ payload['project'] = project if project
1061
1093
 
1062
1094
  unless type.include?(:deploy)
1063
1095
  if opts[:keys]
@@ -1067,18 +1099,10 @@ module Cute
1067
1099
 
1068
1100
  if reservation
1069
1101
  payload['reservation'] = reservation
1070
- info "Starting this reservation at #{reservation}"
1071
1102
  end
1072
1103
 
1073
- begin
1074
- info debug_cmd(api_uri("sites/#{site}/jobs"),"POST",payload.to_json), :debug
1075
- r = @g5k_connection.post_json(api_uri("sites/#{site}/jobs"),payload) # This makes reference to the same class
1076
- rescue Error => e
1077
- info "Fail to submit job"
1078
- info e.message
1079
- e.http_body.split("\\n").each{ |line| info line}
1080
- raise
1081
- end
1104
+ info debug_cmd(api_uri("sites/#{site}/jobs"),"POST",payload.to_json), :debug
1105
+ r = @g5k_connection.post_json(api_uri("sites/#{site}/jobs"),payload) # This makes reference to the same class
1082
1106
 
1083
1107
  job = @g5k_connection.get_json(r.rel_self)
1084
1108
  job = wait_for_job(job) if opts[:wait] == true
@@ -1268,7 +1292,7 @@ module Cute
1268
1292
 
1269
1293
  job["deploy"].map!{ |d| d.refresh(@g5k_connection) }
1270
1294
 
1271
- filter.keep_if{ |k,v| v} # removes nil values
1295
+ filter.keep_if{ |_k,v| v} # removes nil values
1272
1296
  if filter.empty?
1273
1297
  status = job["deploy"].map{ |d| d["status"] }
1274
1298
  else
@@ -1346,7 +1370,7 @@ module Cute
1346
1370
  # @return [Array] machines that did not deploy successfully
1347
1371
  # @param deploy_info [Hash] deployment structure information
1348
1372
  def check_deployment(deploy_info)
1349
- deploy_info["result"].select{ |p,v| v["state"] == "KO"}.keys
1373
+ deploy_info["result"].select{ |_p,v| v["state"] == "KO"}.keys
1350
1374
  end
1351
1375
 
1352
1376
  # Returns a valid URI using the current G5K API version.
@@ -14,17 +14,18 @@ class Net::SSH::Connection::Session
14
14
  res[:stderr] = ""
15
15
  res[:exit_code] = nil
16
16
  res[:exit_signal] = nil
17
+ ts = Time::now
17
18
  open_channel do |channel|
18
- channel.exec(command) do |ch, success|
19
+ channel.exec(command) do |_ch, success|
19
20
  unless success
20
21
  abort "FAILED: couldn't execute command (ssh.channel.exec)"
21
22
  end
22
- channel.on_data do |ch,data|
23
+ channel.on_data do |_ch,data|
23
24
  print data unless o[:no_output]
24
25
  res[:stdout]+=data
25
26
  end
26
27
 
27
- channel.on_extended_data do |ch,type,data|
28
+ channel.on_extended_data do |_ch,_type,data|
28
29
  print data unless o[:no_output]
29
30
  if o[:merge_outputs]
30
31
  res[:stdout]+=data
@@ -33,14 +34,16 @@ class Net::SSH::Connection::Session
33
34
  end
34
35
  end
35
36
 
36
- channel.on_request("exit-status") do |ch,data|
37
+ channel.on_request("exit-status") do |_ch,data|
37
38
  res[:exit_code] = data.read_long
38
- puts "EXITCODE: #{res[:exit_code]}" unless o[:no_log]
39
+ d = sprintf("%.1f", Time::now - ts)
40
+ puts "EXITCODE: #{res[:exit_code]} (duration: #{d}s)" unless o[:no_log]
39
41
  end
40
42
 
41
- channel.on_request("exit-signal") do |ch, data|
43
+ channel.on_request("exit-signal") do |_ch, data|
42
44
  res[:exit_signal] = data.read_long
43
- puts "EXITSIGNAL: #{res[:exit_signal]}" unless o[:no_log]
45
+ d = sprintf("%.1f", Time::now - ts)
46
+ puts "EXITSIGNAL: #{res[:exit_signal]} (duration: #{d}s)" unless o[:no_log]
44
47
  end
45
48
  end
46
49
  end
data/lib/cute/net-ssh.rb CHANGED
@@ -115,7 +115,7 @@ module SessionActions
115
115
  Multi.logger.debug("[#{c.connection.host}] #{data.strip}")
116
116
  end
117
117
  end
118
- channel.on_extended_data do |c, type, data|
118
+ channel.on_extended_data do |c, _type, data|
119
119
  if block
120
120
  block.call(c, :stderr, data)
121
121
  else
@@ -129,7 +129,7 @@ module SessionActions
129
129
  results[c.connection.host][:status] = c[:exit_status]
130
130
  if c[:exit_status] != 0
131
131
  Multi.logger.info("execution of '#{command}' on #{c.connection.host}
132
- failed with return status #{c[:exit_status].to_s}")
132
+ failed with return status #{c[:exit_status]}")
133
133
  if results[c.connection.host][:stdout]
134
134
  Multi.logger.info("--- stdout dump ---")
135
135
  Multi.logger.info(results[c.connection.host][:stdout])
data/lib/cute/net.rb CHANGED
@@ -13,14 +13,12 @@ module Cute
13
13
  end
14
14
 
15
15
  def Network::wait_open_port(host, port, timeout = 120)
16
- def now()
17
- return Time.now.to_f
18
- end
19
- bound = now() + timeout
20
- while now() < bound do
21
- t = now()
16
+ now = -> { return Time.now.to_f }
17
+ bound = now.call + timeout
18
+ while now.call < bound do
19
+ t = now.call
22
20
  return true if port_open?(host, port)
23
- dt = now() - t
21
+ dt = now.call - t
24
22
  sleep(0.5 - dt) if dt < 0.5
25
23
  end
26
24
  return false
@@ -1,8 +1,6 @@
1
1
  module Cute
2
2
  module Synchronization
3
- require 'thread'
4
-
5
- class Semaphore
3
+ class Semaphore
6
4
  def initialize(max)
7
5
  @lock = Mutex.new
8
6
  @cond = ConditionVariable.new
data/lib/cute/taktuk.rb CHANGED
@@ -123,7 +123,6 @@ module Cute
123
123
  yield taktuk_cmd
124
124
  taktuk_cmd.loop unless taktuk_cmd.commands.empty?
125
125
  taktuk_cmd.free! if taktuk_cmd
126
- taktuk_cmd = nil
127
126
  end
128
127
  else
129
128
  return taktuk_cmd
@@ -372,9 +371,9 @@ module Cute
372
371
  def to_cmd
373
372
  self.inject([]) do |ret,val|
374
373
  if val =~ /^\[(.*)\]$/
375
- ret += ['[',Regexp.last_match(1).strip,']']
374
+ ret + ['[',Regexp.last_match(1).strip,']']
376
375
  else
377
- ret += val.split(' ')
376
+ ret + val.split(' ')
378
377
  end
379
378
  end
380
379
  end
@@ -417,7 +416,7 @@ module Cute
417
416
 
418
417
  @streams.types.each{ |name|
419
418
  @args << '-o'
420
- @args << "#{name.to_s}=#{@streams.to_cmd}"
419
+ @args << "#{name}=#{@streams.to_cmd}"
421
420
  }
422
421
 
423
422
  connector = build_connector
@@ -563,7 +562,7 @@ module Cute
563
562
  # tak.input(:file => "test_file.tar")
564
563
  def input(opts = {})
565
564
  mode = "broadcast"
566
- @commands << "#{mode} input #{opts.keys.first.to_s}"
565
+ @commands << "#{mode} input #{opts.keys.first}"
567
566
  @commands << "[ #{opts.values.first} ]"
568
567
  @commands << ';'
569
568
  end
data/lib/cute/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Cute
2
- VERSION = "0.12"
2
+ VERSION = "0.24"
3
3
  end
data/ruby-cute.gemspec CHANGED
@@ -5,9 +5,9 @@ require 'cute/version'
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "ruby-cute"
7
7
  s.version = Cute::VERSION
8
- s.authors = ["Algorille team"]
9
- s.email = "ruby-cute-staff@lists.gforge.inria.fr"
10
- s.homepage = "http://ruby-cute.gforge.inria.fr/"
8
+ s.authors = ["Algorille/Madynes/RESIST teams at Inria/LORIA"]
9
+ s.email = "lucas.nussbaum@inria.fr"
10
+ s.homepage = "http://ruby-cute.github.io/"
11
11
  s.summary = "Critically Useful Tools for Experiments"
12
12
  s.description = "Ruby library for controlling experiments"
13
13
  s.required_rubygems_version = ">= 1.3.6"
@@ -26,7 +26,10 @@ Gem::Specification.new do |s|
26
26
  s.add_dependency 'rest-client', '>= 1.6'
27
27
  s.add_dependency 'json', '>= 1.8'
28
28
  s.add_dependency 'ipaddress', '>= 0.8'
29
+ s.add_dependency 'net-ssh', '>= 3.2'
29
30
  s.add_dependency 'net-ssh-multi', '>= 1.2'
31
+ s.add_dependency 'net-scp', '>= 1.2'
32
+ s.add_dependency 'peach', '>= 0.5.1'
30
33
 
31
34
  s.extra_rdoc_files = ['README.md', 'LICENSE']
32
35
  s.license = 'CeCILL-B'
@@ -4,7 +4,7 @@ require 'spec_helper'
4
4
 
5
5
  describe Cute::G5K::API do
6
6
 
7
- subject { g5k = ENV['TEST_REAL'].nil?? Cute::G5K::API.new(:user => "test") : Cute::G5K::API.new() }
7
+ subject { ENV['TEST_REAL'].nil?? Cute::G5K::API.new(:user => "test") : Cute::G5K::API.new() }
8
8
 
9
9
  before :each do
10
10
  if ENV['TEST_REAL']
data/spec/g5k_api_spec.rb CHANGED
@@ -4,9 +4,9 @@ require 'spec_helper'
4
4
  describe Cute::G5K::API do
5
5
 
6
6
  if ENV['TEST_REAL']
7
- subject { g5k = ENV['DEBUG'].nil?? Cute::G5K::API.new() : Cute::G5K::API.new(:debug => true) }
7
+ subject { ENV['DEBUG'].nil?? Cute::G5K::API.new() : Cute::G5K::API.new(:debug => true) }
8
8
  else
9
- subject { g5k = ENV['DEBUG'].nil?? Cute::G5K::API.new(:user => "test") : Cute::G5K::API.new(:user => "test",:debug => true) }
9
+ subject { ENV['DEBUG'].nil?? Cute::G5K::API.new(:user => "test") : Cute::G5K::API.new(:user => "test",:debug => true) }
10
10
  end
11
11
 
12
12
  let(:sites) { subject.site_uids}
@@ -69,27 +69,20 @@ describe Cute::G5K::API do
69
69
  expect(subject.get_deployments(@rand_site)).to be_an_instance_of(Cute::G5K::G5KArray)
70
70
  end
71
71
 
72
+ =begin
72
73
  it "raises an authentication error" do
73
74
  expect{Cute::G5K::API.new(:user => "fake", :pass => "fake") }.to raise_error
74
75
  end
76
+ =end
75
77
 
76
- it "raises a non found error" do
77
- expect{subject.get_jobs("non-found")}.to raise_error(Cute::G5K::NotFound)
78
- end
79
-
80
- it "raises a bad request error" do
81
- expect{ subject.reserve(:site => @rand_site, :resources =>"/slash_22=1+{nonsense}")}.to raise_error(Cute::G5K::BadRequest)
82
- # expect{ subject.reserve(:site => @rand_site, :resources =>"{ib30g='YES'}/nodes=2")}.to raise_error(Cute::G5K::BadRequest)
83
- end
84
-
85
- it "raises a bad request using OAR API" do
86
- expect{subject.reserve(:site => @rand_site, :resources =>"nodes=1",:keys => "~/jobkey_nonexisting")}.to raise_error(Cute::G5K::BadRequest)
87
- end
88
-
89
- it "raises an exception at deploying" do
90
- expect{ subject.reserve(:site => @rand_site, :nodes => 1, :env => "nonsense")}.to raise_error(Cute::G5K::RequestFailed)
78
+ it "raises a not found error" do
79
+ expect{subject.get_jobs("not-found")}.to raise_error(Cute::G5K::NotFound)
91
80
  end
92
81
 
82
+ # it "raises an exception at deploying" do
83
+ # expect{ subject.reserve(:site => @rand_site, :nodes => 1, :env => "nonsense")}.to raise_error(Cute::G5K::RequestFailed)
84
+ # end
85
+ #
93
86
  it "raises argument errors" do
94
87
  job = Cute::G5K::G5KJSON.new
95
88
  expect {subject.deploy(:env => "env")}.to raise_error(ArgumentError)
@@ -185,10 +178,10 @@ describe Cute::G5K::API do
185
178
  end
186
179
 
187
180
 
188
- it "submits a job and then deploy" do
189
- expect(subject.reserve(:site => @rand_site, :env => @env)).to have_key("deploy")
190
- end
191
-
181
+ # it "submits a job and then deploy" do
182
+ # expect(subject.reserve(:site => @rand_site, :env => @env)).to have_key("deploy")
183
+ # end
184
+ #
192
185
 
193
186
  it "returns the same information" do
194
187
  #low level REST access
@@ -197,7 +190,6 @@ describe Cute::G5K::API do
197
190
  end
198
191
 
199
192
  it "submit and does not wait for the reservation" do
200
- cluster = subject.cluster_uids(@rand_site).first
201
193
  job = subject.reserve(:site => @rand_site, :wait => false)
202
194
  job = subject.wait_for_job(job, :wait_time => 600)
203
195
  expect(job).to include('state' => "running")
data/spec/spec_helper.rb CHANGED
@@ -30,6 +30,7 @@ class FakeG5KResponse < Hash
30
30
  'nodes' => {"node1" => {"hard"=> "alive", "soft"=>"busy"}}
31
31
  }
32
32
  def initialize(num_items = 2)
33
+ super
33
34
  MEDIA_TYPE.each { |key,value| self[key] = value}
34
35
  self['items'] = []
35
36
  num_items.times.each{ self['items'].push(MEDIA_TYPE) }
@@ -46,33 +47,36 @@ RSpec.configure do |config|
46
47
  # uri_sites = Addressable::Template.new "https://{user}:{password}@api.grid5000.fr/{version}/sites"
47
48
  config.before(:each) do
48
49
 
50
+ stub_request(:any,/^https:\/\/api.grid5000.fr\/.*/).
51
+ to_return(:status => 200, :body => g5k_media_type.to_json, :headers => {})
52
+
49
53
  stub_request(:any,/^https:\/\/.*\:.*@api.grid5000.fr\/.*/).
50
54
  to_return(:status => 200, :body => g5k_media_type.to_json, :headers => {})
51
55
 
52
56
  stub_request(:any,/^https:\/\/fake:fake@api.grid5000.fr\.*/).
53
57
  to_return(:status => 401)
54
58
 
55
- stub_request(:any,/^https:\/\/.*\:.*@api.grid5000.fr\/...\/sites\/non-found\/.*/).
59
+ stub_request(:any,/^https:\/\/(.*\:.*@)?api.grid5000.fr\/.*\/sites\/not-found\/.*/).
56
60
  to_return(:status => 404)
57
61
 
58
- stub_request(:any,/^https:\/\/.*\:.*@api.grid5000.fr\/...\/sites\/tmpfail\/.*/).
62
+ stub_request(:any,/^https:\/\/(.*\:.*@)?api.grid5000.fr\/.*\/sites\/tmpfail\/.*/).
59
63
  to_return(:status => 503).
60
64
  to_return(:status => 200, :body => g5k_media_type.to_json, :headers => {})
61
65
 
62
- stub_request(:get,/^https:\/\/.*\:.*@api.grid5000.fr\/...\/sites\/.*vlans$/).
66
+ stub_request(:get,/^https:\/\/(.*\:.*@)?api.grid5000.fr\/.*\/sites\/.*vlans$/).
63
67
  to_return(:status => 200, :body => {'total' => 3, 'items' => [{'type' => "kavlan-local"},{'type' => "kvlan"}]}.to_json)
64
68
 
65
69
  # to_return(:status => 200, :body => {:total => 3, :items => [{:type => "kavlan-local"},{:type => "kavlan"}]})
66
70
 
67
- stub_request(:post, /^https:\/\/.*\:.*@api.grid5000.fr\/.*/).
71
+ stub_request(:post, /^https:\/\/(.*\:.*@)?api.grid5000.fr\/.*/).
68
72
  with(:body => hash_including("resources" => "/slash_22=1+{nonsense},walltime=01:00")).
69
73
  to_return(:status => 400, :body => "Oarsub failed: please verify your request syntax")
70
74
 
71
- stub_request(:post, /^https:\/\/.*\:.*@api.grid5000.fr\/.*/).
75
+ stub_request(:post, /^https:\/\/(.*\:.*@)?api.grid5000.fr\/.*/).
72
76
  with(:body => hash_including("import-job-key-from-file" => [ File.expand_path("~/jobkey_nonexisting") ])).
73
77
  to_return(:status => 400, :body => "Oarsub failed: please verify your request syntax")
74
78
 
75
- stub_request(:post, /^https:\/\/.*\:.*@api.grid5000.fr\/.*/).
79
+ stub_request(:post, /^https:\/\/(.*\:.*@)?api.grid5000.fr\/.*/).
76
80
  with(:body => hash_including("environment" => "nonsense")).
77
81
  to_return(:status => 500, :body => "Invalid environment specification")
78
82
 
data/test/test_execute.rb CHANGED
File without changes