dynport_tools 0.2.8 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.8
1
+ 0.2.9
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{dynport_tools}
8
- s.version = "0.2.8"
8
+ s.version = "0.2.9"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Tobias Schwab"]
12
- s.date = %q{2011-08-23}
12
+ s.date = %q{2011-08-24}
13
13
  s.description = %q{Collection of various tools}
14
14
  s.email = %q{tobias.schwab@dynport.de}
15
15
  s.executables = ["xmldiff", "redis_dumper"]
data/lib/dynport_tools.rb CHANGED
@@ -1,4 +1,9 @@
1
1
  module DynportTools
2
2
  end
3
3
 
4
+ require "time"
5
+ require "typhoeus"
6
+ require "nokogiri"
7
+ require "cgi"
8
+
4
9
  %w(deep_merger differ jenkins redis_dumper xml_file have_attributes redis_q eta).map { |m| require "dynport_tools/#{m}" }
@@ -38,7 +38,7 @@ class DynportTools::ETA
38
38
  end
39
39
 
40
40
  def to_s
41
- "%.1f%%, %.1f/second, ETA: %s" % [percs * 100, per_second, eta.iso8601]
41
+ "%.2f%%, %.2f/second, ETA: %s" % [percs * 100, per_second, eta.iso8601]
42
42
  end
43
43
 
44
44
  def raise_error_when_current_or_total_not_set
@@ -1,6 +1,3 @@
1
- require "typhoeus"
2
- require "nokogiri"
3
-
4
1
  class DynportTools::Jenkins
5
2
  attr_accessor :url
6
3
 
@@ -12,8 +9,49 @@ class DynportTools::Jenkins
12
9
  @hydra ||= Typhoeus::Hydra.new
13
10
  end
14
11
 
15
- def jobs_hash
16
- Nokogiri::XML(Typhoeus::Request.get("#{url}/api/xml").body).search("job").inject({}) do |hash, node|
12
+ def create_project(name, xml)
13
+ post_request "createItem?name=#{escape_job_name(name)}", :headers => { "Content-Type" => "application/xml" }, :body => xml
14
+ end
15
+
16
+ def update_project(name, xml)
17
+ post_request "job/#{escape_job_name(name)}/config.xml", :headers => { "Content-Type" => "application/xml" }, :body => xml
18
+ end
19
+
20
+ def delete_project(name)
21
+ send_to_project(name, "doDelete")
22
+ end
23
+
24
+ def build_project(name)
25
+ send_to_project(name, "build")
26
+ end
27
+
28
+ def disable_project(name)
29
+ send_to_project(name, "disable")
30
+ end
31
+
32
+ def enable_project(name)
33
+ send_to_project(name, "enable")
34
+ end
35
+
36
+ def send_to_project(name, action)
37
+ post_request "job/#{escape_job_name(name)}/#{action}"
38
+ end
39
+
40
+ def post_request(path, options = nil)
41
+ @cache = {}
42
+ Typhoeus::Request.post(*["#{url}/#{path}", options].compact)
43
+ end
44
+
45
+ def cache
46
+ @cache ||= {}
47
+ end
48
+
49
+ def escape_job_name(name)
50
+ URI.escape(name)
51
+ end
52
+
53
+ def projects_hash
54
+ cache[:projects_hash] ||= Nokogiri::XML(Typhoeus::Request.get("#{url}/api/xml").body).search("job").inject({}) do |hash, node|
17
55
  url = node.at("url").inner_text.strip if node.at("url")
18
56
  name = node.at("name").inner_text.strip if node.at("name")
19
57
  hash[url] = { :url => url, :name => name }
@@ -21,9 +59,10 @@ class DynportTools::Jenkins
21
59
  end
22
60
  end
23
61
 
24
- def job_details
62
+ def project_details
63
+ return cache[:projects_details] if cache[:projects_details]
25
64
  jobs = {}
26
- jobs_hash.each do |url, job|
65
+ projects_hash.each do |url, job|
27
66
  request = Typhoeus::Request.new("#{url}config.xml")
