dynport_tools 0.2.21 → 0.2.22
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/Gemfile +2 -1
- data/Gemfile.lock +9 -8
- data/VERSION +1 -1
- data/dynport_tools.gemspec +14 -7
- data/lib/dynport_tools/embedded_redis.rb +6 -2
- data/lib/dynport_tools/jenkins.rb +41 -211
- data/lib/dynport_tools/jenkins/project.rb +151 -0
- data/lib/dynport_tools/jenkins/remote_project.rb +67 -0
- data/spec/dynport_tools/embedded_redis_spec.rb +6 -5
- data/spec/dynport_tools/jenkins/project_spec.rb +211 -0
- data/spec/dynport_tools/jenkins/remote_project_spec.rb +83 -0
- data/spec/dynport_tools/jenkins_spec.rb +141 -280
- data/spec/dynport_tools/redis_q_spec.rb +36 -1
- data/spec/spec_helper.rb +2 -0
- metadata +82 -64
@@ -0,0 +1,67 @@
|
|
1
|
+
class DynportTools::Jenkins::RemoteProject
|
2
|
+
attr_accessor :url, :name, :xml
|
3
|
+
|
4
|
+
def self.from_details_hash(project_hash)
|
5
|
+
new(:url => project_hash[:url], :name => project_hash[:name], :xml => project_hash[:body])
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
options.each do |key, value|
|
10
|
+
self.send(:"#{key}=", value)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def doc
|
15
|
+
@doc ||= Nokogiri::XML(xml) if xml
|
16
|
+
end
|
17
|
+
|
18
|
+
def md5
|
19
|
+
Digest::MD5.hexdigest(xml) if xml
|
20
|
+
end
|
21
|
+
|
22
|
+
def days_to_keep
|
23
|
+
logrotate_value_when_set("daysToKeep")
|
24
|
+
end
|
25
|
+
|
26
|
+
def num_to_keep
|
27
|
+
logrotate_value_when_set("numToKeep")
|
28
|
+
end
|
29
|
+
|
30
|
+
def logrotate_value_when_set(key)
|
31
|
+
if node = doc.at("/project/logRotator/#{key}")
|
32
|
+
node.inner_text.to_i if node.inner_text.to_i != -1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def commands
|
37
|
+
doc.xpath("/project/builders/hudson.tasks.Shell/command").map(&:inner_text)
|
38
|
+
end
|
39
|
+
|
40
|
+
def crontab_patterns
|
41
|
+
doc.xpath("/project/triggers/hudson.triggers.TimerTrigger/spec").map(&:inner_text)
|
42
|
+
end
|
43
|
+
|
44
|
+
def disabled?
|
45
|
+
doc.at("/project/disabled/text()").to_s == "true"
|
46
|
+
end
|
47
|
+
|
48
|
+
def child_projects
|
49
|
+
if projects = doc.xpath("/project/publishers/hudson.tasks.BuildTrigger/childProjects").first
|
50
|
+
projects.inner_text.split(/\s*,\s*/)
|
51
|
+
else
|
52
|
+
[]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def email_addresses
|
57
|
+
doc.xpath("/project/publishers/hudson.tasks.Mailer/recipients").map { |rec| rec.inner_text.split(",") }.flatten
|
58
|
+
end
|
59
|
+
|
60
|
+
def node
|
61
|
+
doc.xpath("/project/assignedNode").map { |n| n.inner_text }.first
|
62
|
+
end
|
63
|
+
|
64
|
+
def locks
|
65
|
+
doc.xpath("/project/buildWrappers/hudson.plugins.locksandlatches.LockWrapper/locks/hudson.plugins.locksandlatches.LockWrapper_-LockWaitConfig/name").map(&:inner_text)
|
66
|
+
end
|
67
|
+
end
|
@@ -4,8 +4,9 @@ describe DynportTools::EmbeddedRedis do
|
|
4
4
|
let(:er) { DynportTools::EmbeddedRedis.instance }
|
5
5
|
|
6
6
|
before(:each) do
|
7
|
+
IO.stub(:popen)
|
7
8
|
er.logger = Logger.new("/dev/null")
|
8
|
-
|
9
|
+
DynportTools::EmbeddedRedis.stub!(:system)
|
9
10
|
er.stub!(:sleep)
|
10
11
|
er.stub!(:kill)
|
11
12
|
FileUtils.stub!(:mkdir_p)
|
@@ -25,7 +26,7 @@ describe DynportTools::EmbeddedRedis do
|
|
25
26
|
end
|
26
27
|
|
27
28
|
it "kills the proces" do
|
28
|
-
|
29
|
+
DynportTools::EmbeddedRedis.should_receive(:system).with("kill 123")
|
29
30
|
er.kill
|
30
31
|
end
|
31
32
|
|
@@ -49,12 +50,12 @@ describe DynportTools::EmbeddedRedis do
|
|
49
50
|
|
50
51
|
it "does not call system when killed" do
|
51
52
|
er.stub(:killed?).and_return true
|
52
|
-
|
53
|
+
DynportTools::EmbeddedRedis.should_not_receive(:system)
|
53
54
|
end
|
54
55
|
|
55
56
|
it "does not call system when pid is nil" do
|
56
57
|
er.stub(:pid?).and_return nil
|
57
|
-
|
58
|
+
DynportTools::EmbeddedRedis.should_not_receive(:system)
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
@@ -145,7 +146,7 @@ describe DynportTools::EmbeddedRedis do
|
|
145
146
|
|
146
147
|
it "starts redis" do
|
147
148
|
er.stub(:config).and_return "some config"
|
148
|
-
|
149
|
+
DynportTools::EmbeddedRedis.should_receive(:system).with(/echo "some config" \| redis-server -/)
|
149
150
|
er.do_start!
|
150
151
|
end
|
151
152
|
|
@@ -0,0 +1,211 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Project" do
|
4
|
+
let(:job) { DynportTools::Jenkins::Project.new("Some Name") }
|
5
|
+
let(:doc) { Nokogiri::XML(job.to_xml) }
|
6
|
+
|
7
|
+
describe "#initialize" do
|
8
|
+
it "sets the commands to an empty array" do
|
9
|
+
job.commands.should == []
|
10
|
+
end
|
11
|
+
|
12
|
+
it "sets the commands to an empty array" do
|
13
|
+
job.child_projects.should == []
|
14
|
+
end
|
15
|
+
|
16
|
+
it "sets the commands to an empty array" do
|
17
|
+
job.locks.should == []
|
18
|
+
end
|
19
|
+
|
20
|
+
it "sets the email addresses to an empty array" do
|
21
|
+
job.email_addresses.should == []
|
22
|
+
end
|
23
|
+
|
24
|
+
it "sets the name" do
|
25
|
+
job.name.should == "Some Name"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "allows setting othe deleted flag" do
|
29
|
+
job.delete = true
|
30
|
+
job.delete.should == true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns the correct status for deleted" do
|
35
|
+
job.should_not be_deleted
|
36
|
+
job.delete = true
|
37
|
+
job.should be_deleted
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#to_xml" do
|
41
|
+
it "returns a string" do
|
42
|
+
job.to_xml.should be_kind_of(String)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "includes a xml header line" do
|
46
|
+
job.to_xml.should include(%(<?xml version="1.0" encoding="UTF-8"?>))
|
47
|
+
end
|
48
|
+
|
49
|
+
it "includes a project root" do
|
50
|
+
job.to_xml.should include("<project>")
|
51
|
+
job.to_xml.should include("</project>")
|
52
|
+
end
|
53
|
+
|
54
|
+
%w(actions description properties publishers buildWrappers).each do |key|
|
55
|
+
it "includes an empty node #{key}" do
|
56
|
+
doc.at("/project/#{key}").children.should be_empty
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
it "adds a git entry when git is set" do
|
61
|
+
job.git_repository = "git@github.com:dynport/dynport_tools.git"
|
62
|
+
job.to_xml.should include(%(scm class="hudson.plugins.git.GitSCM">))
|
63
|
+
end
|
64
|
+
|
65
|
+
it "sets the correct email_addresses when present" do
|
66
|
+
job.email_addresses = %w(test@test.xx test2@test.xx)
|
67
|
+
doc.xpath("/project/publishers/hudson.tasks.Mailer/recipients").map(&:inner_text).should == ["test@test.xx,test2@test.xx"]
|
68
|
+
doc.at("/project/publishers/hudson.tasks.Mailer/dontNotifyEveryUnstableBuild").inner_text.should == "true"
|
69
|
+
doc.at("/project/publishers/hudson.tasks.Mailer/sendToIndividuals").inner_text.should == "false"
|
70
|
+
end
|
71
|
+
|
72
|
+
{
|
73
|
+
"keepDependencies" => "false",
|
74
|
+
"canRoam" => "true",
|
75
|
+
"disabled" => "false",
|
76
|
+
"blockBuildWhenDownstreamBuilding" => "false",
|
77
|
+
"blockBuildWhenUpstreamBuilding" => "false",
|
78
|
+
"concurrentBuild" => "false"
|
79
|
+
}.each do |key, value|
|
80
|
+
it "sets #{key} to #{value}" do
|
81
|
+
doc.at("/project/#{key}").inner_text.should == value
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it "sets disabled to true when set" do
|
86
|
+
job.disabled = true
|
87
|
+
doc.at("/project/disabled").inner_text.should == "true"
|
88
|
+
end
|
89
|
+
|
90
|
+
{ "scm" => "hudson.scm.NullSCM", "triggers" => "vector" }.each do |key, clazz|
|
91
|
+
it "sets the class of #{key} to #{clazz}" do
|
92
|
+
doc.at("/project/#{key}")["class"].should == clazz
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it "includes all set commands" do
|
97
|
+
job.commands << "hostname"
|
98
|
+
job.commands << "date"
|
99
|
+
shell_tasks = doc.search("project/builders/*")
|
100
|
+
shell_tasks.map(&:name).should == ["hudson.tasks.Shell", "hudson.tasks.Shell"]
|
101
|
+
shell_tasks.map { |node| node.at("command").inner_text }.should == ["hostname", "date"]
|
102
|
+
end
|
103
|
+
|
104
|
+
it "includes crontab like triggers" do
|
105
|
+
pattern = "0 2 * * *"
|
106
|
+
job.crontab_pattern = pattern
|
107
|
+
triggers = doc.search("project/triggers/*")
|
108
|
+
triggers.map(&:name).should == ["hudson.triggers.TimerTrigger"]
|
109
|
+
triggers.first.at("spec").inner_text.should == "0 2 * * *"
|
110
|
+
end
|
111
|
+
|
112
|
+
%w(logRotator assignedNode).each do |key|
|
113
|
+
it "does not include a #{key} node by default" do
|
114
|
+
doc.at("/project/#{key}").should be_nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
it "sets assignedNode when node is set" do
|
119
|
+
job.node = "processor"
|
120
|
+
doc.at("/project/assignedNode").inner_text.should == "processor"
|
121
|
+
doc.at("/project/canRoam").inner_text.should == "false"
|
122
|
+
end
|
123
|
+
|
124
|
+
it "allows setting a description" do
|
125
|
+
job.description = "some description"
|
126
|
+
doc.at("/project/description").inner_text.should == "some description"
|
127
|
+
end
|
128
|
+
|
129
|
+
it "returns the correct md5" do
|
130
|
+
job.stub(:to_xml).and_return "some test"
|
131
|
+
job.md5.should == "f1b75ac7689ff88e1ecc40c84b115785"
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "with days_to_keep set" do
|
135
|
+
before(:each) do
|
136
|
+
job.days_to_keep = 7
|
137
|
+
end
|
138
|
+
|
139
|
+
it "sets days_to_keep to 7" do
|
140
|
+
doc.at("/project/logRotator/daysToKeep").inner_text.should == "7"
|
141
|
+
end
|
142
|
+
|
143
|
+
%w(numToKeep artifactDaysToKeep artifactNumToKeep).each do |key|
|
144
|
+
it "sets #{key} to -1" do
|
145
|
+
doc.at("/project/logRotator/#{key}").inner_text.should == "-1"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "with num_to_keep set" do
|
151
|
+
before(:each) do
|
152
|
+
job.num_to_keep = 30
|
153
|
+
end
|
154
|
+
|
155
|
+
it "sets num_to_keep to 30" do
|
156
|
+
doc.at("/project/logRotator/numToKeep").inner_text.should == "30"
|
157
|
+
end
|
158
|
+
|
159
|
+
%w(daysToKeep artifactDaysToKeep artifactNumToKeep).each do |key|
|
160
|
+
it "sets #{key} to -1" do
|
161
|
+
doc.at("/project/logRotator/#{key}").inner_text.should == "-1"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
it "sets numToKeep and daysToKeep when both set" do
|
167
|
+
job.num_to_keep = 10
|
168
|
+
job.days_to_keep = 2
|
169
|
+
doc.at("/project/logRotator/numToKeep").inner_text.should == "10"
|
170
|
+
doc.at("/project/logRotator/daysToKeep").inner_text.should == "2"
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "with child projects" do
|
174
|
+
let(:child1) { DynportTools::Jenkins::Project.new("child 1") }
|
175
|
+
let(:child2) { DynportTools::Jenkins::Project.new("child 2") }
|
176
|
+
let(:triggers) { doc.xpath("/project/publishers/hudson.tasks.BuildTrigger") }
|
177
|
+
|
178
|
+
before(:each) do
|
179
|
+
job.child_projects << child2
|
180
|
+
job.child_projects << child1
|
181
|
+
end
|
182
|
+
|
183
|
+
it "includes all child projects" do
|
184
|
+
triggers.count.should == 1
|
185
|
+
triggers.first.at("childProjects").inner_text.should == "child 2,child 1"
|
186
|
+
end
|
187
|
+
|
188
|
+
{ "name" => "SUCCESS", "ordinal" => "0", "color" => "BLUE" }.each do |key, value|
|
189
|
+
it "sets #{key} to #{value} in threshold" do
|
190
|
+
triggers.first.at("threshold/#{key}").inner_text.should == value
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe "#with locks" do
|
196
|
+
let(:locks) { doc.xpath("/project/buildWrappers/hudson.plugins.locksandlatches.LockWrapper/locks/hudson.plugins.locksandlatches.LockWrapper_-LockWaitConfig") }
|
197
|
+
before(:each) do
|
198
|
+
job.locks << "exclusive3"
|
199
|
+
job.locks << "exclusive2"
|
200
|
+
end
|
201
|
+
|
202
|
+
it "sets the correct amount of locks" do
|
203
|
+
locks.count.should == 2
|
204
|
+
end
|
205
|
+
|
206
|
+
it "sets the correct locks" do
|
207
|
+
locks.map { |l| l.at("name").inner_text }.should == %w(exclusive3 exclusive2)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "RemoteProject" do
|
4
|
+
let(:remote_project) do
|
5
|
+
xml = File.read(root.join("spec/fixtures/jenkins_job.xml"))
|
6
|
+
remote_project = DynportTools::Jenkins::RemoteProject.new(:xml => xml)
|
7
|
+
remote_project
|
8
|
+
end
|
9
|
+
|
10
|
+
it "can be initialized" do
|
11
|
+
DynportTools::Jenkins::RemoteProject.new(:url => "some/url", :name => "Some Name").should return_values(:url => "some/url",
|
12
|
+
:name => "Some Name"
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "returns the correct " do
|
17
|
+
remote_project.commands.should == [%(ssh some.host \"touch /some/path/running.pid\")]
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns an empty array when no commands found" do
|
21
|
+
DynportTools::Jenkins::RemoteProject.new(:url => "some/url", :name => "Some Name", :xml => "<project/>").commands.should be_empty
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returns the correct crontab_patterns" do
|
25
|
+
remote_project.crontab_patterns.should == ["0 4 * * *"]
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns the correct childProjects" do
|
29
|
+
remote_project.child_projects.should == ["Project 2", "Project 6", "Prohect 9"]
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns the correct locks" do
|
33
|
+
remote_project.locks.should == %w(Import)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns the correct md5" do
|
37
|
+
remote_project.stub!(:xml).and_return "some xml"
|
38
|
+
remote_project.md5.should == "53bdfcda073f189a71901011123abf9a"
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "logrotate" do
|
42
|
+
it "returns the correct amount of days_to_keep" do
|
43
|
+
remote_project.days_to_keep.should == 7
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns nil when days_to_keep == -1" do
|
47
|
+
DynportTools::Jenkins::RemoteProject.new(:xml => "<project><logRotator><daysToKeep>-1</daysToKeep></logRotator></project>").days_to_keep.should be_nil
|
48
|
+
end
|
49
|
+
|
50
|
+
it "returns nil for num_to_keep when -1" do
|
51
|
+
remote_project.num_to_keep.should be_nil
|
52
|
+
end
|
53
|
+
|
54
|
+
it "returns the correct value for num_to_keep when set" do
|
55
|
+
DynportTools::Jenkins::RemoteProject.new(:xml => "<project><logRotator><numToKeep>20</numToKeep></logRotator></project>").num_to_keep.should == 20
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it "returns the correct disabled status" do
|
60
|
+
remote_project.should be_disabled
|
61
|
+
end
|
62
|
+
|
63
|
+
it "returns the correct email_addresses" do
|
64
|
+
remote_project.email_addresses.should == %w(test@test.xx)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "returns false when not disabled" do
|
68
|
+
DynportTools::Jenkins::RemoteProject.new(:xml => "<project><disabled>false</disabled></project>").should_not be_disabled
|
69
|
+
end
|
70
|
+
|
71
|
+
it "extracts the correct node" do
|
72
|
+
remote_project.node.should == "Import"
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#with nothing found" do
|
76
|
+
let(:empty_remote_project) { DynportTools::Jenkins::RemoteProject.new(:xml => "<project/>") }
|
77
|
+
[:child_projects, :commands, :crontab_patterns, :locks].each do |method|
|
78
|
+
it "returns an empty array for #{method}" do
|
79
|
+
empty_remote_project.send(method).should == []
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -3,289 +3,23 @@ require 'spec_helper'
|
|
3
3
|
describe "DynportTools::Jenkins" do
|
4
4
|
let(:url) { "http://some.url.com:8098" }
|
5
5
|
let(:jenkins) { DynportTools::Jenkins.new(url) }
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
let(:proj1) { double("proj1", :name => "proj1", :deleted? => false) }
|
7
|
+
let(:proj2) { double("proj2", :name => "proj2", :deleted? => true) }
|
8
|
+
let(:proj3) { double("proj3", :name => "proj3", :deleted? => true) }
|
9
|
+
let(:proj4) { double("proj4", :name => "proj4", :deleted? => false) }
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
it "can be initialized" do
|
18
|
-
DynportTools::Jenkins::RemoteProject.new(:url => "some/url", :name => "Some Name", :rgne => "true").should return_values(:url => "some/url",
|
19
|
-
:name => "Some Name"
|
20
|
-
)
|
21
|
-
end
|
22
|
-
|
23
|
-
it "returns the correct " do
|
24
|
-
remote_project.commands.should == [%(ssh some.host \"touch /some/path/running.pid\")]
|
25
|
-
end
|
26
|
-
|
27
|
-
it "returns an empty array when no commands found" do
|
28
|
-
DynportTools::Jenkins::RemoteProject.new(:url => "some/url", :name => "Some Name", :xml => "<project/>").commands.should be_empty
|
29
|
-
end
|
30
|
-
|
31
|
-
it "returns the correct crontab_patterns" do
|
32
|
-
remote_project.crontab_patterns.should == ["0 4 * * *"]
|
33
|
-
end
|
34
|
-
|
35
|
-
it "returns the correct childProjects" do
|
36
|
-
remote_project.child_projects.should == ["Project 2", "Project 6", "Prohect 9"]
|
37
|
-
end
|
38
|
-
|
39
|
-
it "returns the correct locks" do
|
40
|
-
remote_project.locks.should == %w(Import)
|
41
|
-
end
|
42
|
-
|
43
|
-
it "returns the correct md5" do
|
44
|
-
remote_project.stub!(:xml).and_return "some xml"
|
45
|
-
remote_project.md5.should == "53bdfcda073f189a71901011123abf9a"
|
46
|
-
end
|
47
|
-
|
48
|
-
describe "logrotate" do
|
49
|
-
it "returns the correct amount of days_to_keep" do
|
50
|
-
remote_project.days_to_keep.should == 7
|
51
|
-
end
|
52
|
-
|
53
|
-
it "returns nil when days_to_keep == -1" do
|
54
|
-
DynportTools::Jenkins::RemoteProject.new(:xml => "<project><logRotator><daysToKeep>-1</daysToKeep></logRotator></project>").days_to_keep.should be_nil
|
55
|
-
end
|
56
|
-
|
57
|
-
it "returns nil for num_to_keep when -1" do
|
58
|
-
remote_project.num_to_keep.should be_nil
|
59
|
-
end
|
60
|
-
|
61
|
-
it "returns the correct value for num_to_keep when set" do
|
62
|
-
DynportTools::Jenkins::RemoteProject.new(:xml => "<project><logRotator><numToKeep>20</numToKeep></logRotator></project>").num_to_keep.should == 20
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
it "returns the correct disabled status" do
|
67
|
-
remote_project.should be_disabled
|
68
|
-
end
|
69
|
-
|
70
|
-
it "returns the correct email_addresses" do
|
71
|
-
remote_project.email_addresses.should == %w(test@test.xx)
|
72
|
-
end
|
73
|
-
|
74
|
-
it "returns false when not disabled" do
|
75
|
-
DynportTools::Jenkins::RemoteProject.new(:xml => "<project><disabled>false</disabled></project>").should_not be_disabled
|
76
|
-
end
|
77
|
-
|
78
|
-
it "extracts the correct node" do
|
79
|
-
remote_project.node.should == "Import"
|
80
|
-
end
|
81
|
-
|
82
|
-
describe "#with nothing found" do
|
83
|
-
let(:empty_remote_project) { DynportTools::Jenkins::RemoteProject.new(:xml => "<project/>") }
|
84
|
-
[:child_projects, :commands, :crontab_patterns, :locks].each do |method|
|
85
|
-
it "returns an empty array for #{method}" do
|
86
|
-
empty_remote_project.send(method).should == []
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
11
|
+
let(:configured_projects_hash) do
|
12
|
+
{
|
13
|
+
"proj1" => proj1,
|
14
|
+
"proj2" => proj2, # deleted
|
15
|
+
"proj3" => proj3, # deleted
|
16
|
+
"proj4" => proj4,
|
17
|
+
}
|
90
18
|
end
|
91
19
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
describe "#initialize" do
|
97
|
-
it "sets the commands to an empty array" do
|
98
|
-
job.commands.should == []
|
99
|
-
end
|
100
|
-
|
101
|
-
it "sets the commands to an empty array" do
|
102
|
-
job.child_projects.should == []
|
103
|
-
end
|
104
|
-
|
105
|
-
it "sets the commands to an empty array" do
|
106
|
-
job.locks.should == []
|
107
|
-
end
|
108
|
-
|
109
|
-
it "sets the email addresses to an empty array" do
|
110
|
-
job.email_addresses.should == []
|
111
|
-
end
|
112
|
-
|
113
|
-
it "sets the name" do
|
114
|
-
job.name.should == "Some Name"
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
describe "#to_xml" do
|
119
|
-
it "returns a string" do
|
120
|
-
job.to_xml.should be_kind_of(String)
|
121
|
-
end
|
122
|
-
|
123
|
-
it "includes a xml header line" do
|
124
|
-
job.to_xml.should include(%(<?xml version="1.0" encoding="UTF-8"?>))
|
125
|
-
end
|
126
|
-
|
127
|
-
it "includes a project root" do
|
128
|
-
job.to_xml.should include("<project>")
|
129
|
-
job.to_xml.should include("</project>")
|
130
|
-
end
|
131
|
-
|
132
|
-
%w(actions description properties publishers buildWrappers).each do |key|
|
133
|
-
it "includes an empty node #{key}" do
|
134
|
-
doc.at("/project/#{key}").children.should be_empty
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
it "adds a git entry when git is set" do
|
139
|
-
job.git_repository = "git@github.com:dynport/dynport_tools.git"
|
140
|
-
job.to_xml.should include(%(scm class="hudson.plugins.git.GitSCM">))
|
141
|
-
end
|
142
|
-
|
143
|
-
it "sets the correct email_addresses when present" do
|
144
|
-
job.email_addresses = %w(test@test.xx test2@test.xx)
|
145
|
-
doc.xpath("/project/publishers/hudson.tasks.Mailer/recipients").map(&:inner_text).should == ["test@test.xx,test2@test.xx"]
|
146
|
-
doc.at("/project/publishers/hudson.tasks.Mailer/dontNotifyEveryUnstableBuild").inner_text.should == "true"
|
147
|
-
doc.at("/project/publishers/hudson.tasks.Mailer/sendToIndividuals").inner_text.should == "false"
|
148
|
-
end
|
149
|
-
|
150
|
-
{
|
151
|
-
"keepDependencies" => "false",
|
152
|
-
"canRoam" => "true",
|
153
|
-
"disabled" => "false",
|
154
|
-
"blockBuildWhenDownstreamBuilding" => "false",
|
155
|
-
"blockBuildWhenUpstreamBuilding" => "false",
|
156
|
-
"concurrentBuild" => "false"
|
157
|
-
}.each do |key, value|
|
158
|
-
it "sets #{key} to #{value}" do
|
159
|
-
doc.at("/project/#{key}").inner_text.should == value
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
it "sets disabled to true when set" do
|
164
|
-
job.disabled = true
|
165
|
-
doc.at("/project/disabled").inner_text.should == "true"
|
166
|
-
end
|
167
|
-
|
168
|
-
{ "scm" => "hudson.scm.NullSCM", "triggers" => "vector" }.each do |key, clazz|
|
169
|
-
it "sets the class of #{key} to #{clazz}" do
|
170
|
-
doc.at("/project/#{key}")["class"].should == clazz
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
it "includes all set commands" do
|
175
|
-
job.commands << "hostname"
|
176
|
-
job.commands << "date"
|
177
|
-
shell_tasks = doc.search("project/builders/*")
|
178
|
-
shell_tasks.map(&:name).should == ["hudson.tasks.Shell", "hudson.tasks.Shell"]
|
179
|
-
shell_tasks.map { |node| node.at("command").inner_text }.should == ["hostname", "date"]
|
180
|
-
end
|
181
|
-
|
182
|
-
it "includes crontab like triggers" do
|
183
|
-
pattern = "0 2 * * *"
|
184
|
-
job.crontab_pattern = pattern
|
185
|
-
triggers = doc.search("project/triggers/*")
|
186
|
-
triggers.map(&:name).should == ["hudson.triggers.TimerTrigger"]
|
187
|
-
triggers.first.at("spec").inner_text.should == "0 2 * * *"
|
188
|
-
end
|
189
|
-
|
190
|
-
%w(logRotator assignedNode).each do |key|
|
191
|
-
it "does not include a #{key} node by default" do
|
192
|
-
doc.at("/project/#{key}").should be_nil
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
it "sets assignedNode when node is set" do
|
197
|
-
job.node = "processor"
|
198
|
-
doc.at("/project/assignedNode").inner_text.should == "processor"
|
199
|
-
doc.at("/project/canRoam").inner_text.should == "false"
|
200
|
-
end
|
201
|
-
|
202
|
-
it "allows setting a description" do
|
203
|
-
job.description = "some description"
|
204
|
-
doc.at("/project/description").inner_text.should == "some description"
|
205
|
-
end
|
206
|
-
|
207
|
-
it "returns the correct md5" do
|
208
|
-
job.stub(:to_xml).and_return "some test"
|
209
|
-
job.md5.should == "f1b75ac7689ff88e1ecc40c84b115785"
|
210
|
-
end
|
211
|
-
|
212
|
-
describe "with days_to_keep set" do
|
213
|
-
before(:each) do
|
214
|
-
job.days_to_keep = 7
|
215
|
-
end
|
216
|
-
|
217
|
-
it "sets days_to_keep to 7" do
|
218
|
-
doc.at("/project/logRotator/daysToKeep").inner_text.should == "7"
|
219
|
-
end
|
220
|
-
|
221
|
-
%w(numToKeep artifactDaysToKeep artifactNumToKeep).each do |key|
|
222
|
-
it "sets #{key} to -1" do
|
223
|
-
doc.at("/project/logRotator/#{key}").inner_text.should == "-1"
|
224
|
-
end
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
describe "with num_to_keep set" do
|
229
|
-
before(:each) do
|
230
|
-
job.num_to_keep = 30
|
231
|
-
end
|
232
|
-
|
233
|
-
it "sets num_to_keep to 30" do
|
234
|
-
doc.at("/project/logRotator/numToKeep").inner_text.should == "30"
|
235
|
-
end
|
236
|
-
|
237
|
-
%w(daysToKeep artifactDaysToKeep artifactNumToKeep).each do |key|
|
238
|
-
it "sets #{key} to -1" do
|
239
|
-
doc.at("/project/logRotator/#{key}").inner_text.should == "-1"
|
240
|
-
end
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
it "sets numToKeep and daysToKeep when both set" do
|
245
|
-
job.num_to_keep = 10
|
246
|
-
job.days_to_keep = 2
|
247
|
-
doc.at("/project/logRotator/numToKeep").inner_text.should == "10"
|
248
|
-
doc.at("/project/logRotator/daysToKeep").inner_text.should == "2"
|
249
|
-
end
|
250
|
-
|
251
|
-
describe "with child projects" do
|
252
|
-
let(:child1) { DynportTools::Jenkins::Project.new("child 1") }
|
253
|
-
let(:child2) { DynportTools::Jenkins::Project.new("child 2") }
|
254
|
-
let(:triggers) { doc.xpath("/project/publishers/hudson.tasks.BuildTrigger") }
|
255
|
-
|
256
|
-
before(:each) do
|
257
|
-
job.child_projects << child2
|
258
|
-
job.child_projects << child1
|
259
|
-
end
|
260
|
-
|
261
|
-
it "includes all child projects" do
|
262
|
-
triggers.count.should == 1
|
263
|
-
triggers.first.at("childProjects").inner_text.should == "child 2,child 1"
|
264
|
-
end
|
265
|
-
|
266
|
-
{ "name" => "SUCCESS", "ordinal" => "0", "color" => "BLUE" }.each do |key, value|
|
267
|
-
it "sets #{key} to #{value} in threshold" do
|
268
|
-
triggers.first.at("threshold/#{key}").inner_text.should == value
|
269
|
-
end
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
describe "#with locks" do
|
274
|
-
let(:locks) { doc.xpath("/project/buildWrappers/hudson.plugins.locksandlatches.LockWrapper/locks/hudson.plugins.locksandlatches.LockWrapper_-LockWaitConfig") }
|
275
|
-
before(:each) do
|
276
|
-
job.locks << "exclusive3"
|
277
|
-
job.locks << "exclusive2"
|
278
|
-
end
|
279
|
-
|
280
|
-
it "sets the correct amount of locks" do
|
281
|
-
locks.count.should == 2
|
282
|
-
end
|
283
|
-
|
284
|
-
it "sets the correct locks" do
|
285
|
-
locks.map { |l| l.at("name").inner_text }.should == %w(exclusive3 exclusive2)
|
286
|
-
end
|
287
|
-
end
|
288
|
-
end
|
20
|
+
|
21
|
+
before(:each) do
|
22
|
+
Typhoeus::Request.stub!(:post).and_return nil
|
289
23
|
end
|
290
24
|
|
291
25
|
describe "#initialize" do
|
@@ -398,11 +132,138 @@ describe "DynportTools::Jenkins" do
|
|
398
132
|
}
|
399
133
|
end
|
400
134
|
end
|
135
|
+
|
136
|
+
describe "#configured_projects_hash" do
|
137
|
+
it "returns an empty array by default" do
|
138
|
+
jenkins.configured_projects_hash.should == {}
|
139
|
+
end
|
140
|
+
|
141
|
+
it "allows adding of projects to the configured_projects_hash array" do
|
142
|
+
jenkins.configured_projects_hash[:a] = 1
|
143
|
+
jenkins.configured_projects_hash[:b] = 2
|
144
|
+
jenkins.configured_projects_hash.should == { :a => 1, :b => 2 }
|
145
|
+
jenkins.clear_cache
|
146
|
+
jenkins.configured_projects_hash.should == { :a => 1, :b => 2 }
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "#projects_to_delete" do
|
151
|
+
it "returns an array" do
|
152
|
+
remote_projects = {
|
153
|
+
"proj1" => proj1,
|
154
|
+
"proj3" => proj3,
|
155
|
+
}
|
156
|
+
jenkins.stub!(:remote_projects).and_return(remote_projects)
|
157
|
+
configured_projects = {
|
158
|
+
"proj1" => proj1,
|
159
|
+
"proj2" => proj2,
|
160
|
+
"proj3" => proj3,
|
161
|
+
}
|
162
|
+
jenkins.stub!(:configured_projects_hash).and_return(configured_projects)
|
163
|
+
jenkins.projects_to_delete.should == [proj3]
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe "#projects_to_create" do
|
168
|
+
before(:each) do
|
169
|
+
jenkins.stub!(:remote_projects).and_return({})
|
170
|
+
jenkins.stub!(:configured_projects_hash).and_return({})
|
171
|
+
end
|
172
|
+
|
173
|
+
it "returns an empty hash when both empty" do
|
174
|
+
jenkins.projects_to_create.should {}
|
175
|
+
end
|
176
|
+
|
177
|
+
it "returns an empty hash when all configured projects are deleted" do
|
178
|
+
proj = double("proj", :deleted? => false, :name => "proj")
|
179
|
+
jenkins.stub!(:configured_projects_hash).and_return("proj" => proj)
|
180
|
+
jenkins.projects_to_create.should == [proj]
|
181
|
+
proj.stub!(:deleted?).and_return(true)
|
182
|
+
jenkins.projects_to_create.should == []
|
183
|
+
end
|
184
|
+
|
185
|
+
it "returns the correct array" do
|
186
|
+
jenkins.stub!(:configured_projects_hash).and_return(configured_projects_hash)
|
187
|
+
jenkins.projects_to_create.sort_by(&:name).should == [proj1, proj4]
|
188
|
+
remote_projects = {
|
189
|
+
"proj1" => proj1,
|
190
|
+
"proj3" => proj3,
|
191
|
+
}
|
192
|
+
jenkins.stub!(:remote_projects).and_return(remote_projects)
|
193
|
+
jenkins.projects_to_create.should == [proj4]
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
describe "#not_configured_projects" do
|
198
|
+
before(:each) do
|
199
|
+
jenkins.stub!(:remote_projects).and_return({})
|
200
|
+
end
|
201
|
+
|
202
|
+
it "rerturns an empty array by default" do
|
203
|
+
jenkins.not_configured_projects.should == []
|
204
|
+
end
|
205
|
+
|
206
|
+
it "includes all remote projects which do not exists locally" do
|
207
|
+
proj_a = double("project_a", :name => "a")
|
208
|
+
proj_b = double("project_b", :name => "b")
|
209
|
+
jenkins.stub!(:remote_projects).and_return(
|
210
|
+
"a" => proj_a,
|
211
|
+
"b" => proj_b
|
212
|
+
)
|
213
|
+
jenkins.not_configured_projects.sort_by(&:name).should == [proj_a, proj_b]
|
214
|
+
jenkins.stub!(:configured_projects_hash).and_return(
|
215
|
+
"b" => double("locale b", :name => "b")
|
216
|
+
)
|
217
|
+
jenkins.not_configured_projects.sort_by(&:name).should == [proj_a]
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
describe "#projects_to_update" do
|
222
|
+
before(:each) do
|
223
|
+
jenkins.stub!(:remote_projects).and_return({})
|
224
|
+
end
|
225
|
+
|
226
|
+
it "returns an empty array when remote_projects is empty" do
|
227
|
+
jenkins.projects_to_update.should be_empty
|
228
|
+
end
|
229
|
+
|
230
|
+
it "returns an empty array when configured projects is not empty but remote_projects is empty" do
|
231
|
+
jenkins.stub!(:configured_projects_hash).and_return(configured_projects_hash)
|
232
|
+
jenkins.projects_to_update.sort_by(&:name).should be_empty
|
233
|
+
end
|
234
|
+
|
235
|
+
it "returns the correct projects when changed" do
|
236
|
+
jenkins.stub!(:remote_projects).and_return(
|
237
|
+
"a" => double("remote_a", :md5 => "a_remote", :deleted? => false),
|
238
|
+
"b" => double("remote_b", :md5 => "b_remote", :deleted? => false),
|
239
|
+
"c" => double("remote_c", :md5 => "c_remote", :deleted? => false)
|
240
|
+
)
|
241
|
+
locale_c = double("local_c", :md5 => "c_remote", :deleted? => false, :name => "c")
|
242
|
+
jenkins.stub!(:configured_projects_hash).and_return(
|
243
|
+
"a" => double("local_a", :md5 => "a_remote", :deleted? => false, :name => "a"),
|
244
|
+
"b" => double("local_b", :md5 => "b_remote", :deleted? => false, :name => "b"),
|
245
|
+
"c" => locale_c
|
246
|
+
)
|
247
|
+
jenkins.projects_to_update.sort_by(&:name).should == []
|
248
|
+
jenkins.configured_projects_hash["c"].stub!(:md5).and_return("c_locale")
|
249
|
+
jenkins.projects_to_update.should == [locale_c]
|
250
|
+
|
251
|
+
locale_c.stub!(:deleted?).and_return(true)
|
252
|
+
jenkins.projects_to_update.should == []
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
it "allows setting of the configured_projects_hash" do
|
257
|
+
jenkins.configured_projects_hash.should == {}
|
258
|
+
jenkins.configured_projects_hash = { :a => 1 }
|
259
|
+
jenkins.configured_projects_hash.should == { :a => 1 }
|
260
|
+
end
|
401
261
|
|
402
262
|
describe "#remote_projects" do
|
403
263
|
before(:each) do
|
404
264
|
jenkins.stub(:project_details).and_return({})
|
405
265
|
end
|
266
|
+
|
406
267
|
it "calls project_details" do
|
407
268
|
jenkins.should_receive(:project_details).and_return({})
|
408
269
|
jenkins.remote_projects
|