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.
- data/.gitignore +3 -0
- data/.jenkins.yml +9 -0
- data/.travis.yml +11 -15
- data/CHANGELOG.md +15 -0
- data/Gemfile +2 -2
- data/README.md +7 -9
- data/Rakefile +27 -14
- data/lib/jenkins_api_client.rb +36 -6
- data/lib/jenkins_api_client/build_queue.rb +213 -0
- data/lib/jenkins_api_client/cli/base.rb +10 -6
- data/lib/jenkins_api_client/cli/helper.rb +13 -4
- data/lib/jenkins_api_client/cli/job.rb +6 -9
- data/lib/jenkins_api_client/cli/node.rb +6 -4
- data/lib/jenkins_api_client/cli/system.rb +2 -1
- data/lib/jenkins_api_client/client.rb +31 -25
- data/lib/jenkins_api_client/job.rb +248 -95
- data/lib/jenkins_api_client/node.rb +128 -10
- data/lib/jenkins_api_client/system.rb +4 -2
- data/lib/jenkins_api_client/version.rb +2 -2
- data/lib/jenkins_api_client/view.rb +17 -4
- data/scripts/login_with_irb.rb +4 -3
- data/spec/func_tests/client_spec.rb +90 -0
- data/spec/func_tests/job_spec.rb +348 -0
- data/spec/func_tests/node_spec.rb +174 -0
- data/spec/{spec_helper.rb → func_tests/spec_helper.rb} +2 -2
- data/spec/func_tests/system_spec.rb +55 -0
- data/spec/func_tests/view_spec.rb +53 -0
- data/spec/unit_tests/client_spec.rb +211 -0
- data/spec/unit_tests/fixtures/files/computer_sample.xml +17 -0
- data/spec/unit_tests/fixtures/files/job_sample.xml +16 -0
- data/spec/unit_tests/job_spec.rb +355 -0
- data/spec/unit_tests/node_spec.rb +192 -0
- data/spec/unit_tests/spec_helper.rb +8 -0
- data/spec/unit_tests/system_spec.rb +54 -0
- data/spec/unit_tests/view_spec.rb +127 -0
- metadata +34 -23
- data/spec/client_spec.rb +0 -52
- data/spec/job_spec.rb +0 -158
- data/spec/node_spec.rb +0 -48
- 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
|
105
|
-
|
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
|
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}"]
|
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
|
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
|
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
|
@@ -43,7 +43,10 @@ module JenkinsApi
|
|
43
43
|
# @param [String] view_name
|
44
44
|
#
|
45
45
|
def create(view_name)
|
46
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/scripts/login_with_irb.rb
CHANGED
@@ -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
|
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
|
-
|
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
|