jenkins_api_client 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 58d034d4ed3f397f82ac0db50f4bdd3f955e162c
4
- data.tar.gz: 96e93335ff4401d5077def1902fe7211c054351b
3
+ metadata.gz: 7abcfd6bd7ac3400c06000f1d1caa93becb358fa
4
+ data.tar.gz: e4a2df8fd4b6d38543a298451ba784f93773d5b4
5
5
  SHA512:
6
- metadata.gz: 7c286e0b68b5db499f97e2fac0545678127303d796c6bd29be9afabab715a23c6d4219b97b3b5e07427cfe818703a3bbe6dbf1e66caa3b56fd1a2e985fdd869c
7
- data.tar.gz: 81ef02baf6791a223e5ba72337d4ecfd040d332c51660d1137628df691affac6b011851e04bd4f07b45a535281a36c4dad152650518f90bc0c77f2de5d7ad127
6
+ metadata.gz: 8a5eef38d0003108b8c0111347fee500a769f26217b2f2989074e540f99fbd9fb88d3511d946e4b93bd65d885eed661159f8a78980aac77082f77348098804de
7
+ data.tar.gz: a185e613312035062cb531f5623c7ad7b36064d1e8b55b8bf0f9ce4b36d9f1f8e489506291e5f00ca45fc883934d7d8fda9da2edc866fbac30e5db7e7013b6aa
data/.travis.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 2.1.2
4
+ - 2.1.5
5
5
  - 1.9.3
6
6
 
7
7
  script:
data/CHANGELOG.md CHANGED
@@ -4,6 +4,20 @@ CHANGELOG
4
4
  upcoming
5
5
  --------
6
6
 