28
67
  request.on_complete do |response|
29
68
  xml = Nokogiri::XML(response.body).to_s
@@ -32,24 +71,100 @@ class DynportTools::Jenkins
32
71
  hydra.queue(request)
33
72
  end
34
73
  hydra.run
35
- jobs
74
+ cache[:projects_details] = jobs
75
+ end
76
+
77
+ def remote_projects
78
+ project_details.inject({}) do |hash, (url, project_hash)|
79
+ hash.merge!(project_hash[:name] => RemoteProject.new(:url => project_hash[:url], :name => project_hash[:name], :xml => project_hash[:body]))
80
+ end
81
+ end
82
+
83
+ class RemoteProject
84
+ attr_accessor :url, :name, :xml
85
+
86
+ def initialize(options = {})
87
+ options.each do |key, value|
88
+ self.send(:"#{key}=", value) if self.respond_to?(:"#{key}=")
89
+ end
90
+ end
91
+
92
+ def doc
93
+ @doc ||= Nokogiri::XML(xml) if xml
94
+ end
95
+
96
+ def md5
97
+ Digest::MD5.hexdigest(xml) if xml
98
+ end
99
+
100
+ def days_to_keep
101
+ logrotate_value_when_set("daysToKeep")
102
+ end
103
+
104
+ def num_to_keep
105
+ logrotate_value_when_set("numToKeep")
106
+ end
107
+
108
+ def logrotate_value_when_set(key)
109
+ if node = doc.at("/project/logRotator/#{key}")
110
+ node.inner_text.to_i if node.inner_text.to_i != -1
111
+ end
112
+ end
113
+
114
+ def commands
115
+ doc.xpath("/project/builders/hudson.tasks.Shell/command").map(&:inner_text)
116
+ end
117
+
118
+ def crontab_patterns
119
+ doc.xpath("/project/triggers/hudson.triggers.TimerTrigger/spec").map(&:inner_text)
120
+ end
121
+
122
+ def disabled?
123
+ doc.at("/project/disabled/text()").to_s == "true"
124
+ end
125
+
126
+ def child_projects
127
+ if projects = doc.xpath("/project/publishers/hudson.tasks.BuildTrigger/childProjects").first
128
+ projects.inner_text.split(/\s*,\s*/)
129
+ else
130
+ []
131
+ end
132
+ end
133
+
134
+ def email_addresses
135
+ doc.xpath("/project/publishers/hudson.tasks.Mailer/recipients").map { |rec| rec.inner_text.split(",") }.flatten
136
+ end
137
+
138
+ def node
139
+ doc.xpath("/project/assignedNode").map { |n| n.inner_text }.first
140
+ end
141
+
142
+ def locks
143
+ doc.xpath("/project/buildWrappers/hudson.plugins.locksandlatches.LockWrapper/locks/hudson.plugins.locksandlatches.LockWrapper_-LockWaitConfig/name").map(&:inner_text)
144
+ end
36
145
  end
37
146
 
38
147
  class Project
39
- attr_accessor :name, :commands, :crontab_pattern, :days_to_keep, :num_to_keep, :node, :child_projects
148
+ attr_accessor :name, :commands, :crontab_pattern, :days_to_keep, :num_to_keep, :node, :child_projects, :locks, :disabled, :description, :email_addresses
40
149
  DEFAUL_SCM = "hudson.scm.NullSCM"
41
150
 
42
- def initialize(name)
151
+ def initialize(name = nil)
43
152
  self.name = name
44
153
  self.commands = []
45
154
  self.child_projects = []
155
+ self.email_addresses = []
156
+ self.locks = []
157
+ end
158
+
159
+ def md5
160
+ Digest::MD5.hexdigest(to_xml)
46
161
  end
47
162
 
48
163
  def to_xml
49
164
  Nokogiri::XML::Builder.new(:encoding => "UTF-8") do |xml|
50
165
  xml.project do
51
166
  xml.actions
52
- xml.description
167
+ xml.description *[description].compact
53
168
  if days_to_keep || num_to_keep
54
169
  xml.logRotator do
55
170
  xml.daysToKeep days_to_keep || -1
@@ -58,14 +173,18 @@ class DynportTools::Jenkins
58
173
  xml.artifactNumToKeep -1
59
174
  end
60
175
  end
61
- xml.keepDependencies "false"
176
+ xml.keepDependencies false
62
177
  xml.properties
63
178
  xml.scm(:class => DEFAUL_SCM)
64
- xml.assignedNode node if node
65
- xml.canRoam "true"
66
- xml.disabled "false"
67
- xml.blockBuildWhenDownstreamBuilding "false"
68
- xml.blockBuildWhenUpstreamBuilding "false"
179
+ if node
180
+ xml.assignedNode node
181
+ xml.canRoam false
182
+ else
183
+ xml.canRoam true
184
+ end
185
+ xml.disabled disabled ? true : false
186
+ xml.blockBuildWhenDownstreamBuilding false
187
+ xml.blockBuildWhenUpstreamBuilding false
69
188
  xml.triggers(:class => "vector") do
70
189
  if crontab_pattern
71
190
  xml.send("hudson.triggers.TimerTrigger") do
@@ -73,11 +192,11 @@ class DynportTools::Jenkins
73
192
  end
74
193
  end
75
194
  end
76
- xml.concurrentBuild "false"
195
+ xml.concurrentBuild false
77
196
  xml.builders do
78
197
  commands.each do |command|
79
198
  xml.send("hudson.tasks.Shell") do
80
- xml.command ["#!/bin/sh", command].join("\n")
199
+ xml.command command
81
200
  end
82
201
  end
83
202
  end
@@ -92,8 +211,24 @@ class DynportTools::Jenkins
92
211
  end
93
212
  end
94
213
  end
214
+ if email_addresses.any?
215
+ xml.send("hudson.tasks.Mailer") do
216
+ xml.recipients email_addresses.join(",")
217
+ xml.dontNotifyEveryUnstableBuild true
218
+ xml.sendToIndividuals false
219
+ end
220
+ end
95
221
  end
96
222
  xml.buildWrappers do
223
+ if locks.any?
224
+ xml.send("hudson.plugins.locksandlatches.LockWrapper") do
225
+ xml.locks do
226
+ locks.each do |lock|
227
+ xml.send("hudson.plugins.locksandlatches.LockWrapper_-LockWaitConfig") { xml.name lock }
228
+ end
229
+ end
230
+ end
231
+ end
97
232
  end
98
233
  end
99
234
  end.to_xml
@@ -1,10 +1,15 @@
1
1
  require "nokogiri"
2
2
 
3
3
  class DynportTools::XmlFile
4
- attr_accessor :path
4
+ attr_accessor :path, :content
5
5
 
6
- def initialize(path)
7
- self.path = path.to_s
6
+ def initialize(path_or_options = nil)
7
+ if path_or_options.is_a?(Hash)
8
+ self.path = path_or_options[:path].to_s if path_or_options[:path].to_s
9
+ self.content = path_or_options[:content]
10
+ elsif !path_or_options.nil?
11
+ self.path = path_or_options.to_s
12
+ end
8
13
  end
9
14
 
10
15
  def nodes_hash
@@ -12,7 +17,7 @@ class DynportTools::XmlFile
12
17
  end
13
18
 
14
19
  def doc
15
- @doc ||= Nokogiri::XML(File.open(path))
20
+ @doc ||= Nokogiri::XML(content || File.open(path))
16
21
  end
17
22
 
18
23
  def parse_node(node)
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require "time"
3
2
 
4
3
  describe "DynportTools::ETA" do
5
4
  let(:eta) { DynportTools::ETA.new(:current => 17, :total => 100) }
@@ -101,7 +100,7 @@ describe "DynportTools::ETA" do
101
100
  end
102
101
 
103
102
  it "returns the correct string" do
