jenkins_api_client 0.8.1 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +1 -0
- data/CHANGELOG.md +12 -0
- data/Rakefile +5 -0
- data/lib/jenkins_api_client/build_queue.rb +9 -6
- data/lib/jenkins_api_client/cli/base.rb +0 -1
- data/lib/jenkins_api_client/cli/system.rb +6 -0
- data/lib/jenkins_api_client/client.rb +73 -35
- data/lib/jenkins_api_client/exceptions.rb +6 -2
- data/lib/jenkins_api_client/job.rb +198 -124
- data/lib/jenkins_api_client/system.rb +7 -1
- data/lib/jenkins_api_client/version.rb +2 -2
- data/lib/jenkins_api_client/view.rb +2 -0
- data/scripts/login_with_irb.rb +1 -3
- data/spec/func_tests/client_spec.rb +25 -0
- data/spec/func_tests/job_spec.rb +31 -12
- data/spec/func_tests/node_spec.rb +18 -2
- data/spec/func_tests/system_spec.rb +10 -0
- data/spec/func_tests/view_spec.rb +166 -10
- data/spec/unit_tests/build_queue_spec.rb +148 -0
- data/spec/unit_tests/client_spec.rb +59 -35
- data/spec/unit_tests/job_spec.rb +16 -0
- data/spec/unit_tests/system_spec.rb +8 -0
- metadata +4 -3
@@ -65,11 +65,17 @@ module JenkinsApi
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
+
# Reload the Jenkins server
|
69
|
+
#
|
70
|
+
def reload
|
71
|
+
@client.api_post_request("/reload")
|
72
|
+
end
|
73
|
+
|
68
74
|
# This method waits till the server becomes ready after a start
|
69
75
|
# or restart.
|
70
76
|
#
|
71
77
|
def wait_for_ready
|
72
|
-
Timeout::timeout(
|
78
|
+
Timeout::timeout(@client.timeout) do
|
73
79
|
while true do
|
74
80
|
response = @client.get_root
|
75
81
|
puts "[INFO] Waiting for jenkins to restart..." if @client.debug
|
data/scripts/login_with_irb.rb
CHANGED
@@ -8,9 +8,7 @@ require 'yaml'
|
|
8
8
|
require 'irb'
|
9
9
|
|
10
10
|
begin
|
11
|
-
@client = JenkinsApi::Client.new(YAML.load_file(File.expand_path(
|
12
|
-
'~/.jenkins_api_client/spec.yml', __FILE__))
|
13
|
-
)
|
11
|
+
@client = JenkinsApi::Client.new(YAML.load_file(File.expand_path('~/.jenkins_api_client/login.yml', __FILE__)))
|
14
12
|
puts "logged-in to the Jenkins API, use the '@client' variable to use the client"
|
15
13
|
end
|
16
14
|
|
@@ -60,7 +60,26 @@ describe JenkinsApi::Client do
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
63
|
+
describe "#get_jenkins_version" do
|
64
|
+
it "Should the jenkins version" do
|
65
|
+
@client.get_jenkins_version.class.should == String
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#get_hudson_version" do
|
70
|
+
it "Should get the hudson version" do
|
71
|
+
@client.get_hudson_version.class.should == String
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#get_server_date" do
|
76
|
+
it "Should return the server date" do
|
77
|
+
@client.get_server_date.class.should == String
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
63
81
|
|
82
|
+
describe "SubClassAccessorMethods" do
|
64
83
|
describe "#job" do
|
65
84
|
it "Should return a job object on call" do
|
66
85
|
@client.job.class.should == JenkinsApi::Client::Job
|
@@ -84,6 +103,12 @@ describe JenkinsApi::Client do
|
|
84
103
|
@client.system.class.should == JenkinsApi::Client::System
|
85
104
|
end
|
86
105
|
end
|
106
|
+
|
107
|
+
describe "#queue" do
|
108
|
+
it "Should return a build queue object on call" do
|
109
|
+
@client.queue.class.should == JenkinsApi::Client::BuildQueue
|
110
|
+
end
|
111
|
+
end
|
87
112
|
end
|
88
113
|
|
89
114
|
end
|
data/spec/func_tests/job_spec.rb
CHANGED
@@ -53,7 +53,9 @@ describe JenkinsApi::Client::Job do
|
|
53
53
|
describe "#create" do
|
54
54
|
it "Should be able to create a job by getting an xml" do
|
55
55
|
xml = @helper.create_job_xml
|
56
|
-
|
56
|
+
name = "qwerty_nonexistent_job"
|
57
|
+
@client.job.create(name, xml).to_i.should == 200
|
58
|
+
@client.job.list(name).include?(name).should be_true
|
57
59
|
end
|
58
60
|
end
|
59
61
|
|
@@ -225,12 +227,23 @@ describe JenkinsApi::Client::Job do
|
|
225
227
|
end
|
226
228
|
end
|
227
229
|
|
230
|
+
describe "#add_email_notification" do
|
231
|
+
it "Should accept email address and add to existing job" do
|
232
|
+
name = "email_notification_test_job"
|
233
|
+
params = {:name => name}
|
234
|
+
@client.job.create_freestyle(params).to_i.should == 200
|
235
|
+
@client.job.add_email_notification(
|
236
|
+
:name => name,
|
237
|
+
:notification_email => "testuser@testdomain.com"
|
238
|
+
).to_i.should == 200
|
239
|
+
@client.job.delete(name).to_i.should == 302
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
228
243
|
describe "#add_skype_notification" do
|
229
244
|
it "Should accept skype configuration and add to existing job" do
|
230
245
|
name = "skype_notification_test_job"
|
231
|
-
params = {
|
232
|
-
:name => name
|
233
|
-
}
|
246
|
+
params = {:name => name}
|
234
247
|
@client.job.create_freestyle(params).to_i.should == 200
|
235
248
|
@client.job.add_skype_notification(
|
236
249
|
:name => name,
|
@@ -239,6 +252,7 @@ describe JenkinsApi::Client::Job do
|
|
239
252
|
@client.job.delete(name).to_i.should == 302
|
240
253
|
end
|
241
254
|
end
|
255
|
+
|
242
256
|
describe "#rename" do
|
243
257
|
it "Should accept new and old job names and rename the job" do
|
244
258
|
xml = @helper.create_job_xml
|
@@ -335,12 +349,14 @@ describe JenkinsApi::Client::Job do
|
|
335
349
|
it "Should obtain the current build status for the specified job" do
|
336
350
|
build_status = @client.job.get_current_build_status(@job_name)
|
337
351
|
build_status.class.should == String
|
338
|
-
valid_build_status = [
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
352
|
+
valid_build_status = [
|
353
|
+
"not_run",
|
354
|
+
"aborted",
|
355
|
+
"success",
|
356
|
+
"failure",
|
357
|
+
"unstable",
|
358
|
+
"running"
|
359
|
+
]
|
344
360
|
valid_build_status.include?(build_status).should be_true
|
345
361
|
end
|
346
362
|
end
|
@@ -398,8 +414,11 @@ describe JenkinsApi::Client::Job do
|
|
398
414
|
it "Should be able to chain jobs based on the specified criteria" do
|
399
415
|
jobs = @client.job.list(@filter)
|
400
416
|
jobs.class.should == Array
|
401
|
-
start_jobs = @client.job.chain(
|
402
|
-
|
417
|
+
start_jobs = @client.job.chain(
|
418
|
+
jobs,
|
419
|
+
'failure',
|
420
|
+
["not_run", "aborted", 'failure'],
|
421
|
+
3
|
403
422
|
)
|
404
423
|
start_jobs.class.should == Array
|
405
424
|
start_jobs.length.should == 3
|
@@ -43,14 +43,30 @@ describe JenkinsApi::Client::Node do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
describe "#create_dump_slave" do
|
46
|
+
|
47
|
+
def test_and_validate(params)
|
48
|
+
name = params[:name]
|
49
|
+
@client.node.create_dump_slave(params).to_i.should == 302
|
50
|
+
@client.node.list(name).include?(name).should be_true
|
51
|
+
@client.node.delete(params[:name]).to_i.should == 302
|
52
|
+
@client.node.list(name).include?(name).should be_false
|
53
|
+
end
|
54
|
+
|
46
55
|
it "accepts required params and creates the slave on jenkins" do
|
47
56
|
params = {
|
48
57
|
:name => "func_test_slave",
|
49
58
|
:slave_host => "10.10.10.10",
|
50
59
|
:private_key_file => "/root/.ssh/id_rsa"
|
51
60
|
}
|
52
|
-
|
53
|
-
|
61
|
+
test_and_validate(params)
|
62
|
+
end
|
63
|
+
it "accepts spaces and other characters in node name" do
|
64
|
+
params = {
|
65
|
+
:name => "slave with spaces and {special characters}",
|
66
|
+
:slave_host => "10.10.10.10",
|
67
|
+
:private_key_file => "/root/.ssh/id_rsa"
|
68
|
+
}
|
69
|
+
test_and_validate(params)
|
54
70
|
end
|
55
71
|
it "fails if name is missing" do
|
56
72
|
params = {
|
@@ -49,6 +49,16 @@ describe JenkinsApi::Client::System do
|
|
49
49
|
@client.system.wait_for_ready.should == true
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
describe "#reload" do
|
54
|
+
it "Should be able to reload a Jenkins server" do
|
55
|
+
@client.system.reload.to_i.should == 302
|
56
|
+
end
|
57
|
+
it "Should be able to wait after a force restart" do
|
58
|
+
@client.system.wait_for_ready.should == true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
52
62
|
end
|
53
63
|
|
54
64
|
end
|
@@ -19,6 +19,9 @@ describe JenkinsApi::Client::View do
|
|
19
19
|
puts "WARNING: Credentials are not set properly."
|
20
20
|
puts e.message
|
21
21
|
end
|
22
|
+
|
23
|
+
# Create a view that can be used for tests
|
24
|
+
@client.view.create("general_purpose_view").to_i.should == 302
|
22
25
|
end
|
23
26
|
|
24
27
|
describe "InstanceMethods" do
|
@@ -29,25 +32,178 @@ describe JenkinsApi::Client::View do
|
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
35
|
+
describe "#create" do
|
36
|
+
it "accepts the name of the view and creates the view" do
|
37
|
+
name = "test_view"
|
38
|
+
@client.view.create(name).to_i.should == 302
|
39
|
+
@client.view.list(name).include?(name).should be_true
|
40
|
+
@client.view.delete(name).to_i.should == 302
|
41
|
+
end
|
42
|
+
it "accepts spaces and other characters in the view name" do
|
43
|
+
name = "test view with spaces and {special characters}"
|
44
|
+
@client.view.create(name).to_i.should == 302
|
45
|
+
@client.view.list(name).include?(name).should be_true
|
46
|
+
@client.view.delete(name).to_i.should == 302
|
47
|
+
end
|
48
|
+
it "accepts the name of view and creates a listview" do
|
49
|
+
name = "test_view"
|
50
|
+
@client.view.create(name, "listview").to_i.should == 302
|
51
|
+
@client.view.list(name).include?(name).should be_true
|
52
|
+
@client.view.delete(name).to_i.should == 302
|
53
|
+
end
|
54
|
+
it "accepts the name of view and creates a myview" do
|
55
|
+
name = "test_view"
|
56
|
+
@client.view.create(name, "myview").to_i.should == 302
|
57
|
+
@client.view.list(name).include?(name).should be_true
|
58
|
+
@client.view.delete(name).to_i.should == 302
|
59
|
+
end
|
60
|
+
it "raises an error when unsupported view type is specified" do
|
61
|
+
expect(
|
62
|
+
lambda { @client.view.create(name, "awesomeview") }
|
63
|
+
).to raise_error
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#create_list_view" do
|
68
|
+
|
69
|
+
def test_and_validate(params)
|
70
|
+
name = params[:name]
|
71
|
+
@client.view.create_list_view(params).to_i.should == 302
|
72
|
+
@client.view.list(name).include?(name).should be_true
|
73
|
+
@client.view.delete(name).to_i.should == 302
|
74
|
+
@client.view.list(name).include?(name).should be_false
|
75
|
+
end
|
76
|
+
|
77
|
+
it "accepts just the name of the view and creates the view" do
|
78
|
+
params = {
|
79
|
+
:name => "test_list_view"
|
80
|
+
}
|
81
|
+
test_and_validate(params)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "accepts description as an option" do
|
85
|
+
params = {
|
86
|
+
:name => "test_list_view",
|
87
|
+
:description => "test list view created for functional test"
|
88
|
+
}
|
89
|
+
test_and_validate(params)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "accepts filter_queue as an option" do
|
93
|
+
params = {
|
94
|
+
:name => "test_list_view",
|
95
|
+
:filter_queue => true
|
96
|
+
}
|
97
|
+
test_and_validate(params)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "accepts filter_executors as an option" do
|
101
|
+
params = {
|
102
|
+
:name => "test_list_view",
|
103
|
+
:filter_executors => true
|
104
|
+
}
|
105
|
+
test_and_validate(params)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "accepts regex as an option" do
|
109
|
+
params = {
|
110
|
+
:name => "test_list_view",
|
111
|
+
:regex => "^test.*"
|
112
|
+
}
|
113
|
+
test_and_validate(params)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "#delete" do
|
118
|
+
name = "test_view_to_delete"
|
119
|
+
before(:all) do
|
120
|
+
@client.view.create(name).to_i.should == 302
|
121
|
+
end
|
122
|
+
it "accepts the name of the view and deletes from Jenkins" do
|
123
|
+
@client.view.list(name).include?(name).should be_true
|
124
|
+
@client.view.delete(name).to_i.should == 302
|
125
|
+
@client.view.list(name).include?(name).should be_false
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "#list_jobs" do
|
130
|
+
it "accepts the view name and lists all jobs in the view" do
|
131
|
+
@client.view.list_jobs("general_purpose_view").class.should == Array
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "#exists?" do
|
136
|
+
it "accepts the vie name and returns true if the view exists" do
|
137
|
+
@client.view.exists?("general_purpose_view").should be_true
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "#add_job" do
|
142
|
+
before(:all) do
|
143
|
+
@client.job.create_freestyle(
|
144
|
+
:name => "test_job_for_view"
|
145
|
+
).to_i.should == 200
|
146
|
+
end
|
147
|
+
it "accepts the job and and adds it to the specified view" do
|
148
|
+
@client.view.add_job(
|
149
|
+
"general_purpose_view",
|
150
|
+
"test_job_for_view"
|
151
|
+
).to_i.should == 200
|
152
|
+
@client.view.list_jobs(
|
153
|
+
"general_purpose_view"
|
154
|
+
).include?("test_job_for_view").should be_true
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe "#remove_job" do
|
159
|
+
before(:all) do
|
160
|
+
unless @client.job.exists?("test_job_for_view")
|
161
|
+
@client.job.create_freestyle(
|
162
|
+
:name => "test_job_for_view"
|
163
|
+
).to_i.should == 200
|
164
|
+
end
|
165
|
+
unless @client.view.list_jobs(
|
166
|
+
"general_purpose_view").include?("test_job_for_view")
|
167
|
+
@client.view.add_job(
|
168
|
+
"general_purpose_job",
|
169
|
+
"test_job_for_view"
|
170
|
+
).to_i.should == 200
|
171
|
+
end
|
172
|
+
end
|
173
|
+
it "accepts the job name and removes it from the specified view" do
|
174
|
+
@client.view.remove_job(
|
175
|
+
"general_purpose_view",
|
176
|
+
"test_job_for_view"
|
177
|
+
).to_i.should == 200
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
32
181
|
describe "#get_config" do
|
33
182
|
it "obtaines the view config.xml from the server" do
|
34
|
-
|
35
|
-
|
36
|
-
|
183
|
+
expect(
|
184
|
+
lambda { @client.view.get_config("general_purpose_view") }
|
185
|
+
).not_to raise_error
|
37
186
|
end
|
38
187
|
end
|
39
188
|
|
40
189
|
describe "#post_config" do
|
41
190
|
it "posts the given config.xml to the jenkins server's view" do
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
191
|
+
expect(
|
192
|
+
lambda {
|
193
|
+
xml = @client.view.get_config("general_purpose_view")
|
194
|
+
@client.view.post_config("general_purpose_view", xml)
|
195
|
+
}
|
196
|
+
).not_to raise_error
|
48
197
|
end
|
49
198
|
end
|
50
|
-
|
51
199
|
end
|
200
|
+
|
201
|
+
after(:all) do
|
202
|
+
@client.view.delete("general_purpose_view").to_i.should == 302
|
203
|
+
if @client.job.exists?("test_job_for_view")
|
204
|
+
@client.job.delete("test_job_for_view").to_i.should == 302
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
52
208
|
end
|
53
209
|
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe JenkinsApi::Client::BuildQueue do
|
4
|
+
context "With properly initialized Client" do
|
5
|
+
before do
|
6
|
+
@client = mock
|
7
|
+
@queue = JenkinsApi::Client::BuildQueue.new(@client)
|
8
|
+
@sample_queue_json = {
|
9
|
+
"items" => [
|
10
|
+
{
|
11
|
+
"actions" => [
|
12
|
+
{
|
13
|
+
"causes" => [
|
14
|
+
{
|
15
|
+
|
16
|
+
}
|
17
|
+
]
|
18
|
+
}
|
19
|
+
],
|
20
|
+
"blocked" => true,
|
21
|
+
"buildable" => false,
|
22
|
+
"id" => 2,
|
23
|
+
"inQueueSince" => 1362906942731,
|
24
|
+
"params" => "",
|
25
|
+
"stuck" => false,
|
26
|
+
"task" => {
|
27
|
+
"name" => "queue_test",
|
28
|
+
"url" => "http://localhost:8080/job/queue_test/",
|
29
|
+
"color" => "grey_anime"
|
30
|
+
},
|
31
|
+
"why" => "Build #1 is already in progress (ETA:N/A)",
|
32
|
+
"buildStartMilliseconds" => 1362906942832
|
33
|
+
}
|
34
|
+
]
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "InstanceMethods" do
|
39
|
+
describe "#initialize" do
|
40
|
+
it "initializes by receiving an instance of client object" do
|
41
|
+
expect(
|
42
|
+
lambda{ JenkinsApi::Client::BuildQueue.new(@client) }
|
43
|
+
).not_to raise_error
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#size" do
|
48
|
+
it "returns the size of the queue" do
|
49
|
+
@client.should_receive(:api_get_request).with("/queue").and_return(
|
50
|
+
@sample_queue_json
|
51
|
+
)
|
52
|
+
@queue.size
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#list" do
|
57
|
+
it "returns the list of tasks in the queue" do
|
58
|
+
@client.should_receive(:api_get_request).with("/queue").and_return(
|
59
|
+
@sample_queue_json
|
60
|
+
)
|
61
|
+
@queue.list.class.should == Array
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#get_age" do
|
66
|
+
it "returns the age of a task" do
|
67
|
+
@client.should_receive(:api_get_request).with("/queue").and_return(
|
68
|
+
@sample_queue_json
|
69
|
+
)
|
70
|
+
@queue.get_age("queue_test").class.should == Float
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#get_details" do
|
75
|
+
it "returns the details of a task in the queue" do
|
76
|
+
@client.should_receive(:api_get_request).with("/queue").and_return(
|
77
|
+
@sample_queue_json
|
78
|
+
)
|
79
|
+
@queue.get_details("queue_test").class.should == Hash
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#get_causes" do
|
84
|
+
it "returns the causes of a task in queue" do
|
85
|
+
@client.should_receive(:api_get_request).with("/queue").and_return(
|
86
|
+
@sample_queue_json
|
87
|
+
)
|
88
|
+
@queue.get_causes("queue_test").class.should == Array
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#get_reason" do
|
93
|
+
it "returns the reason of a task in queue" do
|
94
|
+
@client.should_receive(:api_get_request).with("/queue").and_return(
|
95
|
+
@sample_queue_json
|
96
|
+
)
|
97
|
+
@queue.get_reason("queue_test").class.should == String
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#get_eta" do
|
102
|
+
it "returns the ETA of a task in queue" do
|
103
|
+
@client.should_receive(:api_get_request).with("/queue").and_return(
|
104
|
+
@sample_queue_json
|
105
|
+
)
|
106
|
+
@queue.get_eta("queue_test").class.should == String
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "#get_params" do
|
111
|
+
it "returns the params of a task in queue" do
|
112
|
+
@client.should_receive(:api_get_request).with("/queue").and_return(
|
113
|
+
@sample_queue_json
|
114
|
+
)
|
115
|
+
@queue.get_params("queue_test").class.should == String
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "#is_buildable?" do
|
120
|
+
it "returns true if the job is buildable" do
|
121
|
+
@client.should_receive(:api_get_request).with("/queue").and_return(
|
122
|
+
@sample_queue_json
|
123
|
+
)
|
124
|
+
@queue.is_buildable?("queue_test").should == false
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "#is_blocked?" do
|
129
|
+
it "returns true if the job is blocked" do
|
130
|
+
@client.should_receive(:api_get_request).with("/queue").and_return(
|
131
|
+
@sample_queue_json
|
132
|
+
)
|
133
|
+
@queue.is_blocked?("queue_test").should == true
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "#is_stuck?" do
|
138
|
+
it "returns true if the job is stuck" do
|
139
|
+
@client.should_receive(:api_get_request).with("/queue").and_return(
|
140
|
+
@sample_queue_json
|
141
|
+
)
|
142
|
+
@queue.is_stuck?("queue_test").should == false
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|