jenkins_api_client 1.3.0 → 1.4.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.
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