7
+ v1.4.0 [08-JUN-2015]
8
+ ----------------------
9
+ * [#161][] Fix job#build method when true/false values are passed as timeout parameter. Credit: [@jlucasps][]
10
+ * [#172][] Promotion plugin config support. Credit: [@AndrewHanes][]
11
+ * [#168][] Added ability to pass "tree" parameter to the Job#get_builds call. Credit: [@bkon][]
12
+ * [#169][] Add optional parameters to cli job build. Credit: [@cyrez][]
13
+ * [#167][] Add ability to override the default logger. Credit: [@gpetras][]
14
+ * [#174][] Use the specified client ssl when downloading artifacts. Credit: [@paulgeringer][]
15
+ * [#165][] Fix for is_offline? bug reporting all nodes as being offline. Credit: [@bsnape][]
16
+ * [#176][] Add ability to delete a promotion configuration. Credit: [@l8nite][]
17
+ * [#59][] Add capability to take the node offline and online. Credit: [@stjohnjohnson][]
18
+ * [#177][] Add ability to create promotion processes. Credit: [@AndrewHanes][]
19
+ * [#179][] Clean up Node calls to make only one call for the computer item. Credit: [@stjohnjohnson][]
20
+
7
21
  v1.3.0 [03-JAN-2015]
8
22
  ----------------------
9
23
  * [#159][] Add ability to configure git tool for a job. Credit: [@hubert][]
@@ -276,6 +290,7 @@ v0.0.1 [15-OCT-2012]
276
290
  [#23]: https://github.com/arangamani/jenkins_api_client/issues/23
277
291
  [#27]: https://github.com/arangamani/jenkins_api_client/issues/27
278
292
  [#42]: https://github.com/arangamani/jenkins_api_client/issues/42
293
+ [#59]: https://github.com/arangamani/jenkins_api_client/issues/59
279
294
  [#85]: https://github.com/arangamani/jenkins_api_client/issues/85
280
295
  [#106]: https://github.com/arangamani/jenkins_api_client/issues/106
281
296
  [#112]: https://github.com/arangamani/jenkins_api_client/issues/112
@@ -300,28 +315,46 @@ v0.0.1 [15-OCT-2012]
300
315
  [#157]: https://github.com/arangamani/jenkins_api_client/issues/157
301
316
  [#158]: https://github.com/arangamani/jenkins_api_client/issues/158
302
317
  [#159]: https://github.com/arangamani/jenkins_api_client/issues/159
318
+ [#161]: https://github.com/arangamani/jenkins_api_client/issues/161
303
319
  [#163]: https://github.com/arangamani/jenkins_api_client/issues/163
320
+ [#165]: https://github.com/arangamani/jenkins_api_client/issues/165
321
+ [#167]: https://github.com/arangamani/jenkins_api_client/issues/167
322
+ [#168]: https://github.com/arangamani/jenkins_api_client/issues/168
323
+ [#169]: https://github.com/arangamani/jenkins_api_client/issues/169
324
+ [#172]: https://github.com/arangamani/jenkins_api_client/issues/172
325
+ [#174]: https://github.com/arangamani/jenkins_api_client/issues/174
326
+ [#176]: https://github.com/arangamani/jenkins_api_client/issues/176
327
+ [#177]: https://github.com/arangamani/jenkins_api_client/issues/177
328
+ [#179]: https://github.com/arangamani/jenkins_api_client/issues/179
329
+ [@AndrewHanes]: https://github.com/AndrewHanes
304
330
  [@Loa]: https://github.com/Loa
305
331
  [@Niarfe]: https://github.com/Niarfe
332
+ [@bkon]: https://github.com/bkon
306
333
  [@bobbrez]: https://github.com/bobbrez
307
334
  [@brettporter]: https://github.com/brettporter
335
+ [@bsnape]: https://github.com/bsnape
308
336
  [@chilicheech]: https://github.com/chilicheech
309
337
  [@client]: https://github.com/client
310
338
  [@cylol]: https://github.com/cylol
311
339
  [@cynipe]: https://github.com/cynipe
340
+ [@cyrez]: https://github.com/cyrez
312
341
  [@dieterdemeyer]: https://github.com/dieterdemeyer
313
342
  [@dkerwin]: https://github.com/dkerwin
314
343
  [@dougforpres]: https://github.com/dougforpres
315
344
  [@drnic]: https://github.com/drnic
345
+ [@gpetras]: https://github.com/gpetras
316
346
  [@hubert]: https://github.com/hubert
347
+ [@jlucasps]: https://github.com/jlucasps
317
348
  [@joelneubert]: https://github.com/joelneubert
318
349
  [@kevinhcross]: https://github.com/kevinhcross
350
+ [@l8nite]: https://github.com/l8nite
319
351
  [@lheinlen-os]: https://github.com/lheinlen-os
320
352
  [@madisp]: https://github.com/madisp
321
353
  [@mattrose]: https://github.com/mattrose
322
354
  [@missedone]: https://github.com/missedone
323
355
  [@n-rodriguez]: https://github.com/n-rodriguez
324
356
  [@notruthless]: https://github.com/notruthless
357
+ [@paulgeringer]: https://github.com/paulgeringer
325
358
  [@riywo]: https://github.com/riywo
326
359
  [@rubytester]: https://github.com/rubytester
327
360
  [@scotje]: https://github.com/scotje
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: jenkins_api_client 1.3.0 ruby lib
5
+ # stub: jenkins_api_client 1.4.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "jenkins_api_client"
9
- s.version = "1.3.0"
9
+ s.version = "1.4.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Kannan Manickam"]
14
- s.date = "2015-01-03"
14
+ s.date = "2015-06-09"
15
15
  s.description = "\nThis is a simple and easy-to-use Jenkins Api client with features focused on\nautomating Job configuration programaticaly and so forth"
16
16
  s.email = ["arangamani.kannan@gmail.com"]
17
17
  s.executables = ["jenkinscli"]
@@ -61,9 +61,11 @@ module JenkinsApi
61
61
  #
62
62
  # @param [String] job Name of the job
63
63
  #
64
+ option :params, :type => :hash, :default => {}
65
+ option :opts, :type => :hash, :default => {}
64
66
  def build(job)
65
67
  @client = Helper.setup(parent_options)
66
- @client.job.build(job)
68
+ @client.job.build(job, options[:params], options[:opts])
67
69
  end
68
70
 
69
71
  desc "status JOB", "Get the current build status of a job"
@@ -57,6 +57,7 @@ module JenkinsApi
57
57
  "username",
58
58
  "password",
59
59
  "password_base64",
60
+ "logger",
60
61
  "log_location",
61
62
  "log_level",
62
63
  "timeout",
@@ -90,6 +91,7 @@ module JenkinsApi
90
91
  # @option args [Boolean] :follow_redirects this argument causes the client to follow a redirect (jenkins can
91
92
  # return a 30x when starting a build)
92
93
  # @option args [Fixnum] :timeout (120) This argument sets the timeout for operations that take longer (in seconds)
94
+ # @option args [Logger] :logger a Logger object, used to override the default logger (optional)
93
95
  # @option args [String] :log_location (STDOUT) the location for the log file
94
96
  # @option args [Fixnum] :log_level (Logger::INFO) The level for messages to be logged. Should be one of:
95
97
  # Logger::DEBUG (0), Logger::INFO (1), Logger::WARN (2), Logger::ERROR (2), Logger::FATAL (3)
@@ -100,6 +102,7 @@ module JenkinsApi
100
102
  # @raise [ArgumentError] when required options are not provided.
101
103
  #
102
104
  def initialize(args)
105
+ args = symbolize_keys(args)
103
106
  args.each do |key, value|
104
107
  if value && VALID_PARAMS.include?(key.to_s)
105
108
  instance_variable_set("@#{key}", value)
@@ -145,11 +148,16 @@ module JenkinsApi
145
148
  @ssl ||= false
146
149
 
147
150
  # Setting log options
148
- @log_location = STDOUT unless @log_location
149
- @log_level = Logger::INFO unless @log_level
150
- @logger = Logger.new(@log_location)
151
- @logger.level = @log_level
152
-
151
+ if @logger
152
+ raise ArgumentError, "logger parameter must be a Logger object" unless @logger.is_a?(Logger)
153
+ raise ArgumentError, "log_level should not be set if using custom logger" if @log_level
154
+ raise ArgumentError, "log_location should not be set if using custom logger" if @log_location
155
+ else
156
+ @log_location = STDOUT unless @log_location
157
+ @log_level = Logger::INFO unless @log_level
158
+ @logger = Logger.new(@log_location)
159
+ @logger.level = @log_level
160
+ end
153
161
 
154
162
  # Base64 decode inserts a newline character at the end. As a workaround
155
163
  # added chomp to remove newline characters. I hope nobody uses newline
@@ -260,7 +268,7 @@ module JenkinsApi
260
268
  uri = URI.parse(@artifact)
261
269
  http = Net::HTTP.new(uri.host, uri.port)
262
270
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
263
- http.use_ssl = true
271
+ http.use_ssl = @ssl
264
272
  request = Net::HTTP::Get.new(uri.request_uri)
265
273
  request.basic_auth(@username, @password)
266
274
  response = http.request(request)
@@ -363,6 +371,8 @@ module JenkinsApi
363
371
  #
364
372
  # @param [String] url_prefix The prefix to be used in the URL
365
373
  # @param [Hash] form_data Form data to send with POST request
374
+ # @param [Boolean] raw_response Return complete Response object instead of
375
+ # JSON body of response
366
376
  #
367
377
  # @return [String] Response code form Jenkins Response
368
378
  #
@@ -683,6 +693,25 @@ module JenkinsApi
683
693
  end
684
694
  end
685
695
 
696
+ # Private method. Converts keys passed in as strings into symbols.
697
+ #
698
+ # @param hash [Hash] Hash containing arguments to login to jenkins.
699
+ #
700
+ def symbolize_keys(hash)
701
+ hash.inject({}){|result, (key, value)|
702
+ new_key = case key
703
+ when String then key.to_sym
704
+ else key
705
+ end
706
+ new_value = case value
707
+ when Hash then symbolize_keys(value)
708
+ else value
709
+ end
710
+ result[new_key] = new_value
711
+ result
712
+ }
713
+ end
714
+
686
715
  # Private method that handles the exception and raises with proper error
687
716
  # message with the type of exception and returns the required values if no
688
717
  # exceptions are raised.
@@ -324,7 +324,7 @@ module JenkinsApi
324
324
  "#{params[:block_build_when_downstream_building]}")
325
325
  xml.blockBuildWhenUpstreamBuilding(
326
326
  "#{params[:block_build_when_upstream_building]}")
327
- xml.triggers.vector do
327
+ xml.triggers.vector do
328
328
  if params[:timer]
329
329
  xml.send("hudson.triggers.TimerTrigger") do
330
330
  xml.spec params[:timer]
@@ -360,7 +360,7 @@ module JenkinsApi
360
360
  xml.buildWrappers
361
361
  end
362
362
  end
363
-
363
+
364
364
  xml_doc = Nokogiri::XML(builder.to_xml)
365
365
  plugin_collection.configure(xml_doc).to_xml
366
366
  end
@@ -449,7 +449,7 @@ module JenkinsApi
449
449
  # @option artifact_params [Boolean] :default_excludes (false)
450
450
  # exclude defaults automatically
451
451
  #
452
- # @return [Nokogiri::XML::Builder]
452
+ # @return [Nokogiri::XML::Builder]
453
453
  #
454
454
  def artifact_archiver(artifact_params, xml)
455
455
  return xml if artifact_params.nil?
@@ -712,9 +712,12 @@ module JenkinsApi
712
712
  #
713
713
  # @param [String] job_name
714
714
  #
715
- def get_builds(job_name)
715
+ def get_builds(job_name, options = {})
716
716
  @logger.info "Obtaining the build details of '#{job_name}'"
717
- response_json = @client.api_get_request("/job/#{path_encode job_name}")
717
+ url = "/job/#{path_encode job_name}"
718
+
719
+ tree = options[:tree] || nil
720
+ response_json = @client.api_get_request url, tree_string(tree)
718
721
  response_json["builds"]
719
722
  end
720
723
 
@@ -827,9 +830,9 @@ module JenkinsApi
827
830
  # @return [String] HTTP response code (per prev. behavior) (NO TIMEOUT SPECIFIED)
828
831
  #
829
832
  def build(job_name, params={}, opts = {})
830
- if opts.nil? || opts.class.is_a?(FalseClass)
833
+ if opts.nil? || opts.is_a?(FalseClass)
831
834
  opts = {}
832
- elsif opts.class.is_a?(TrueClass)
835
+ elsif opts.is_a?(TrueClass)
833
836
  opts = { 'build_start_timeout' => @client_timeout }
834
837
  end
835
838
 
@@ -1494,6 +1497,52 @@ module JenkinsApi
1494
1497
  result
1495
1498
  end
1496
1499
 
1500
+
1501
+ # Create a new promotion process
1502
+ #
1503
+ # This must be called before set/get promote config can be used on a process
1504
+ #
1505
+ # Must be called after updating the job's config
1506
+ # @param [String] job_name
1507
+ # @param [String] process The process name
1508
+ # @return [String] Process config
1509
+ def init_promote_process(job_name, process, config)
1510
+ @logger.info "Creating new process #{process} for job #{job_name}"
1511
+ @client.post_config("/job/#{job_name}/promotion/createProcess?name=#{process}", config)
1512
+ end
1513
+
1514
+
1515
+ # Get a job's promotion config
1516
+ #
1517
+ # @param [String] job_name
1518
+ # @param [String] process The process name
1519
+ # @return [String] Promote config
1520
+ def get_promote_config(job_name, process)
1521
+ @logger.info "Getting promote config for job '#{job_name}' process '#{process}'"
1522
+ @client.get_config("/job/#{job_name}/promotion/process/#{process}/config.xml")
1523
+ end
1524
+
1525
+ # Set a job's promotion config
1526
+ #
1527
+ # @param [String] job_name
1528
+ # @param [String] process The process name
1529
+ # @param [String] Job config
1530
+ # @return nil
1531
+ def set_promote_config(job_name, process, config)
1532
+ @logger.info "Setting promote config for job '#{job_name}' process '#{process}' to #{config}"
1533
+ @client.post_config("/job/#{job_name}/promotion/process/#{process}/config.xml", config)
1534
+ end
1535
+
1536
+ # Delete a job's promotion config
1537
+ #
1538
+ # @param [String] job_name
1539
+ # @param [String] process The process name
1540
+ # @return nil
1541
+ def delete_promote_config(job_name, process)
1542
+ @logger.info "Deleting promote config for job '#{job_name}' process '#{process}'"
1543
+ @client.post_config("/job/#{job_name}/promotion/process/#{process}/doDelete")
1544
+ end
1545
+
1497
1546
  #A Method to find artifacts path from the Current Build
1498
1547
  #
1499
1548
  # @param [String] job_name
@@ -1741,6 +1790,11 @@ module JenkinsApi
1741
1790
  }
1742
1791
  }
1743
1792
  end
1793
+
1794
+ def tree_string tree_value
1795
+ return nil unless tree_value
1796
+ "tree=#{tree_value}"
1797
+ end
1744
1798
  end
1745
1799
  end
1746
1800
  end
@@ -244,7 +244,7 @@ module JenkinsApi
244
244
  GENERAL_ATTRIBUTES.each do |meth_suffix|
245
245
  define_method("get_#{meth_suffix}") do
246
246
  @logger.info "Obtaining '#{meth_suffix}' attribute from jenkins"
247
- response_json = @client.api_get_request("/computer")
247
+ response_json = @client.api_get_request("/computer", "tree=#{path_encode meth_suffix}")
248
248
  response_json["#{meth_suffix}"]
249
249
  end
250
250
  end
@@ -254,8 +254,9 @@ module JenkinsApi
254
254
  NODE_PROPERTIES.each do |meth_suffix|
255
255
  define_method("is_#{meth_suffix}?") do |node_name|
256
256
  @logger.info "Obtaining '#{meth_suffix}' property of '#{node_name}'"
257
- response_json = @client.api_get_request("/computer")
258
- resp = response_json["computer"][index(node_name)]["#{meth_suffix}"]
257
+ node_name = "(master)" if node_name == "master"
258
+ response_json = @client.api_get_request("/computer/#{path_encode node_name}", "tree=#{path_encode meth_suffix}")
259
+ resp = response_json["#{meth_suffix}"].to_s
259
260
  resp =~ /False/i ? false : true
260
261
  end
261
262
  end
@@ -264,8 +265,9 @@ module JenkinsApi
264
265
  NODE_ATTRIBUTES.each do |meth_suffix|
265
266
  define_method("get_node_#{meth_suffix}") do |node_name|
266
267
  @logger.info "Obtaining '#{meth_suffix}' attribute of '#{node_name}'"
267
- response_json = @client.api_get_request("/computer")
268
- response_json["computer"][index(node_name)]["#{meth_suffix}"]
268
+ node_name = "(master)" if node_name == "master"
269
+ response_json = @client.api_get_request("/computer/#{path_encode node_name}", "tree=#{path_encode meth_suffix}")
270
+ response_json["#{meth_suffix}"]
269
271
  end
270
272
  end
271
273
 
@@ -292,7 +294,7 @@ module JenkinsApi
292
294
  def get_config(node_name)
293
295
  @logger.info "Obtaining the config.xml of node '#{node_name}'"
294
296
  node_name = "(master)" if node_name == "master"
295
- @client.get_config("/computer/#{ path_encode node_name}")
297
+ @client.get_config("/computer/#{path_encode node_name}")
296
298
  end
297
299
 
298
300
  # Posts the given config.xml to the Jenkins node
@@ -306,6 +308,22 @@ module JenkinsApi
306
308
  @client.post_config("/computer/#{path_encode node_name}/config.xml", xml)
307
309
  end
308
310
 
311
+ # Toggles the temporarily offline state of the Jenkins node
312
+ #
313
+ # @param [String] node_name name of the node
314
+ # @param [String] reason Offline reason why the node is offline
315
+ #
316
+ def toggle_temporarilyOffline(node_name, reason="")
317
+ @logger.info "Toggling the temporarily offline status of of node '#{node_name}' with reason '#{reason}'"
318
+ node_name = "(master)" if node_name == "master"
319
+ previous_state = is_temporarilyOffline?(node_name)
320
+ @client.api_post_request("/computer/#{path_encode node_name}/toggleOffline?offlineMessage=#{path_encode reason}")
321
+ new_state = is_temporarilyOffline?(node_name)
322
+ if new_state == previous_state
323
+ raise "The specified node '#{node_name}' was unable to change offline state."
324
+ end
325
+ new_state
326
+ end
309
327
  end
310
328
  end
311
329
  end
@@ -25,7 +25,7 @@ module JenkinsApi
25
25
  # Major version of the gem
26
26
  MAJOR = 1
27
27
  # Minor version of the gem
28
- MINOR = 3
28
+ MINOR = 4
29
29
  # Tiny version of the gem used for patches
30
30
  TINY = 0
31
31
  # Used for pre-releases
@@ -38,8 +38,9 @@ else
38
38
  end
39
39
 
40
40
  begin
41
- client_opts = YAML.load_file(File.expand_path(config_file))
42
- unless client_opts.has_key?(:username)
41
+ client_opts = Hash[YAML.load_file(File.expand_path(config_file)).map { | (k,v) | [k.to_sym, v]} ]
42
+
43
+ unless client_opts.has_key?(:username)
43
44
  client_opts[:username] = prompt_for_username()
44
45
  end
45
46
  unless client_opts.has_key?(:password) or client_opts.has_key?(:password_base64)
@@ -420,4 +420,52 @@ describe JenkinsApi::Client do
420
420
  end
421
421
  end
422
422
  end
423
+
424
+ context "With logging configuration" do
425
+
426
+ it "Should fail if logger is not a Logger object" do
427
+ expect(
428
+ lambda do
429
+ JenkinsApi::Client.new({
430
+ :server_ip => '127.0.0.1',
431
+ :logger => 'testing',
432
+ })
433
+ end
434
+ ).to raise_error
435
+ end
436
+
437
+ it "Should set logger instance variable to Logger" do
438
+ client = JenkinsApi::Client.new(
439
+ :server_ip => '127.0.0.1',
440
+ :logger => Logger.new(STDOUT),
441
+ )
442
+
443
+ client.instance_variable_get('@logger').class.should == Logger
444
+ end
445
+
446
+ it "Should fail if logger and log_level are both set" do
447
+ expect(
448
+ lambda do
449
+ JenkinsApi::Client.new({
450
+ :server_ip => '127.0.0.1',
451
+ :logger => Logger.new(STDOUT),
452
+ :log_level => Logger::INFO,
453
+ })
454
+ end
455
+ ).to raise_error
456
+ end
457
+
458
+ it "Should fail if logger and log_location are both set" do
459
+ expect(
460
+ lambda do
461
+ JenkinsApi::Client.new({
462
+ :server_ip => '127.0.0.1',
463
+ :logger => Logger.new(STDOUT),
464
+ :log_location => 'test.log',
465
+ })
466
+ end
467
+ ).to raise_error
468
+ end
469
+
470
+ end
423
471
  end
@@ -400,15 +400,31 @@ describe JenkinsApi::Client::Job do
400
400
  ### OLD NON-QUEUE RESPONSE JENKINS ###
401
401
  # Next tests confirm it deals with different jenkins versions and waits
402
402
  # for build to start (or not)
403
- it "accepts the job name and builds the job (w/timeout)" do
404
- @client.should_receive(:api_get_request).with(
405
- "/job/test_job").and_return({})
403
+ context "accepts the job name and builds the job (w/timeout)" do
404
+ before do
405
+ @client.should_receive(:api_get_request).with(
406
+ "/job/test_job").and_return({})
407
+ @client.should_receive(:api_post_request).with(
408
+ "/job/test_job/build", {}, true).and_return(FakeResponse.new(302))
409
+ @client.should_receive(:api_get_request).with(
410
+ "/job/test_job/1/").and_return({})
411
+ @client.should_receive(:get_jenkins_version).and_return("1.1")
412
+ end
413
+
414
+ it "passes a number of seconds for timeout in opts={} parameter" do
415
+ @job.build("test_job", {}, {'build_start_timeout' => 10}).should == 1
416
+ end
417
+
418
+ it "passes a true value for timeout in opts={} parameter" do
419
+ @job.instance_variable_set :@client_timeout, 10
420
+ @job.build("test_job", {}, true).should == 1
421
+ end
422
+ end
423
+
424
+ it "accepts the job name and builds the job (with a false timeout value)" do
406
425
  @client.should_receive(:api_post_request).with(
407
426
  "/job/test_job/build", {}, true).and_return(FakeResponse.new(302))
408
- @client.should_receive(:api_get_request).with(
409
- "/job/test_job/1/").and_return({})
410
- @client.should_receive(:get_jenkins_version).and_return("1.1")
411
- @job.build("test_job", {}, {'build_start_timeout' => 10}).should == 1
427
+ @job.build("test_job", {}, false).should == "302"
412
428
  end
413
429
 
414
430
  # wait for build to start (or not) (initial response will fail)
@@ -616,6 +632,27 @@ describe JenkinsApi::Client::Job do
616
632
  end
617
633
  end
618
634
 
635
+ describe "#get_promote_config" do
636
+ it "accepts name and process and returns promotion config" do
637
+ @client.should_receive(:get_config).with('/job/testjob/promotion/process/promo/config.xml')
638
+ @job.get_promote_config('testjob', 'promo')
639
+ end
640
+ end
641
+
642
+ describe "#set_promote_config" do
643
+ it "accepts name, process and config." do
644
+ @client.should_receive(:post_config).with('/job/testjob/promotion/process/promo/config.xml', 'xml')
645
+ @job.set_promote_config('testjob', 'promo', 'xml')
646
+ end
647
+ end
648
+
649
+ describe "#delete_promote_config" do
650
+ it "accepts name and process and deletes promotion config" do
651
+ @client.should_receive(:post_config).with('/job/testjob/promotion/process/promo/doDelete')
652
+ @job.delete_promote_config('testjob', 'promo')
653
+ end
654
+ end
655
+
619
656
  describe '#scm_git' do
620
657
  before do
621
658
  @job.send(:scm_git, {
@@ -7,11 +7,32 @@ describe JenkinsApi::Client::Node do
7
7
  mock_logger = Logger.new "/dev/null"
8
8
  @client.should_receive(:logger).and_return(mock_logger)
9
9
  @node = JenkinsApi::Client::Node.new(@client)
10
- @sample_json_computer_response = {
10
+ @sample_json_list_response = {
11
11
  "computer" => [
12
12
  "displayName" => "slave"
13
13
  ]
14
14
  }
15
+ @sample_json_computer_response = {
16
+ "displayName" => "slave"
17
+ }
18
+ @offline_slave = {
19
+ "displayName" => "slave",
20
+ "offline" => true,
21
+ "temporarilyOffline" => true,
22
+ }
23
+ @online_slave = {
24
+ "displayName" => "slave",
25
+ "offline" => false,
26
+ "temporarilyOffline" => false,
27
+ }
28
+ @offline_slave_in_string = {
29
+ "displayName" => "slave",
30
+ "offline" => "true",
31
+ }
32
+ @online_slave_in_string = {
33
+ "displayName" => "slave",
34
+ "offline" => "false",
35
+ }
15
36
  computer_sample_xml_filename = '../fixtures/files/computer_sample.xml'
16
37
  @sample_computer_xml = File.read(
17
38
  File.expand_path(computer_sample_xml_filename , __FILE__)
@@ -91,7 +112,7 @@ describe JenkinsApi::Client::Node do
91
112
  ).with(
92
113
  "/computer"
93
114
  ).and_return(
94
- @sample_json_computer_response
115
+ @sample_json_list_response
95
116
  )
96
117
  @client.should_receive(
97
118
  :api_post_request
@@ -109,7 +130,7 @@ describe JenkinsApi::Client::Node do
109
130
  ).with(
110
131
  "/computer"
111
132
  ).and_return(
112
- @sample_json_computer_response
133
+ @sample_json_list_response
113
134
  )
114
135
  expect(
115
136
  lambda{ @node.delete(slave_name) }
@@ -121,8 +142,10 @@ describe JenkinsApi::Client::Node do
121
142
  it "accepts filter and lists all nodes matching the filter" do
122
143
  @client.should_receive(
123
144
  :api_get_request
145
+ ).with(
146
+ "/computer"
124
147
  ).and_return(
125
- @sample_json_computer_response
148
+ @sample_json_list_response
126
149
  )
127
150
  @node.list("slave").class.should == Array
128
151
  end
@@ -135,8 +158,11 @@ describe JenkinsApi::Client::Node do
135
158
  it "should get the #{attribute} attribute" do
136
159
  @client.should_receive(
137
160
  :api_get_request
161
+ ).with(
162
+ "/computer",
163
+ "tree=#{attribute}"
138
164
  ).and_return(
139
- @sample_json_computer_response
165
+ @sample_json_list_response
140
166
  )
141
167
  @node.method("get_#{attribute}").call
142
168
  end
@@ -151,15 +177,80 @@ describe JenkinsApi::Client::Node do
151
177
  it "should get the #{property} property" do
152
178
  @client.should_receive(
153
179
  :api_get_request
154
- ).twice.and_return(
180
+ ).with(
181
+ "/computer/slave",
182
+ "tree=#{property}"
183
+ ).and_return(
155
184
  @sample_json_computer_response
156
185
  )
157
186
  @node.method("is_#{property}?").call("slave")
158
187
  end
188
+
189
+ it "should get the #{property} property for master" do
190
+ @client.should_receive(
191
+ :api_get_request
192
+ ).with(
193
+ "/computer/(master)",
194
+ "tree=#{property}"
195
+ ).and_return(
196
+ @sample_json_computer_response
197
+ )
198
+ @node.method("is_#{property}?").call("master")
199
+ end
159
200
  end
160
201
  end
161
202
  end
162
203
 
204
+ describe 'is_offline?' do
205
+ it "returns true if the node is offline" do
206
+ @client.should_receive(
207
+ :api_get_request
208
+ ).with(
209
+ "/computer/slave",
210
+ "tree=offline"
211
+ ).and_return(
212
+ @offline_slave
213
+ )
214
+ @node.method("is_offline?").call("slave").should be_true
215
+ end
216
+
217
+ it "returns false if the node is online" do
218
+ @client.should_receive(
219
+ :api_get_request
220
+ ).with(
221
+ "/computer/slave",
222
+ "tree=offline"
223
+ ).and_return(
224
+ @online_slave
225
+ )
226
+ @node.method("is_offline?").call("slave").should be_false
227
+ end
228
+
229
+ it "returns false if the node is online and have a string value on its attr" do
230
+ @client.should_receive(
231
+ :api_get_request
232
+ ).with(
233
+ "/computer/slave",
234
+ "tree=offline"
235
+ ).and_return(
236
+ @offline_slave_in_string
237
+ )
238
+ @node.method("is_offline?").call("slave").should be_true
239
+ end
240
+
241
+ it "returns false if the node is online and have a string value on its attr" do
242
+ @client.should_receive(
243
+ :api_get_request
244
+ ).with(
245
+ "/computer/slave",
246
+ "tree=offline"
247
+ ).and_return(
248
+ @online_slave_in_string
249
+ )
250
+ @node.method("is_offline?").call("slave").should be_false
251
+ end
252
+ end
253
+
163
254
  describe "NodeAttributes" do
164
255
  node_attributes = JenkinsApi::Client::Node::NODE_ATTRIBUTES
165
256
  node_attributes.each do |attribute|
@@ -167,11 +258,26 @@ describe JenkinsApi::Client::Node do
167
258
  it "should get the #{attribute} node attribute" do
168
259
  @client.should_receive(
169
260
  :api_get_request
170
- ).twice.and_return(
261
+ ).with(
262
+ "/computer/slave",
263
+ "tree=#{attribute}"
264
+ ).and_return(
171
265
  @sample_json_computer_response
172
266
  )
173
267
  @node.method("get_node_#{attribute}").call("slave")
174
268
  end
269
+
270
+ it "should get the #{attribute} node attribute for master" do
271
+ @client.should_receive(
272
+ :api_get_request
273
+ ).with(
274
+ "/computer/(master)",
275
+ "tree=#{attribute}"
276
+ ).and_return(
277
+ @sample_json_computer_response
278
+ )
279
+ @node.method("get_node_#{attribute}").call("master")
280
+ end
175
281
  end
176
282
  end
177
283
  end
@@ -194,6 +300,43 @@ describe JenkinsApi::Client::Node do
194
300
  end
195
301
  end
196
302
 
303
+ describe "#toggle_temporarilyOffline" do
304
+ it "successfully toggles an offline status of a node" do
305
+ @client.should_receive(:api_post_request).with(
306
+ "/computer/slave/toggleOffline?offlineMessage=foo%20bar"
307
+ ).and_return("302")
308
+ @client.should_receive(
309
+ :api_get_request
310
+ ).with(
311
+ "/computer/slave",
312
+ "tree=temporarilyOffline"
313
+ ).and_return(
314
+ @offline_slave,
315
+ @online_slave
316
+ )
317
+ @node.method("toggle_temporarilyOffline").call("slave", "foo bar").should be_false
318
+ end
319
+
320
+ it "fails to toggle an offline status of a node" do
321
+ @client.should_receive(:api_post_request).with(
322
+ "/computer/slave/toggleOffline?offlineMessage=foo%20bar"
323
+ ).and_return("302")
324
+ @client.should_receive(
325
+ :api_get_request
326
+ ).with(
327
+ "/computer/slave",
328
+ "tree=temporarilyOffline"
329
+ ).and_return(
330
+ @online_slave,
331
+ @online_slave
332
+ )
333
+ expect(
334
+ lambda{
335
+ @node.toggle_temporarilyOffline("slave", "foo bar")
336
+ }
337
+ ).to raise_error
338
+ end
339
+ end
197
340
  end
198
341
  end
199
342
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jenkins_api_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kannan Manickam
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-03 00:00:00.000000000 Z
11
+ date: 2015-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri