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 +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +33 -0
- data/jenkins_api_client.gemspec +3 -3
- data/lib/jenkins_api_client/cli/job.rb +3 -1
- data/lib/jenkins_api_client/client.rb +35 -6
- data/lib/jenkins_api_client/job.rb +61 -7
- data/lib/jenkins_api_client/node.rb +24 -6
- data/lib/jenkins_api_client/version.rb +1 -1
- data/scripts/login_with_irb.rb +3 -2
- data/spec/unit_tests/client_spec.rb +48 -0
- data/spec/unit_tests/job_spec.rb +44 -7
- data/spec/unit_tests/node_spec.rb +150 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7abcfd6bd7ac3400c06000f1d1caa93becb358fa
|
4
|
+
data.tar.gz: e4a2df8fd4b6d38543a298451ba784f93773d5b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a5eef38d0003108b8c0111347fee500a769f26217b2f2989074e540f99fbd9fb88d3511d946e4b93bd65d885eed661159f8a78980aac77082f77348098804de
|
7
|
+
data.tar.gz: a185e613312035062cb531f5623c7ad7b36064d1e8b55b8bf0f9ce4b36d9f1f8e489506291e5f00ca45fc883934d7d8fda9da2edc866fbac30e5db7e7013b6aa
|
data/.travis.yml
CHANGED
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
|
data/jenkins_api_client.gemspec
CHANGED
@@ -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.
|
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.
|
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-
|
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
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
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 =
|
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
|
-
|
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.
|
833
|
+
if opts.nil? || opts.is_a?(FalseClass)
|
831
834
|
opts = {}
|
832
|
-
elsif opts.
|
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
|
-
|
258
|
-
|
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
|
-
|
268
|
-
response_json
|
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/#{
|
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
|
data/scripts/login_with_irb.rb
CHANGED
@@ -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
|
-
|
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
|
data/spec/unit_tests/job_spec.rb
CHANGED
@@ -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
|
-
|
404
|
-
|
405
|
-
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
).
|
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
|
-
).
|
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.
|
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-
|
11
|
+
date: 2015-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|