104
- DynportTools::ETA.new(:current => 10, :total => 100, :started => time - 1).to_s.should == "10.0%, 10.0/second, ETA: 2011-02-03T04:50:09+01:00"
103
+ DynportTools::ETA.new(:current => 10, :total => 100, :started => time - 1).to_s.should == "10.00%, 10.00/second, ETA: 2011-02-03T04:50:09+01:00"
105
104
  end
106
105
 
107
106
  describe "#from_time_string" do
@@ -5,6 +5,91 @@ require "dynport_tools/jenkins"
5
5
  describe "DynportTools::Jenkins" do
6
6
  let(:url) { "http://some.url.com:8098" }
7
7
  let(:jenkins) { DynportTools::Jenkins.new(url) }
8
+ before(:each) do
9
+ Typhoeus::Request.stub!(:post).and_return nil
10
+ end
11
+
12
+ describe "RemoteProject" do
13
+ let(:remote_project) do
14
+ xml = File.read(root.join("spec/fixtures/jenkins_job.xml"))
15
+ remote_project = DynportTools::Jenkins::RemoteProject.new(:xml => xml)
16
+ remote_project
17
+ end
18
+
19
+ it "can be initialized" do
20
+ DynportTools::Jenkins::RemoteProject.new(:url => "some/url", :name => "Some Name", :rgne => "true").should return_values(:url => "some/url",
21
+ :name => "Some Name"
22
+ )
23
+ end
24
+
25
+ it "returns the correct " do
26
+ remote_project.commands.should == [%(ssh some.host \"touch /some/path/running.pid\")]
27
+ end
28
+
29
+ it "returns an empty array when no commands found" do
30
+ DynportTools::Jenkins::RemoteProject.new(:url => "some/url", :name => "Some Name", :xml => "<project/>").commands.should be_empty
31
+ end
32
+
33
+ it "returns the correct crontab_patterns" do
34
+ remote_project.crontab_patterns.should == ["0 4 * * *"]
35
+ end
36
+
37
+ it "returns the correct childProjects" do
38
+ remote_project.child_projects.should == ["Project 2", "Project 6", "Prohect 9"]
39
+ end
40
+
41
+ it "returns the correct locks" do
42
+ remote_project.locks.should == %w(Import)
43
+ end
44
+
45
+ it "returns the correct md5" do
46
+ remote_project.stub!(:xml).and_return "some xml"
47
+ remote_project.md5.should == "53bdfcda073f189a71901011123abf9a"
48
+ end
49
+
50
+ describe "logrotate" do
51
+ it "returns the correct amount of days_to_keep" do
52
+ remote_project.days_to_keep.should == 7
53
+ end
54
+
55
+ it "returns nil when days_to_keep == -1" do
56
+ DynportTools::Jenkins::RemoteProject.new(:xml => "<project><logRotator><daysToKeep>-1</daysToKeep></logRotator></project>").days_to_keep.should be_nil
57
+ end
58
+
59
+ it "returns nil for num_to_keep when -1" do
60
+ remote_project.num_to_keep.should be_nil
61
+ end
62
+
63
+ it "returns the correct value for num_to_keep when set" do
64
+ DynportTools::Jenkins::RemoteProject.new(:xml => "<project><logRotator><numToKeep>20</numToKeep></logRotator></project>").num_to_keep.should == 20
65
+ end
66
+ end
67
+
68
+ it "returns the correct disabled status" do
69
+ remote_project.should be_disabled
70
+ end
71
+
72
+ it "returns the correct email_addresses" do
73
+ remote_project.email_addresses.should == %w(test@test.xx)
74
+ end
75
+
76
+ it "returns false when not disabled" do
77
+ DynportTools::Jenkins::RemoteProject.new(:xml => "<project><disabled>false</disabled></project>").should_not be_disabled
78
+ end
79
+
80
+ it "extracts the correct node" do
81
+ remote_project.node.should == "Import"
82
+ end
83
+
84
+ describe "#with nothing found" do
85
+ let(:empty_remote_project) { DynportTools::Jenkins::RemoteProject.new(:xml => "<project/>") }
86
+ [:child_projects, :commands, :crontab_patterns, :locks].each do |method|
87
+ it "returns an empty array for #{method}" do
88
+ empty_remote_project.send(method).should == []
89
+ end
90
+ end
91
+ end
92
+ end
8
93
 
9
94
  describe "Project" do
10
95
  let(:job) { DynportTools::Jenkins::Project.new("Some Name") }
@@ -19,6 +104,14 @@ describe "DynportTools::Jenkins" do
19
104
  job.child_projects.should == []
20
105
  end
21
106
 
107
+ it "sets the commands to an empty array" do
108
+ job.locks.should == []
109
+ end
110
+
111
+ it "sets the email addresses to an empty array" do
112
+ job.email_addresses.should == []
113
+ end
114
+
22
115
  it "sets the name" do
23
116
  job.name.should == "Some Name"
24
117
  end
@@ -38,12 +131,19 @@ describe "DynportTools::Jenkins" do
38
131
  job.to_xml.should include("</project>")
39
132
  end
40
133
 
41
- %w(actions description properties builders publishers buildWrappers).each do |key|
134
+ %w(actions description properties publishers buildWrappers).each do |key|
42
135
  it "includes an empty node #{key}" do
43
136
  doc.at("/project/#{key}").children.should be_empty
44
137
  end
45
138
  end
46
139
 
140
+ it "sets the correct email_addresses when present" do
141
+ job.email_addresses = %w(test@test.xx test2@test.xx)
142
+ doc.xpath("/project/publishers/hudson.tasks.Mailer/recipients").map(&:inner_text).should == ["test@test.xx,test2@test.xx"]
143
+ doc.at("/project/publishers/hudson.tasks.Mailer/dontNotifyEveryUnstableBuild").inner_text.should == "true"
144
+ doc.at("/project/publishers/hudson.tasks.Mailer/sendToIndividuals").inner_text.should == "false"
145
+ end
146
+
47
147
  {
48
148
  "keepDependencies" => "false",
49
149
  "canRoam" => "true",
@@ -57,6 +157,11 @@ describe "DynportTools::Jenkins" do
57
157
  end
58
158
  end
59
159
 
160
+ it "sets disabled to true when set" do
161
+ job.disabled = true
162
+ doc.at("/project/disabled").inner_text.should == "true"
163
+ end
164
+
60
165
  { "scm" => "hudson.scm.NullSCM", "triggers" => "vector" }.each do |key, clazz|
61
166
  it "sets the class of #{key} to #{clazz}" do
62
167
  doc.at("/project/#{key}")["class"].should == clazz
@@ -68,7 +173,7 @@ describe "DynportTools::Jenkins" do
68
173
  job.commands << "date"
69
174
  shell_tasks = doc.search("project/builders/*")
70
175
  shell_tasks.map(&:name).should == ["hudson.tasks.Shell", "hudson.tasks.Shell"]
71
- shell_tasks.map { |node| node.at("command").inner_text }.should == ["#!/bin/sh\nhostname", "#!/bin/sh\ndate"]
176
+ shell_tasks.map { |node| node.at("command").inner_text }.should == ["hostname", "date"]
72
177
  end
73
178
 
74
179
  it "includes crontab like triggers" do
@@ -88,6 +193,17 @@ describe "DynportTools::Jenkins" do
88
193
  it "sets assignedNode when node is set" do
89
194
  job.node = "processor"
90
195
  doc.at("/project/assignedNode").inner_text.should == "processor"
196
+ doc.at("/project/canRoam").inner_text.should == "false"
197
+ end
198
+
199
+ it "allows setting a description" do
200
+ job.description = "some description"
201
+ doc.at("/project/description").inner_text.should == "some description"
202
+ end
203
+
204
+ it "returns the correct md5" do
205
+ job.stub(:to_xml).and_return "some test"
206
+ job.md5.should == "f1b75ac7689ff88e1ecc40c84b115785"
91
207
  end
92
208
 
93
209
  describe "with days_to_keep set" do
@@ -150,6 +266,22 @@ describe "DynportTools::Jenkins" do
150
266
  end
151
267
  end
152
268
  end
269
+
270
+ describe "#with locks" do
271
+ let(:locks) { doc.xpath("/project/buildWrappers/hudson.plugins.locksandlatches.LockWrapper/locks/hudson.plugins.locksandlatches.LockWrapper_-LockWaitConfig") }
272
+ before(:each) do
273
+ job.locks << "exclusive3"
274
+ job.locks << "exclusive2"
275
+ end
276
+
277
+ it "sets the correct amount of locks" do
278
+ locks.count.should == 2
279
+ end
280
+
281
+ it "sets the correct locks" do
282
+ locks.map { |l| l.at("name").inner_text }.should == %w(exclusive3 exclusive2)
283
+ end
284
+ end
153
285
  end
154
286
  end
155
287
 
@@ -159,7 +291,15 @@ describe "DynportTools::Jenkins" do
159
291
  end
160
292
  end
161
293
 
162
- describe "#jobs_hash" do
294
+ describe "#post_request" do
295
+ it "clears the local cache" do
296
+ jenkins.instance_variable_set("@cache", { :a => 1 })
297
+ jenkins.post_request("some/path")
298
+ jenkins.instance_variable_get("@cache").should == {}
299
+ end
300
+ end
301
+
302
+ describe "#projects_hash" do
163
303
  let(:body) do
164
304
  html =<<-HTML
165
305
  <hudson>
@@ -194,19 +334,45 @@ describe "DynportTools::Jenkins" do
194
334
 
195
335
  it "fetches the correct url" do
196
336
  Typhoeus::Request.should_receive(:get).with("http://some.url.com:8098/api/xml")
197
- jenkins.jobs_hash
337
+ jenkins.projects_hash
198
338
  end
199
339
 
200
- it "returns the correct jobs_hash" do
201
- jobs = jenkins.jobs_hash
340
+ it "returns the correct projects_hash" do
341
+ jobs = jenkins.projects_hash
202
342
  jobs["http://hudson.host:8080/job/Job1/"].should == { :url => "http://hudson.host:8080/job/Job1/", :name => "Job 1"}
203
343
  jobs["http://hudson.host:8080/job/Job2/"].should == { :url => "http://hudson.host:8080/job/Job2/", :name => "Job 2"}
204
344
  end
205
345
  end
346
+
347
+ it "sends the correct Typhoeus request when creating a project" do
348
+ xml = "some_xml"
349
+ Typhoeus::Request.should_receive(:post).with("http://some.url.com:8098/createItem?name=Test%20Job",
350
+ :headers => { "Content-Type" => "application/xml" }, :body => "some_xml"
351
+ )
352
+ jenkins.create_project("Test Job", xml)
353
+ end
354
+
355
+ it "sends the correct request when updating a project" do
356
+ xml = "some_update"
357
+ Typhoeus::Request.should_receive(:post).with("http://some.url.com:8098/job/Test%20Job/config.xml",
358
+ :headers => { "Content-Type" => "application/xml" }, :body => "some_update"
359
+ )
360
+ jenkins.update_project("Test Job", xml)
361
+ end
362
+
363
+ {
364
+ :delete_project => "doDelete", :build_project => "build", :disable_project => "disable",
365
+ :enable_project => "enable"
366
+ }.each do |method, action|
367
+ it "posts to the correct url when calling #{action}" do
368
+ Typhoeus::Request.should_receive(:post).with("http://some.url.com:8098/job/Test%20Job/#{action}")
369
+ jenkins.send(method, "Test Job")
370
+ end
371
+ end
206
372
 
207
- describe "#job_details" do
373
+ describe "#project_details" do
208
374
  before(:each) do
209
- jenkins.stub!(:jobs_hash).and_return(
375
+ jenkins.stub!(:projects_hash).and_return(
210
376
  "http://hudson.host:8080/job/Job1/" => { :url => "http://hudson.host:8080/job/Job1/", :name => "Job 1"},
211
377
  "http://hudson.host:8080/job/Job2/" => { :url => "http://hudson.host:8080/job/Job2/", :name => "Job 2"}
212
378
  )
@@ -217,7 +383,7 @@ describe "DynportTools::Jenkins" do
217
383
  response2 = Typhoeus::Response.new(:code => 200, :headers => "", :body => "<root><a>test2</a><b></b></root>")
218
384
  jenkins.hydra.stub(:get, "http://hudson.host:8080/job/Job1/config.xml").and_return(response1)
219
385
  jenkins.hydra.stub(:get, "http://hudson.host:8080/job/Job2/config.xml").and_return(response2)
220
- details = jenkins.job_details
386
+ details = jenkins.project_details
221
387
  details.should be_an_instance_of(Hash)
222
388
  details["http://hudson.host:8080/job/Job2/"].should == {
223
389
  :body=>"<?xml version=\"1.0\"?>\n<root>\n <a>test2</a>\n <b/>\n</root>\n",
@@ -228,39 +394,29 @@ describe "DynportTools::Jenkins" do
228
394
  :md5=>"14fa3890bea86820f7e45ce7f5a3ada4", :name=>"Job 1", :url=>"http://hudson.host:8080/job/Job1/"
229
395
  }
230
396
  end
397
+ end
398
+
399
+ describe "#remote_projects" do
400
+ before(:each) do
401
+ jenkins.stub(:project_details).and_return({})
402
+ end
403
+ it "calls project_details" do
404
+ jenkins.should_receive(:project_details).and_return({})
405
+ jenkins.remote_projects
406
+ end
231
407
 
232
- it "has a builder" do
233
- builder = Nokogiri::XML::Builder.new(:encoding => "UTF-8") do |xml|
234
- xml.project {
235
- xml.actions
236
- xml.description
237
- xml.keepDependencies false
238
- xml.properties
239
- xml.scm(:class => "hudson.scm.NullSCM")
240
- xml.canRoam true
241
- xml.disabled false
242
- xml.blockBuildWhenDownstreamBuilding false
243
- xml.blockBuildWhenUpstreamBuilding false
244
- xml.triggers(:class => "vector")
245
- xml.concurrentBuild false
246
- xml.builders do
247
- xml.send("hudson.tasks.Shell") do
248
- xml.command %(#!/bin/sh\nssh some.host "cd /some/path && ./script/runner -e production 'Some.command'")
249
- end
250
- end
251
- xml.publishers
252
- xml.buildWrappers do
253
- xml.send("hudson.plugins.locksandlatches.LockWrapper") do
254
- xml.locks do
255
- xml.send("hudson.plugins.locksandlatches.LockWrapper_-LockWaitConfig") do
256
- xml.name "Popularities"
257
- end
258
- end
259
- end
260
- end
261
- }
262
- end
263
- builder.to_xml.should == Nokogiri::XML(File.read(root.join("spec/fixtures/jenkins_job.xml"))).to_s
408
+ it "returns a hash" do
409
+ jenkins.remote_projects.should be_kind_of(Hash)
410
+ end
411
+
412
+ it "sets RemoteProject as values for hash" do
413
+ jenkins.should_receive(:project_details).and_return(
414
+ "url1" => { :name => "Project 1", :body => "some xml", :url => "url1" },
415
+ "url2" => { :name => "Project 2", :body => "some other xml", :url => "url2" }
416
+ )
417
+ remote_projects = jenkins.remote_projects
418
+ remote_projects.values.map(&:class).should == [DynportTools::Jenkins::RemoteProject, DynportTools::Jenkins::RemoteProject]
419
+ remote_projects["Project 1"].should return_values(:url => "url1", :name => "Project 1", :xml => "some xml")
264
420
  end
265
421
  end
266
422
  end
@@ -11,6 +11,30 @@ describe "DynportTools::XmlFile" do
11
11
  it "sets the correct path" do
12
12
  DynportTools::XmlFile.new(FILE1).path.should == FILE1.to_s
13
13
  end
14
+
15
+ it "also sets the pathwhen given as hash" do
16
+ DynportTools::XmlFile.new(:path => FILE1).path.should == FILE1.to_s
17
+ end
18
+
19
+ it "sets content when given" do
20
+ DynportTools::XmlFile.new(:content => "some content").content.should == "some content"
21
+ end
22
+ end
23
+
24
+ describe "#doc" do
25
+ it "opens a file when set" do
26
+ f = double("f")
27
+ File.should_receive(:open).with("/some/path").and_return f
28
+ Nokogiri.should_receive(:XML).with(f).and_return nil
29
+ DynportTools::XmlFile.new("/some/path").doc
30
+ end
31
+
32
+ it "parses the direct content when present" do
33
+ file = DynportTools::XmlFile.new
34
+ file.content = "some content"
35
+ Nokogiri.should_receive(:XML).with("some content").and_return nil
36
+ file.doc
37
+ end
14
38
  end
15
39
 
16
40
  describe "#nodes_hash" do
@@ -2,27 +2,51 @@
2
2
  <project>
3
3
  <actions/>
4
4
  <description></description>
5
+ <logRotator>
6
+ <daysToKeep>7</daysToKeep>
7
+ <numToKeep>-1</numToKeep>
8
+ <artifactDaysToKeep>-1</artifactDaysToKeep>
9
+ <artifactNumToKeep>-1</artifactNumToKeep>
10
+ </logRotator>
5
11
  <keepDependencies>false</keepDependencies>
6
12
  <properties/>
7
13
  <scm class="hudson.scm.NullSCM"/>
14
+ <assignedNode>Import</assignedNode>
8
15
  <canRoam>true</canRoam>
9
- <disabled>false</disabled>
16
+ <disabled>true</disabled>
10
17
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
11
18
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
12
- <triggers class="vector"/>
19
+ <triggers class="vector">
20
+ <hudson.triggers.TimerTrigger>
21
+ <spec>0 4 * * *</spec>
22
+ </hudson.triggers.TimerTrigger>
23
+ </triggers>
13
24
  <concurrentBuild>false</concurrentBuild>
14
25
  <builders>
15
26
  <hudson.tasks.Shell>
16
- <command>#!/bin/sh
17
- ssh some.host &quot;cd /some/path &amp;&amp; ./script/runner -e production &apos;Some.command&apos;&quot;</command>
27
+ <command>ssh some.host &quot;touch /some/path/running.pid&quot;</command>
18
28
  </hudson.tasks.Shell>
19
29
  </builders>
20
- <publishers/>
30
+ <publishers>
31
+ <hudson.tasks.BuildTrigger>
32
+ <childProjects>Project 2,Project 6, Prohect 9</childProjects>
33
+ <threshold>
34
+ <name>SUCCESS</name>
35
+ <ordinal>0</ordinal>
36
+ <color>BLUE</color>
37
+ </threshold>
38
+ </hudson.tasks.BuildTrigger>
39
+ <hudson.tasks.Mailer>
40
+ <recipients>test@test.xx</recipients>
41
+ <dontNotifyEveryUnstableBuild>true</dontNotifyEveryUnstableBuild>
42
+ <sendToIndividuals>false</sendToIndividuals>
43
+ </hudson.tasks.Mailer>
44
+ </publishers>
21
45
  <buildWrappers>
22
46
  <hudson.plugins.locksandlatches.LockWrapper>
23
47
  <locks>
24
48
  <hudson.plugins.locksandlatches.LockWrapper_-LockWaitConfig>
25
- <name>Popularities</name>
49
+ <name>Import</name>
26
50
  </hudson.plugins.locksandlatches.LockWrapper_-LockWaitConfig>
27
51
  </locks>
28
52
  </hudson.plugins.locksandlatches.LockWrapper>
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynport_tools
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 5
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 8
10
- version: 0.2.8
9
+ - 9
10
+ version: 0.2.9
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tobias Schwab
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-08-23 00:00:00 +02:00
18
+ date: 2011-08-24 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency