jenkins_api_client 0.6.2 → 0.7.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.
Files changed (40) hide show
  1. data/.gitignore +3 -0
  2. data/.jenkins.yml +9 -0
  3. data/.travis.yml +11 -15
  4. data/CHANGELOG.md +15 -0
  5. data/Gemfile +2 -2
  6. data/README.md +7 -9
  7. data/Rakefile +27 -14
  8. data/lib/jenkins_api_client.rb +36 -6
  9. data/lib/jenkins_api_client/build_queue.rb +213 -0
  10. data/lib/jenkins_api_client/cli/base.rb +10 -6
  11. data/lib/jenkins_api_client/cli/helper.rb +13 -4
  12. data/lib/jenkins_api_client/cli/job.rb +6 -9
  13. data/lib/jenkins_api_client/cli/node.rb +6 -4
  14. data/lib/jenkins_api_client/cli/system.rb +2 -1
  15. data/lib/jenkins_api_client/client.rb +31 -25
  16. data/lib/jenkins_api_client/job.rb +248 -95
  17. data/lib/jenkins_api_client/node.rb +128 -10
  18. data/lib/jenkins_api_client/system.rb +4 -2
  19. data/lib/jenkins_api_client/version.rb +2 -2
  20. data/lib/jenkins_api_client/view.rb +17 -4
  21. data/scripts/login_with_irb.rb +4 -3
  22. data/spec/func_tests/client_spec.rb +90 -0
  23. data/spec/func_tests/job_spec.rb +348 -0
  24. data/spec/func_tests/node_spec.rb +174 -0
  25. data/spec/{spec_helper.rb → func_tests/spec_helper.rb} +2 -2
  26. data/spec/func_tests/system_spec.rb +55 -0
  27. data/spec/func_tests/view_spec.rb +53 -0
  28. data/spec/unit_tests/client_spec.rb +211 -0
  29. data/spec/unit_tests/fixtures/files/computer_sample.xml +17 -0
  30. data/spec/unit_tests/fixtures/files/job_sample.xml +16 -0
  31. data/spec/unit_tests/job_spec.rb +355 -0
  32. data/spec/unit_tests/node_spec.rb +192 -0
  33. data/spec/unit_tests/spec_helper.rb +8 -0
  34. data/spec/unit_tests/system_spec.rb +54 -0
  35. data/spec/unit_tests/view_spec.rb +127 -0
  36. metadata +34 -23
  37. data/spec/client_spec.rb +0 -52
  38. data/spec/job_spec.rb +0 -158
  39. data/spec/node_spec.rb +0 -48
  40. data/spec/system_spec.rb +0 -46
@@ -37,7 +37,7 @@ module JenkinsApi
37
37
  "busyExecutors",
38
38
  "displayName",
39
39
  "totalExecutors"
40
- ]
40
+ ].freeze
41
41
 
42
42
  # Properties of a node.
43
43
  # The following methods are defined to be called on the node object
@@ -57,7 +57,7 @@ module JenkinsApi
57
57
  "manualLaunchAllowed",
58
58
  "offline",
59
59
  "temporarilyOffline"
60
- ]
60
+ ].freeze
61
61
 
62
62
  # Node specific attributes.
63
63
  # The following methods are defined using define_method.
@@ -79,7 +79,7 @@ module JenkinsApi
79
79
  "monitorData",
80
80
  "offlineCause",
81
81
  "oneOffExecutors"
82
- ]
82
+ ].freeze
83
83
 
84
84
  # Initializes a new node object
85
85
  #
@@ -89,10 +89,91 @@ module JenkinsApi
89
89
  @client = client
90
90
  end
91
91
 
92
+ # Gives the string representation of the Object
93
+ #
92
94
  def to_s
93
95
  "#<JenkinsApi::Client::Node>"
94
96
  end
95
97
 
98
+ # Creates a new node with the specified parameters
99
+ #
100
+ # @param [Hash] params parameters for creating a dump slave
101
+ # * +:name+ name of the slave
102
+ # * +:description+ description of the new slave
103
+ # * +:executors+ number of executors
104
+ # * +:remote_fs+ Remote FS root
105
+ # * +:labels+ comma separated list of labels
106
+ # * +:mode+ mode of the slave: normal, exclusive
107
+ # * +:slave_host+ Hostname/IP of the slave
108
+ # * +:slave_port+ Slave port
109
+ # * +:private_key_file+ Private key file of master
110
+ #
111
+ def create_dump_slave(params)
112
+
113
+ if list.include?(params[:name])
114
+ raise "The specified slave '#{params[:name]}' already exists."
115
+ end
116
+
117
+ unless params[:name] && params[:slave_host] && params[:private_key_file]
118
+ raise "Name, slave host, and private key file are required for" +
119
+ " creating a slave."
120
+ end
121
+
122
+ default_params = {
123
+ :description => "Automatically created through jenkins_api_client",
124
+ :executors => 2,
125
+ :remote_fs => "/var/jenkins",
126
+ :labels => params[:name],
127
+ :slave_port => 22,
128
+ :mode => "normal"
129
+ }
130
+
131
+ params = default_params.merge(params)
132
+ labels = params[:labels].split(/\s*,\s*/).join(" ")
133
+ mode = params[:mode].upcase
134
+
135
+ post_params = {
136
+ "name" => params[:name],
137
+ "type" => "hudson.slaves.DumbSlave$DescriptorImpl",
138
+ "json" => {
139
+ "name" => params[:name],
140
+ "nodeDescription" => params[:description],
141
+ "numExecutors" => params[:executors],
142
+ "remoteFS" => params[:remote_fs],
143
+ "labelString" => labels,
144
+ "mode" => mode,
145
+ "type" => "hudson.slaves.DumbSlave$DescriptorImpl",
146
+ "retentionStrategy" => {
147
+ "stapler-class" => "hudson.slaves.RetentionStrategy$Always"
148
+ },
149
+ "nodeProperties" => {
150
+ "stapler-class-bag" => "true"
151
+ },
152
+ "launcher" => {
153
+ "stapler-class" => "hudson.plugins.sshslaves.SSHLauncher",
154
+ "host" => params[:slave_host],
155
+ "port" => params[:slave_port],
156
+ "username" => params[:slave_user],
157
+ "privatekey" => params[:private_key_file],
158
+ }
159
+ }.to_json
160
+ }
161
+
162
+ @client.api_post_request("/computer/doCreateItem", post_params)
163
+ end
164
+
165
+ # Deletes the specified node
166
+ #
167
+ # @params [String] node_name Name of the node to delete
168
+ #
169
+ def delete(node_name)
170
+ if list.include?(node_name)
171
+ @client.api_post_request("/computer/#{node_name}/doDelete")
172
+ else
173
+ raise "The specified node '#{node_name}' doesn't exist in Jenkins."
174
+ end
175
+ end
176
+
96
177
  # This method lists all nodes
97
178
  #
98
179
  # @param [String] filter a regex to filter node names
@@ -101,9 +182,11 @@ module JenkinsApi
101
182
  def list(filter = nil, ignorecase = true)
102
183
  node_names = []
103
184
  response_json = @client.api_get_request("/computer")
104
- response_json["computer"].each { |computer|
105
- node_names << computer["displayName"] if computer["displayName"] =~ /#{filter}/i
106
- }
185
+ response_json["computer"].each do |computer|
186
+ if computer["displayName"] =~ /#{filter}/i
187
+ node_names << computer["displayName"]
188
+ end
189
+ end
107
190
  node_names
108
191
  end
109
192
 
@@ -113,9 +196,9 @@ module JenkinsApi
113
196
  #
114
197
  def index(node_name)
115
198
  response_json = @client.api_get_request("/computer")
116
- response_json["computer"].each_with_index { |computer, index|
199
+ response_json["computer"].each_with_index do |computer, index|
117
200
  return index if computer["displayName"] == node_name
118
- }
201
+ end
119
202
  end
120
203
 
121
204
  # Defines methods for general node attributes.
@@ -132,7 +215,8 @@ module JenkinsApi
132
215
  NODE_PROPERTIES.each do |meth_suffix|
133
216
  define_method("is_#{meth_suffix}?") do |node_name|
134
217
  response_json = @client.api_get_request("/computer")
135
- response_json["computer"][index(node_name)]["#{meth_suffix}"] =~ /False/i ? false : true
218
+ resp = response_json["computer"][index(node_name)]["#{meth_suffix}"]
219
+ resp =~ /False/i ? false : true
136
220
  end
137
221
  end
138
222
 
@@ -144,6 +228,40 @@ module JenkinsApi
144
228
  end
145
229
  end
146
230
 
231
+ # Changes the mode of a slave node in Jenkins
232
+ #
233
+ # @param [String] node_name name of the node to change mode for
234
+ # @param [String] mode mode to change to
235
+ #
236
+ def change_mode(node_name, mode)
237
+ mode = mode.upcase
238
+ xml = get_config(node_name)
239
+ n_xml = Nokogiri::XML(xml)
240
+ desc = n_xml.xpath("//mode").first
241
+ desc.content = "#{mode.upcase}"
242
+ xml_modified = n_xml.to_xml
243
+ post_config(node_name, xml_modified)
244
+ end
245
+
246
+ # Obtains the configuration of node from Jenkins server
247
+ #
248
+ # @param [String] node_name name of the node
249
+ #
250
+ def get_config(node_name)
251
+ node_name = "(master)" if node_name == "master"
252
+ @client.get_config("/computer/#{node_name}/config.xml")
253
+ end
254
+
255
+ # Posts the given config.xml to the Jenkins node
256
+ #
257
+ # @param [String] node_name name of the node
258
+ # @param [String] xml Config.xml of the node
259
+ #
260
+ def post_config(node_name, xml)
261
+ node_name = "(master)" if node_name == "master"
262
+ @client.post_config("/computer/#{node_name}/config.xml", xml)
263
+ end
264
+
147
265
  end
148
266
  end
149
- end
267
+ end
@@ -54,7 +54,8 @@ module JenkinsApi
54
54
 
55
55
  # Restarts the Jenkins server
56
56
  #
57
- # @param [Bool] force whether to force restart or wait till all jobs are completed.
57
+ # @param [Bool] force whether to force restart or wait till all
58
+ # jobs are completed.
58
59
  #
59
60
  def restart(force = false)
60
61
  if force
@@ -64,7 +65,8 @@ module JenkinsApi
64
65
  end
65
66
  end
66
67
 
67
- # This method waits till the server becomes ready after a start or restart.
68
+ # This method waits till the server becomes ready after a start
69
+ # or restart.
68
70
  #
69
71
  def wait_for_ready
70
72
  Timeout::timeout(120) do
@@ -23,8 +23,8 @@
23
23
  module JenkinsApi
24
24
  class Client
25
25
  MAJOR = 0
26
- MINOR = 6
27
- TINY = 2
26
+ MINOR = 7
27
+ TINY = 0
28
28
  PRE = nil
29
29
  VERSION = [MAJOR, MINOR, TINY, PRE].compact.join('.')
30
30
  end
@@ -43,7 +43,10 @@ module JenkinsApi
43
43
  # @param [String] view_name
44
44
  #
45
45
  def create(view_name)
46
- @client.api_post_request("/createView?name=#{view_name}&mode=hudson.model.ListView&json={\"name\":\"#{view_name}\",\"mode\":\"hudson.model.ListView\"}")
46
+ post_msg = "/createView?name=#{view_name}&"
47
+ post_msg << "mode=hudson.model.ListView&json={\"name\":\"#{view_name}}"
48
+ post_msg << "\",\"mode\":\"hudson.model.ListView\"}"
49
+ @client.api_post_request(post_msg)
47
50
  end
48
51
 
49
52
  # Delete a view
@@ -63,7 +66,11 @@ module JenkinsApi
63
66
  view_names = []
64
67
  response_json = @client.api_get_request("/")
65
68
  response_json["views"].each { |view|
66
- view_names << view["name"] if view["name"] =~ /#{filter}/i
69
+ if ignorecase
70
+ view_names << view["name"] if view["name"] =~ /#{filter}/i
71
+ else
72
+ view_names << view["name"] if view["name"] =~ /#{filter}/
73
+ end
67
74
  }
68
75
  view_names
69
76
  end
@@ -80,8 +87,12 @@ module JenkinsApi
80
87
  #
81
88
  # @param [String] view_name
82
89
  #
90
+ # @return [Array] job_names list of jobs in the specified view
91
+ #
83
92
  def list_jobs(view_name)
84
93
  job_names = []
94
+ raise "The view #{view_name} doesn't exists on the server"\
95
+ unless exists?(view_name)
85
96
  response_json = @client.api_get_request("/view/#{view_name}")
86
97
  response_json["jobs"].each do |job|
87
98
  job_names << job["name"]
@@ -95,7 +106,8 @@ module JenkinsApi
95
106
  # @param [String] job_name
96
107
  #
97
108
  def add_job(view_name, job_name)
98
- @client.api_post_request("/view/#{view_name}/addJobToView?name=#{job_name}")
109
+ post_msg = "/view/#{view_name}/addJobToView?name=#{job_name}"
110
+ @client.api_post_request(post_msg)
99
111
  end
100
112
 
101
113
  # Remove a job from view
@@ -104,7 +116,8 @@ module JenkinsApi
104
116
  # @param [String] job_name
105
117
  #
106
118
  def remove_job(view_name, job_name)
107
- @client.api_post_request("/view/#{view_name}/removeJobFromView?name=#{job_name}")
119
+ post_msg = "/view/#{view_name}/removeJobFromView?name=#{job_name}"
120
+ @client.api_post_request(post_msg)
108
121
  end
109
122
 
110
123
  # Obtain the configuration stored in config.xml of a specific view
@@ -1,8 +1,9 @@
1
1
  # This script provides an easier way to login to Jenkins server API.
2
- # It logs you in with the credentials and server details you proided and then starts an IRB
3
- # session so you can interactively play with the API.
2
+ # It logs you in with the credentials and server details you proided and then
3
+ # starts an IRB session so you can interactively play with the API.
4
4
 
5
- require File.expand_path('../../lib/jenkins_api_client', __FILE__)
5
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
6
+ require 'jenkins_api_client'
6
7
  require 'yaml'
7
8
  require 'irb'
8
9
 
@@ -0,0 +1,90 @@
1
+ #
2
+ # Specifying JenkinsApi::Client class capabilities
3
+ # Author: Kannan Manickam <arangamani.kannan@gmail.com>
4
+ #
5
+
6
+ require File.expand_path('../spec_helper', __FILE__)
7
+ require 'yaml'
8
+
9
+ describe JenkinsApi::Client do
10
+ context "Given valid credentials and server information are given" do
11
+ before(:all) do
12
+ @creds_file = '~/.jenkins_api_client/spec.yml'
13
+ # Grabbing just the server IP in a variable so we can check
14
+ # for wrong credentials
15
+ @server_ip = YAML.load_file(
16
+ File.expand_path(@creds_file, __FILE__)
17
+ )[:server_ip]
18
+ begin
19
+ @client = JenkinsApi::Client.new(
20
+ YAML.load_file(File.expand_path(@creds_file, __FILE__))
21
+ )
22
+ rescue Exception => e
23
+ puts "WARNING: Credentials are not set properly."
24
+ puts e.message
25
+ end
26
+ end
27
+
28
+ describe "InstanceMethods" do
29
+
30
+ describe "#debug" do
31
+ it "Should be able to toggle the debug value" do
32
+ value = @client.debug
33
+ @client.toggle_debug.should_not == value
34
+ end
35
+ end
36
+
37
+ describe "#initialize" do
38
+ it "Should be able to initialize with valid credentials" do
39
+ client1 = JenkinsApi::Client.new(
40
+ YAML.load_file(File.expand_path(@creds_file, __FILE__))
41
+ )
42
+ client1.class.should == JenkinsApi::Client
43
+ end
44
+
45
+ it "Should accept a YAML argument when creating a new client" do
46
+ client3 = JenkinsApi::Client.new(
47
+ YAML.load_file(File.expand_path(@creds_file, __FILE__))
48
+ )
49
+ client3.class.should == JenkinsApi::Client
50
+ end
51
+
52
+ it "Should fail if wrong credentials are given" do
53
+ begin
54
+ client2 = JenkinsApi::Client.new(:server_ip => @server_ip,
55
+ :username => 'stranger',
56
+ :password => 'hacked')
57
+ client2.job.list_all
58
+ rescue Exception => e
59
+ e.class.should == JenkinsApi::Exceptions::UnautherizedException
60
+ end
61
+ end
62
+ end
63
+
64
+ describe "#job" do
65
+ it "Should return a job object on call" do
66
+ @client.job.class.should == JenkinsApi::Client::Job
67
+ end
68
+ end
69
+
70
+ describe "#node" do
71
+ it "Should return a node object on call" do
72
+ @client.node.class.should == JenkinsApi::Client::Node
73
+ end
74
+ end
75
+
76
+ describe "#view" do
77
+ it "Should return a view object on call" do
78
+ @client.view.class.should == JenkinsApi::Client::View
79
+ end
80
+ end
81
+
82
+ describe "#system" do
83
+ it "Should return a system object on call" do
84
+ @client.system.class.should == JenkinsApi::Client::System
85
+ end
86
+ end
87
+ end
88
+
89
+ end
90
+ end
@@ -0,0 +1,348 @@
1
+ #
2
+ # Specifying JenkinsApi::Client::Job class capabilities
3
+ # Author: Kannan Manickam <arangamani.kannan@gmail.com>
4
+ #
5
+
6
+ require File.expand_path('../spec_helper', __FILE__)
7
+ require 'yaml'
8
+
9
+ describe JenkinsApi::Client::Job do
10
+ context "With properly initialized client" do
11
+ before(:all) do
12
+ @helper = JenkinsApiSpecHelper::Helper.new
13
+ @creds_file = '~/.jenkins_api_client/spec.yml'
14
+ @job_name_prefix = 'awesome_rspec_test_job'
15
+ @filter = "^#{@job_name_prefix}.*"
16
+ @job_name = ''
17
+ begin
18
+ @client = JenkinsApi::Client.new(
19
+ YAML.load_file(File.expand_path(@creds_file, __FILE__))
20
+ )
21
+ rescue Exception => e
22
+ puts "WARNING: Credentials are not set properly."
23
+ puts e.message
24
+ end
25
+ # Creating 10 jobs to run the spec tests on
26
+ begin
27
+ 10.times do |num|
28
+ xml = @helper.create_job_xml
29
+ job = "#{@job_name_prefix}_#{num}"
30
+ @job_name = job if num == 0
31
+ @client.job.create(job, xml).to_i.should == 200
32
+ end
33
+ rescue Exception => e
34
+ puts "WARNING: Can't create jobs for preparing to spec tests"
35
+ end
36
+ end
37
+
38
+ describe "InstanceMethods" do
39
+
40
+ describe "#initialize" do
41
+ it "Initializes without any exception" do
42
+ expect(
43
+ lambda { job = JenkinsApi::Client::Job.new(@client) }
44
+ ).not_to raise_error
45
+ end
46
+ it "Raises an error if a reference of client is not passed" do
47
+ expect(
48
+ lambda { job = JenkinsApi::Client::Job.new() }
49
+ ).to raise_error
50
+ end
51
+ end
52
+
53
+ describe "#create" do
54
+ it "Should be able to create a job by getting an xml" do
55
+ xml = @helper.create_job_xml
56
+ @client.job.create("qwerty_nonexistent_job", xml).to_i.should == 200
57
+ end
58
+ end
59
+
60
+ describe "#create_freestyle" do
61
+ it "Should be able to create a simple freestyle job" do
62
+ params = {
63
+ :name => "test_job_name_using_params"
64
+ }
65
+ @client.job.create_freestyle(params).to_i.should == 200
66
+ @client.job.delete("test_job_name_using_params").to_i.should == 302
67
+ end
68
+ it "Should be able to create a freestyle job with shell command" do
69
+ params = {
70
+ :name => "test_job_using_params_shell",
71
+ :shell_command => "echo this is a free style project"
72
+ }
73
+ @client.job.create_freestyle(params).to_i.should == 200
74
+ @client.job.delete("test_job_using_params_shell").to_i.should == 302
75
+ end
76
+ it "Should accept Git SCM provider" do
77
+ params = {
78
+ :name => "test_job_with_git_scm",
79
+ :scm_provider => "git",
80
+ :scm_url => "git://github.com./arangamani/jenkins_api_client.git",
81
+ :scm_branch => "master"
82
+ }
83
+ @client.job.create_freestyle(params).to_i.should == 200
84
+ @client.job.delete("test_job_with_git_scm").to_i.should == 302
85
+ end
86
+ it "Should accept subversion SCM provider" do
87
+ params = {
88
+ :name => "test_job_with_subversion_scm",
89
+ :scm_provider => "subversion",
90
+ :scm_url => "http://svn.freebsd.org/base/",
91
+ :scm_branch => "master"
92
+ }
93
+ @client.job.create_freestyle(params).to_i.should == 200
94
+ @client.job.delete("test_job_with_subversion_scm").to_i.should == 302
95
+ end
96
+ it "Should accept CVS SCM provider with branch" do
97
+ params = {
98
+ :name => "test_job_with_cvs_scm_branch",
99
+ :scm_provider => "cvs",
100
+ :scm_url => "http://cvs.NetBSD.org",
101
+ :scm_module => "src",
102
+ :scm_branch => "MAIN"
103
+ }
104
+ @client.job.create_freestyle(params).to_i.should == 200
105
+ @client.job.delete("test_job_with_cvs_scm_branch").to_i.should == 302
106
+ end
107
+ it "Should accept CVS SCM provider with tag" do
108
+ params = {
109
+ :name => "test_job_with_cvs_scm_tag",
110
+ :scm_provider => "cvs",
111
+ :scm_url => "http://cvs.NetBSD.org",
112
+ :scm_module => "src",
113
+ :scm_tag => "MAIN"
114
+ }
115
+ @client.job.create_freestyle(params).to_i.should == 200
116
+ @client.job.delete("test_job_with_cvs_scm_tag").to_i.should == 302
117
+ end
118
+ it "Should fail if unsupported SCM is specified" do
119
+ params = {
120
+ :name => "test_job_unsupported_scm",
121
+ :scm_provider => "non-existent",
122
+ :scm_url => "http://non-existent.com/non-existent.non",
123
+ :scm_branch => "master"
124
+ }
125
+ expect(
126
+ lambda{ @client.job.create_freestyle(params) }
127
+ ).to raise_error
128
+ end
129
+ it "Should accept restricted_node option" do
130
+ params = {
131
+ :name => "test_job_restricted_node",
132
+ :restricted_node => "master"
133
+ }
134
+ @client.job.create_freestyle(params).to_i.should == 200
135
+ @client.job.delete("test_job_restricted_node").to_i.should == 302
136
+ end
137
+ it "Should accept block_build_when_downstream_building option" do
138
+ params = {
139
+ :name => "test_job_block_build_when_downstream_building",
140
+ :block_build_when_downstream_building => true,
141
+ }
142
+ @client.job.create_freestyle(params).to_i.should == 200
143
+ @client.job.delete(
144
+ "test_job_block_build_when_downstream_building"
145
+ ).to_i.should == 302
146
+ end
147
+ it "Should accept block_build_when_upstream_building option" do
148
+ params = {
149
+ :name => "test_job_block_build_when_upstream_building",
150
+ :block_build_when_upstream_building => true
151
+ }
152
+ @client.job.create_freestyle(params).to_i.should == 200
153
+ @client.job.delete(
154
+ "test_job_block_build_when_upstream_building"
155
+ ).to_i.should == 302
156
+ end
157
+ it "Should accept concurrent_build option" do
158
+ params = {
159
+ :name => "test_job_concurrent_build",
160
+ :concurrent_build => true
161
+ }
162
+ @client.job.create_freestyle(params).to_i.should == 200
163
+ @client.job.delete("test_job_concurrent_build").to_i.should == 302
164
+ end
165
+ it "Should accept child projects option" do
166
+ params = {
167
+ :name => "test_job_child_projects",
168
+ :child_projects => @job_name,
169
+ :child_threshold => "success"
170
+ }
171
+ @client.job.create_freestyle(params).to_i.should == 200
172
+ @client.job.delete("test_job_child_projects").to_i.should == 302
173
+ end
174
+ it "Should accept notification_email option" do
175
+ params = {
176
+ :name => "test_job_notification_email",
177
+ :notification_email => "kannan@testdomain.com"
178
+ }
179
+ @client.job.create_freestyle(params).to_i.should == 200
180
+ @client.job.delete("test_job_notification_email").to_i.should == 302
181
+ end
182
+ end
183
+
184
+ describe "#recreate" do
185
+ it "Should be able to re-create a job" do
186
+ @client.job.recreate("qwerty_nonexistent_job").to_i.should == 200
187
+ end
188
+ end
189
+
190
+ describe "#change_description" do
191
+ it "Should be able to change the description of a job" do
192
+ @client.job.change_description("qwerty_nonexistent_job",
193
+ "The description has been changed by the spec test"
194
+ ).to_i.should == 200
195
+ end
196
+ end
197
+
198
+ describe "#delete" do
199
+ it "Should be able to delete a job" do
200
+ @client.job.delete("qwerty_nonexistent_job").to_i.should == 302
201
+ end
202
+ end
203
+
204
+ describe "#list_all" do
205
+ it "Should list all jobs" do
206
+ @client.job.list_all.class.should == Array
207
+ end
208
+ end
209
+
210
+ describe "#list" do
211
+ it "Should return job names based on the filter" do
212
+ names = @client.job.list(@filter)
213
+ names.class.should == Array
214
+ names.each { |name|
215
+ name.should match /#{@filter}/i
216
+ }
217
+ end
218
+ end
219
+
220
+ describe "#list_by_status" do
221
+ it "Should be able to list jobs by status" do
222
+ names = @client.job.list_by_status('success')
223
+ names.class.should == Array
224
+ names.each do |name|
225
+ status = @client.job.get_current_build_status(name)
226
+ status.should == 'success'
227
+ end
228
+ end
229
+ end
230
+
231
+ describe "#list_all_with_details" do
232
+ it "Should return all job names with details" do
233
+ @client.job.list_all_with_details.class.should == Array
234
+ end
235
+ end
236
+
237
+ describe "#list_details" do
238
+ it "Should list details of a particular job" do
239
+ job_name = @client.job.list(@filter)[0]
240
+ job_name.class.should == String
241
+ @client.job.list_details(job_name).class.should == Hash
242
+ end
243
+ end
244
+
245
+ describe "#get_upstream_projects" do
246
+ it "Should list upstream projects of the specified job" do
247
+ @client.job.get_upstream_projects(@job_name).class.should == Array
248
+ end
249
+ end
250
+
251
+ describe "#get_downstream_projects" do
252
+ it "Should list downstream projects of the specified job" do
253
+ @client.job.get_downstream_projects(@job_name).class.should == Array
254
+ end
255
+ end
256
+
257
+ describe "#get_builds" do
258
+ it "Should get builds of a specified job" do
259
+ @client.job.get_builds(@job_name).class.should == Array
260
+ end
261
+ end
262
+
263
+ describe "#get_current_build_status" do
264
+ it "Should obtain the current build status for the specified job" do
265
+ build_status = @client.job.get_current_build_status(@job_name)
266
+ build_status.class.should == String
267
+ valid_build_status = ["not_run",
268
+ "aborted",
269
+ "success",
270
+ "failure",
271
+ "unstable",
272
+ "running"]
273
+ valid_build_status.include?(build_status).should be_true
274
+ end
275
+ end
276
+
277
+ describe "#build" do
278
+ it "Should build the specified job" do
279
+ @client.job.get_current_build_status(
280
+ @job_name
281
+ ).should_not == "running"
282
+ response = @client.job.build(@job_name)
283
+ response.to_i.should == 302
284
+ # Sleep for 6 seconds so we don't hit the Jenkins quiet period (5
285
+ # seconds)
286
+ sleep 6
287
+ @client.job.get_current_build_status(@job_name).should == "running"
288
+ while @client.job.get_current_build_status(@job_name) == "running" do
289
+ # Waiting for this job to finish so it doesn't affect other tests
290
+ sleep 10
291
+ end
292
+ end
293
+ end
294
+
295
+ describe "#stop" do
296
+ it "Should be able to abort a recent build of a running job" do
297
+ @client.job.get_current_build_status(
298
+ @job_name
299
+ ).should_not == "running"
300
+ @client.job.build(@job_name)
301
+ sleep 6
302
+ @client.job.get_current_build_status(@job_name).should == "running"
303
+ sleep 5
304
+ @client.job.stop_build(@job_name).to_i.should == 302
305
+ sleep 5
306
+ @client.job.get_current_build_status(@job_name).should == "aborted"
307
+ end
308
+ end
309
+
310
+ describe "#restrict_to_node" do
311
+ it "Should be able to restrict a job to a node" do
312
+ @client.job.restrict_to_node(@job_name, 'master').to_i.should == 200
313
+ # Run it again to make sure that the replace existing node works
314
+ @client.job.restrict_to_node(@job_name, 'master').to_i.should == 200
315
+ end
316
+ end
317
+
318
+ describe "#chain" do
319
+ it "Should be able to chain all jobs" do
320
+ # Filter jobs to be chained
321
+ jobs = @client.job.list(@filter)
322
+ jobs.class.should == Array
323
+ start_jobs = @client.job.chain(jobs, 'success', ["all"])
324
+ start_jobs.class.should == Array
325
+ start_jobs.length.should == 1
326
+ end
327
+ it "Should be able to chain jobs based on the specified criteria" do
328
+ jobs = @client.job.list(@filter)
329
+ jobs.class.should == Array
330
+ start_jobs = @client.job.chain(jobs,
331
+ 'failure', ["not_run", "aborted", 'failure'], 3
332
+ )
333
+ start_jobs.class.should == Array
334
+ start_jobs.length.should == 3
335
+ end
336
+ end
337
+
338
+ end
339
+
340
+ after(:all) do
341
+ job_names = @client.job.list(@filter)
342
+ job_names.each { |job_name|
343
+ @client.job.delete(job_name)
344
+ }
345
+ end
346
+
347
+ end
348
+ end