hudson 0.2.4 → 0.2.5.pre2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +85 -0
- data/Rakefile +120 -0
- data/bin/hudson +4 -55
- data/features/create_jobs.feature +22 -0
- data/features/development.feature +14 -0
- data/features/fixtures/projects/ruby/Rakefile +4 -0
- data/features/managing_remote_servers.feature +31 -0
- data/features/server.feature +16 -0
- data/features/step_definitions/common_steps.rb +181 -0
- data/features/step_definitions/fixture_project_steps.rb +8 -0
- data/features/step_definitions/hudson_steps.rb +71 -0
- data/features/step_definitions/scm_steps.rb +10 -0
- data/features/support/common.rb +29 -0
- data/features/support/env.rb +16 -0
- data/features/support/hooks.rb +16 -0
- data/features/support/matchers.rb +12 -0
- data/hudson.gemspec +57 -0
- data/lib/hudson/api.rb +43 -0
- data/lib/hudson/cli/formatting.rb +53 -0
- data/lib/hudson/cli.rb +141 -0
- data/lib/hudson/hudson.war +0 -0
- data/lib/hudson/job_config_builder.rb +161 -0
- data/lib/hudson/project_scm.rb +22 -0
- data/lib/hudson.rb +9 -5
- data/spec/fixtures/ec2_global.config.xml +103 -0
- data/spec/fixtures/rails.multi.config.xml +88 -0
- data/spec/fixtures/rails.single.config.xml +82 -0
- data/spec/fixtures/rubygem.config.xml +60 -0
- data/spec/fixtures/therubyracer.config.xml +77 -0
- data/spec/job_config_builder_spec.rb +30 -0
- data/spec/spec_helper.rb +19 -0
- metadata +190 -15
data/README.md
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
Hudson
|
2
|
+
======
|
3
|
+
|
4
|
+
Hudson is a sweet CI server. Hudson.rb makes it easy
|
5
|
+
to run ruby builds by bundling all the ruby-centric plugins
|
6
|
+
(ruby, rake, git, github) and wrapping them in a super simple
|
7
|
+
executeable.
|
8
|
+
|
9
|
+
Install
|
10
|
+
=======
|
11
|
+
|
12
|
+
gem install hudson
|
13
|
+
gem install hudson --pre (bleeding edge)
|
14
|
+
|
15
|
+
Example
|
16
|
+
=======
|
17
|
+
|
18
|
+
Hudson.rb is continuously tested using Hudson at [http://hudson.thefrontside.net/job/hudson.rb/](http://hudson.thefrontside.net/job/hudson.rb/).
|
19
|
+
|
20
|
+
The `hudson` application allows you to see the projects/jobs and their statuses:
|
21
|
+
|
22
|
+
$ hudson list --host hudson.thefrontside.net --port 80
|
23
|
+
hudson.rb - http://hudson.thefrontside.net/job/hudson.rb/
|
24
|
+
TheRubyRacer - http://hudson.thefrontside.net/job/TheRubyRacer/
|
25
|
+
|
26
|
+
# alternately use environment variables
|
27
|
+
$ HUDSON_HOST=hudson.thefrontside.net HUDSON_PORT=80 hudson list
|
28
|
+
|
29
|
+
Usage
|
30
|
+
=====
|
31
|
+
|
32
|
+
To run Hudson server:
|
33
|
+
|
34
|
+
Usage: hudson server [HUDSON_HOME] [options]
|
35
|
+
-d, --daemon fork into background and run as daemon
|
36
|
+
-p, --port [3001] run hudson on specified port
|
37
|
+
-c, --control-port [3002] set the shutdown/control port
|
38
|
+
-k, --kill send shutdown signal to control port
|
39
|
+
-v, --version show version information
|
40
|
+
-h, --help
|
41
|
+
|
42
|
+
Note: HUDSON_HOME defaults to ~/.hudson
|
43
|
+
|
44
|
+
To list Jobs/Projects on a Hudson server:
|
45
|
+
|
46
|
+
Usage: hudson list [project_path] [options]
|
47
|
+
-p, --port [3001] find hudson on specified port
|
48
|
+
--host [localhost] find hudson on specified host
|
49
|
+
-h, --help
|
50
|
+
|
51
|
+
To add Project (create a Job) on a Hudson server:
|
52
|
+
|
53
|
+
Usage: hudson create [project_path] [options]
|
54
|
+
-n, --name [dir_name] name of hudson job
|
55
|
+
-p, --port [3001] find hudson on specified port
|
56
|
+
--host [localhost] find hudson on specified host
|
57
|
+
-h, --help
|
58
|
+
|
59
|
+
For all commands, if flags for `host:port` are not provided, it will use `$HUDSON_HOST` and `$HUDSON_PORT` if available.
|
60
|
+
|
61
|
+
License
|
62
|
+
=======
|
63
|
+
|
64
|
+
(The MIT License)
|
65
|
+
|
66
|
+
Copyright (c) 2010 Charles Lowell, cowboyd@thefrontside.net
|
67
|
+
|
68
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
69
|
+
a copy of this software and associated documentation files (the
|
70
|
+
'Software'), to deal in the Software without restriction, including
|
71
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
72
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
73
|
+
permit persons to whom the Software is furnished to do so, subject to
|
74
|
+
the following conditions:
|
75
|
+
|
76
|
+
The above copyright notice and this permission notice shall be
|
77
|
+
included in all copies or substantial portions of the Software.
|
78
|
+
|
79
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
80
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
81
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
82
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
83
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
84
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
85
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
$:.unshift('lib')
|
2
|
+
require 'hudson'
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
$gemspec = s
|
7
|
+
s.name = s.rubyforge_project = "hudson"
|
8
|
+
s.version = Hudson::VERSION
|
9
|
+
s.summary = "Painless Continuous Integration with Hudson Server"
|
10
|
+
s.description = "A suite of utilities for bringing continous integration to your projects (not the other way around) with hudson CI"
|
11
|
+
s.email = ["cowboyd@thefrontside.net", "drnicwilliams@gmail.com"]
|
12
|
+
s.homepage = "http://github.com/cowboyd/hudson.rb"
|
13
|
+
s.authors = ["Charles Lowell", "Dr Nic Williams"]
|
14
|
+
s.executables = ["hudson"]
|
15
|
+
s.require_paths = ["lib"]
|
16
|
+
s.files = Rake::FileList.new("**/*").tap do |manifest|
|
17
|
+
manifest.exclude "tmp", "**/*.gem"
|
18
|
+
end.to_a
|
19
|
+
s.add_dependency("term-ansicolor", [">= 1.0.4"])
|
20
|
+
s.add_dependency("yajl-ruby", [">= 0.7.6"])
|
21
|
+
s.add_dependency("httparty", ["~> 0.5.2"])
|
22
|
+
s.add_dependency("builder", ["~> 2.1.2"])
|
23
|
+
s.add_dependency("thor", ["~> 0.13.6"])
|
24
|
+
s.add_dependency("hpricot")
|
25
|
+
s.add_development_dependency("cucumber", ["~> 0.7.3"])
|
26
|
+
s.add_development_dependency("rspec", ["~> 1.3.0"])
|
27
|
+
s.add_development_dependency("json", ["~>1.4.0"])
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "Build gem"
|
31
|
+
task :gem => :gemspec do
|
32
|
+
Gem::Builder.new($gemspec).build
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "Build gemspec"
|
36
|
+
task :gemspec => :clean do
|
37
|
+
File.open("#{$gemspec.name}.gemspec", "w") do |f|
|
38
|
+
f.write($gemspec.to_ruby)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Clean up"
|
43
|
+
task :clean do
|
44
|
+
sh "rm -rf *.gem"
|
45
|
+
end
|
46
|
+
|
47
|
+
namespace :cucumber do
|
48
|
+
require 'cucumber/rake/task'
|
49
|
+
Cucumber::Rake::Task.new(:wip, 'Run features that are being worked on') do |t|
|
50
|
+
t.cucumber_opts = "--tags @wip"
|
51
|
+
end
|
52
|
+
Cucumber::Rake::Task.new(:ok, 'Run features that should be working') do |t|
|
53
|
+
t.cucumber_opts = "--tags ~@wip"
|
54
|
+
end
|
55
|
+
task :all => [:ok, :wip]
|
56
|
+
end
|
57
|
+
|
58
|
+
desc 'Alias for cucumber:ok'
|
59
|
+
task :cucumber => 'cucumber:ok'
|
60
|
+
|
61
|
+
desc "Start test server; Run cucumber:ok; Kill Test Server;"
|
62
|
+
task :default => ["hudson:server:killtest", "hudson:server:test"] do
|
63
|
+
require 'socket'
|
64
|
+
print "waiting for at most 30 seconds for the server to start"
|
65
|
+
tries = 1
|
66
|
+
begin
|
67
|
+
print "."; $stdout.flush
|
68
|
+
tries += 1
|
69
|
+
Net::HTTP.start("localhost", "3010") { |http| http.get('/') }
|
70
|
+
sleep(10)
|
71
|
+
puts ""
|
72
|
+
Rake::Task["cucumber:ok"].invoke
|
73
|
+
rescue Exception => e
|
74
|
+
if tries <= 15
|
75
|
+
sleep 2
|
76
|
+
retry
|
77
|
+
end
|
78
|
+
raise
|
79
|
+
ensure
|
80
|
+
Rake::Task["hudson:server:killtest"].tap do |task|
|
81
|
+
task.reenable
|
82
|
+
task.invoke
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
namespace :hudson do
|
88
|
+
namespace :server do
|
89
|
+
require 'fileutils'
|
90
|
+
|
91
|
+
desc "Run a server for tests"
|
92
|
+
task :test do
|
93
|
+
port = 3010
|
94
|
+
control = 3011
|
95
|
+
|
96
|
+
FileUtils.chdir(File.dirname(__FILE__)) do
|
97
|
+
logfile = File.join("/tmp", "test_hudson.log")
|
98
|
+
puts "Launching hudson test server at http://localhost:#{port}..."
|
99
|
+
puts " output will be logged to #{logfile}"
|
100
|
+
`ruby bin/hudson server --home /tmp/test_hudson --port #{port} --control #{control} --daemon --logfile #{logfile}`
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
desc "Kill hudson test server if it is running."
|
105
|
+
task :killtest do
|
106
|
+
FileUtils.chdir(File.dirname(__FILE__)) do
|
107
|
+
puts "Killing any running server processes..."
|
108
|
+
`ruby bin/hudson server --control 3011 --kill 2>/dev/null`
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
desc "Grab the latest hudson.war from hudson-ci.org"
|
113
|
+
task :getwar do
|
114
|
+
sh "cd lib/hudson && rm hudson.war && wget http://hudson-ci.org/latest/hudson.war"
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
|
data/bin/hudson
CHANGED
@@ -1,58 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
$:.unshift(File.expand_path(File.dirname(File.dirname(__FILE__) + "/../lib/hudson.rb")))
|
2
4
|
require File.dirname(__FILE__) + '/../lib/hudson'
|
3
|
-
require '
|
4
|
-
require 'optparse'
|
5
|
-
|
6
|
-
|
7
|
-
options = {
|
8
|
-
:port => 3001,
|
9
|
-
:control => 3002,
|
10
|
-
:home => File.join(ENV['HOME'], '.hudson')
|
11
|
-
}
|
12
|
-
args = ARGV.dup
|
13
|
-
|
14
|
-
opts = OptionParser.new do |opts|
|
15
|
-
opts.banner = "Usage: hudson [options] [HUDSON_HOME]"
|
16
|
-
|
17
|
-
opts.on("-d", "--daemon", "fork into background and run as daemon") do
|
18
|
-
options[:daemon] = true
|
19
|
-
end
|
20
|
-
|
21
|
-
opts.on("-p", "--port [3001]", "run hudson on specified port ") do |port|
|
22
|
-
options[:port] = port
|
23
|
-
end
|
24
|
-
|
25
|
-
opts.on("-c", "--control-port [3002]", Integer, "set the shutdown/control port") do |port|
|
26
|
-
options[:control] = cport
|
27
|
-
end
|
28
|
-
|
29
|
-
opts.on_tail("-k", "--kill", "send shutdown signal to control port") do
|
30
|
-
require 'socket'
|
31
|
-
TCPSocket.open("localhost", options[:control]) do |sock|
|
32
|
-
sock.write("0")
|
33
|
-
end
|
34
|
-
exit
|
35
|
-
end
|
36
|
-
|
37
|
-
opts.on_tail("-v", "--version", "show version information") do
|
38
|
-
puts "#{Hudson::VERSION} (Hudson Server #{Hudson::HUDSON_VERSION})"
|
39
|
-
exit
|
40
|
-
end
|
41
|
-
opts.on_tail("-h", "--help") do
|
42
|
-
puts opts
|
43
|
-
exit
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
opts.parse!(args)
|
48
|
-
dir = args.shift || options[:home]
|
49
|
-
FileUtils.mkdir_p dir
|
50
|
-
FileUtils.cp_r Hudson::PLUGINS, dir
|
51
|
-
ENV['HUDSON_HOME'] = dir
|
52
|
-
cmd = ["java", "-jar", Hudson::WAR]
|
53
|
-
cmd << "--httpPort=#{options[:port]}"
|
54
|
-
cmd << "--controlPort=#{options[:control]}"
|
55
|
-
cmd << "--daemon" if options[:daemon]
|
56
|
-
puts cmd.join(" ")
|
57
|
-
exec(*cmd)
|
5
|
+
require 'hudson/cli'
|
58
6
|
|
7
|
+
Hudson::CLI.start
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Feature: Create jobs
|
2
|
+
In order to reduce cost of getting a new project up onto Hudson
|
3
|
+
As a project developer
|
4
|
+
I want to add a new project to Hudson as a job
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given I have a Hudson server running
|
8
|
+
And the Hudson server has no current jobs
|
9
|
+
|
10
|
+
Scenario: Discover Ruby project, on git scm, and create job
|
11
|
+
Given I am in the "ruby" project folder
|
12
|
+
And the project uses "git" scm
|
13
|
+
When I run local executable "hudson" with arguments "create . --host localhost --port 3010"
|
14
|
+
Then I should see "Added project 'ruby' to Hudson."
|
15
|
+
Then I should see "http://localhost:3010/job/ruby/build"
|
16
|
+
When I run local executable "hudson" with arguments "list --host localhost --port 3010"
|
17
|
+
Then I should see "ruby"
|
18
|
+
|
19
|
+
Scenario: Attempt to create project without scm
|
20
|
+
Given I am in the "ruby" project folder
|
21
|
+
When I run local executable "hudson" with arguments "create . --host localhost --port 3010"
|
22
|
+
Then I should see "Cannot determine project SCM. Currently supported:"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Feature: Development processes of hudson itself (rake tasks)
|
2
|
+
|
3
|
+
As a Newgem maintainer or contributor
|
4
|
+
I want rake tasks to maintain and release the gem
|
5
|
+
So that I can spend time on the tests and code, and not excessive time on maintenance processes
|
6
|
+
|
7
|
+
Scenario: Generate RubyGem
|
8
|
+
Given this project is active project folder
|
9
|
+
When I invoke task "rake clean" so that I start with nothing
|
10
|
+
And I invoke task "rake gem"
|
11
|
+
Then file with name matching "hudson-*.gem" is created
|
12
|
+
And file with name matching "hudson.gemspec" is created
|
13
|
+
And the file "hudson.gemspec" is a valid gemspec
|
14
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
@wip
|
2
|
+
Feature: Managing remote servers
|
3
|
+
In order to reduce cost of referencing remote servers by explicit --host/--port options
|
4
|
+
As a user
|
5
|
+
I want a directory of remote servers I frequently use
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given I have a Hudson server running
|
9
|
+
And the Hudson server has no current jobs
|
10
|
+
|
11
|
+
Scenario: No remote servers
|
12
|
+
When I run local executable "hudson" with arguments "list"
|
13
|
+
Then I should see "Either use --host or add remote servers."
|
14
|
+
|
15
|
+
Scenario: Add a remote server
|
16
|
+
When I run local executable "hudson" with arguments "remotes add --host localhost --port 3010"
|
17
|
+
And I run local executable "hudson" with arguments "remotes add --host localhost --port 3011"
|
18
|
+
And I run local executable "hudson" with arguments "list"
|
19
|
+
Then I should not see "Either use --host or add remote servers."
|
20
|
+
And I should see "localhost:3010 -"
|
21
|
+
And I should see "No jobs"
|
22
|
+
And I should see "localhost:3011 - no connection"
|
23
|
+
|
24
|
+
Scenario: Add a remote server and access by abbreviation
|
25
|
+
When I run local executable "hudson" with arguments "remotes add --host localhost --port 3010"
|
26
|
+
When I run local executable "hudson" with arguments "remotes add --host another.server"
|
27
|
+
And I run local executable "hudson" with arguments "list --server local"
|
28
|
+
And I should see "localhost:3010 -"
|
29
|
+
And I should see "No jobs"
|
30
|
+
And I should not see "another.server"
|
31
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Feature: Running a Hudson Server
|
2
|
+
As a hudson server administrator
|
3
|
+
I want to be able to easily control a hudson server
|
4
|
+
In order to spend my time on how the process operates, not how to start stop and control it.
|
5
|
+
|
6
|
+
Scenario: Start a Hudson Server
|
7
|
+
Given env variable $HOME set to project path "home"
|
8
|
+
And "home/.hudson" folder is deleted
|
9
|
+
And there is nothing listening on port 5001
|
10
|
+
And there is nothing listening on port 5002
|
11
|
+
And I cleanup any hudson processes with control port 5002
|
12
|
+
When I run hudson server with arguments "--port 5001 --control 5002 --daemon --logfile=server.log"
|
13
|
+
Then I should see a hudson server on port 5001
|
14
|
+
And folder "home/.hudson/server" is created
|
15
|
+
And folder "home/.hudson/server/javatmp" is created
|
16
|
+
|
@@ -0,0 +1,181 @@
|
|
1
|
+
Given /^this project is active project folder/ do
|
2
|
+
@active_project_folder = File.expand_path(File.dirname(__FILE__) + "/../..")
|
3
|
+
end
|
4
|
+
|
5
|
+
Given /^env variable \$([\w_]+) set to( project path |)"(.*)"/ do |env_var, path, value|
|
6
|
+
in_project_folder {
|
7
|
+
value = File.expand_path(value)
|
8
|
+
} unless path.empty?
|
9
|
+
ENV[env_var] = value
|
10
|
+
end
|
11
|
+
|
12
|
+
Given /"(.*)" folder is deleted/ do |folder|
|
13
|
+
in_project_folder { FileUtils.rm_rf folder }
|
14
|
+
end
|
15
|
+
|
16
|
+
When /^I invoke "(.*)" generator with arguments "(.*)"$/ do |generator, arguments|
|
17
|
+
@stdout = StringIO.new
|
18
|
+
in_project_folder do
|
19
|
+
if Object.const_defined?("APP_ROOT")
|
20
|
+
APP_ROOT.replace(FileUtils.pwd)
|
21
|
+
else
|
22
|
+
APP_ROOT = FileUtils.pwd
|
23
|
+
end
|
24
|
+
run_generator(generator, arguments.split(' '), SOURCES, :stdout => @stdout)
|
25
|
+
end
|
26
|
+
File.open(File.join(@tmp_root, "generator.out"), "w") do |f|
|
27
|
+
@stdout.rewind
|
28
|
+
f << @stdout.read
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
When /^I run executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
|
33
|
+
@stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
|
34
|
+
in_project_folder do
|
35
|
+
system "#{executable} #{arguments} > #{@stdout} 2> #{@stdout}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
When /^I run project executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
|
40
|
+
@stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
|
41
|
+
in_project_folder do
|
42
|
+
system "ruby #{executable} #{arguments} > #{@stdout} 2> #{@stdout}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
When /^I run local executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
|
47
|
+
@stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
|
48
|
+
executable = File.expand_path(File.join(File.dirname(__FILE__), "/../../bin", executable))
|
49
|
+
in_project_folder do
|
50
|
+
system "ruby #{executable} #{arguments} > #{@stdout} 2> #{@stdout}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
When /^I invoke task "rake (.*)"/ do |task|
|
55
|
+
@stdout = File.expand_path(File.join(@tmp_root, "tests.out"))
|
56
|
+
in_project_folder do
|
57
|
+
system "rake #{task} --trace > #{@stdout} 2> #{@stdout}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
Then /^folder "(.*)" (is|is not) created/ do |folder, is|
|
62
|
+
in_project_folder do
|
63
|
+
File.exists?(folder).should(is == 'is' ? be_true : be_false)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
Then /^file "(.*)" (is|is not) created/ do |file, is|
|
68
|
+
in_project_folder do
|
69
|
+
File.exists?(file).should(is == 'is' ? be_true : be_false)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
Then /^file with name matching "(.*)" is created/ do |pattern|
|
74
|
+
in_project_folder do
|
75
|
+
Dir[pattern].should_not be_empty
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
Then /^file "(.*)" contents (does|does not) match \/(.*)\// do |file, does, regex|
|
80
|
+
in_project_folder do
|
81
|
+
actual_output = File.read(file)
|
82
|
+
(does == 'does') ?
|
83
|
+
actual_output.should(match(/#{regex}/)) :
|
84
|
+
actual_output.should_not(match(/#{regex}/))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
Then /gem file "(.*)" and generated file "(.*)" should be the same/ do |gem_file, project_file|
|
89
|
+
File.exists?(gem_file).should be_true
|
90
|
+
File.exists?(project_file).should be_true
|
91
|
+
gem_file_contents = File.read(File.dirname(__FILE__) + "/../../#{gem_file}")
|
92
|
+
project_file_contents = File.read(File.join(@active_project_folder, project_file))
|
93
|
+
project_file_contents.should == gem_file_contents
|
94
|
+
end
|
95
|
+
|
96
|
+
Then /^(does|does not) invoke generator "(.*)"$/ do |does_invoke, generator|
|
97
|
+
actual_output = File.read(@stdout)
|
98
|
+
does_invoke == "does" ?
|
99
|
+
actual_output.should(match(/dependency\s+#{generator}/)) :
|
100
|
+
actual_output.should_not(match(/dependency\s+#{generator}/))
|
101
|
+
end
|
102
|
+
|
103
|
+
Then /help options "(.*)" and "(.*)" are displayed/ do |opt1, opt2|
|
104
|
+
actual_output = File.read(@stdout)
|
105
|
+
actual_output.should match(/#{opt1}/)
|
106
|
+
actual_output.should match(/#{opt2}/)
|
107
|
+
end
|
108
|
+
|
109
|
+
Then /^I should see "([^\"]*)"$/ do |text|
|
110
|
+
actual_output = File.read(@stdout)
|
111
|
+
actual_output.should contain(text)
|
112
|
+
end
|
113
|
+
|
114
|
+
Then /^I should not see "([^\"]*)"$/ do |text|
|
115
|
+
actual_output = File.read(@stdout)
|
116
|
+
actual_output.should_not contain(text)
|
117
|
+
end
|
118
|
+
|
119
|
+
Then /^I should see$/ do |text|
|
120
|
+
actual_output = File.read(@stdout)
|
121
|
+
actual_output.should contain(text)
|
122
|
+
end
|
123
|
+
|
124
|
+
Then /^I should not see$/ do |text|
|
125
|
+
actual_output = File.read(@stdout)
|
126
|
+
actual_output.should_not contain(text)
|
127
|
+
end
|
128
|
+
|
129
|
+
Then /^I should see exactly$/ do |text|
|
130
|
+
actual_output = File.read(@stdout)
|
131
|
+
actual_output.should == text
|
132
|
+
end
|
133
|
+
|
134
|
+
Then /^I should see all (\d+) tests pass/ do |expected_test_count|
|
135
|
+
expected = %r{^#{expected_test_count} tests, \d+ assertions, 0 failures, 0 errors}
|
136
|
+
actual_output = File.read(@stdout)
|
137
|
+
actual_output.should match(expected)
|
138
|
+
end
|
139
|
+
|
140
|
+
Then /^I should see all (\d+) examples pass/ do |expected_test_count|
|
141
|
+
expected = %r{^#{expected_test_count} examples?, 0 failures}
|
142
|
+
actual_output = File.read(@stdout)
|
143
|
+
actual_output.should match(expected)
|
144
|
+
end
|
145
|
+
|
146
|
+
Then /^yaml file "(.*)" contains (\{.*\})/ do |file, yaml|
|
147
|
+
in_project_folder do
|
148
|
+
yaml = eval yaml
|
149
|
+
YAML.load(File.read(file)).should == yaml
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
Then /^Rakefile can display tasks successfully/ do
|
154
|
+
@stdout = File.expand_path(File.join(@tmp_root, "rakefile.out"))
|
155
|
+
in_project_folder do
|
156
|
+
system "rake -T > #{@stdout} 2> #{@stdout}"
|
157
|
+
end
|
158
|
+
actual_output = File.read(@stdout)
|
159
|
+
actual_output.should match(/^rake\s+\w+\s+#\s.*/)
|
160
|
+
end
|
161
|
+
|
162
|
+
Then /^task "rake (.*)" is executed successfully/ do |task|
|
163
|
+
@stdout.should_not be_nil
|
164
|
+
actual_output = File.read(@stdout)
|
165
|
+
actual_output.should_not match(/^Don't know how to build task '#{task}'/)
|
166
|
+
actual_output.should_not match(/Error/i)
|
167
|
+
end
|
168
|
+
|
169
|
+
Then /^gem spec key "(.*)" contains \/(.*)\// do |key, regex|
|
170
|
+
in_project_folder do
|
171
|
+
gem_file = Dir["pkg/*.gem"].first
|
172
|
+
gem_spec = Gem::Specification.from_yaml(`gem spec #{gem_file}`)
|
173
|
+
spec_value = gem_spec.send(key.to_sym)
|
174
|
+
spec_value.to_s.should match(/#{regex}/)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
Then /^the file "([^\"]*)" is a valid gemspec$/ do |filename|
|
179
|
+
spec = eval(File.read(filename))
|
180
|
+
spec.validate
|
181
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
Given /^I am in the "([^\"]*)" project folder$/ do |project|
|
2
|
+
project_folder = File.expand_path(File.dirname(__FILE__) + "/../fixtures/projects/#{project}")
|
3
|
+
in_tmp_folder do
|
4
|
+
FileUtils.cp_r(project_folder, project)
|
5
|
+
setup_active_project_folder(project)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
@@ -0,0 +1,71 @@
|
|
1
|
+
Given /^I have a Hudson server running$/ do
|
2
|
+
unless ENV['HUDSON_PORT']
|
3
|
+
port = 3010
|
4
|
+
begin
|
5
|
+
res = Net::HTTP.start("localhost", port) { |http| http.get('/api/json') }
|
6
|
+
rescue Errno::ECONNREFUSED => e
|
7
|
+
puts "\n\n\nERROR: To run tests, launch hudson in test mode: 'rake hudson:server:test'\n\n\n"
|
8
|
+
exit
|
9
|
+
end
|
10
|
+
ENV['HUDSON_PORT'] = port.to_s
|
11
|
+
ENV['HUDSON_HOST'] = 'localhost'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Given /^the Hudson server has no current jobs$/ do
|
16
|
+
if port = ENV['HUDSON_PORT']
|
17
|
+
require "open-uri"
|
18
|
+
require "yajl"
|
19
|
+
hudson_info = Yajl::Parser.new.parse(open("http://localhost:#{ENV['HUDSON_PORT']}/api/json"))
|
20
|
+
|
21
|
+
hudson_info['jobs'].each do |job|
|
22
|
+
job_url = job['url']
|
23
|
+
res = Net::HTTP.start("localhost", port) { |http| http.post("#{job_url}doDelete/api/json", {}) }
|
24
|
+
end
|
25
|
+
hudson_info = Yajl::Parser.new.parse(open("http://localhost:#{ENV['HUDSON_PORT']}/api/json"))
|
26
|
+
hudson_info['jobs'].should == []
|
27
|
+
else
|
28
|
+
puts "WARNING: Run 'I have a Hudson server running' step first."
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Given /^there is nothing listening on port (\d+)$/ do |port|
|
33
|
+
lambda {
|
34
|
+
TCPSocket.open("localhost", port) {}
|
35
|
+
}.should raise_error
|
36
|
+
end
|
37
|
+
|
38
|
+
Given /^I cleanup any hudson processes with control port (\d+)$/ do |port|
|
39
|
+
@hudson_cleanup << port
|
40
|
+
end
|
41
|
+
|
42
|
+
def try(times, interval = 1)
|
43
|
+
begin
|
44
|
+
times -= 1
|
45
|
+
return yield
|
46
|
+
rescue Exception => e
|
47
|
+
if times >= 0
|
48
|
+
sleep(interval)
|
49
|
+
retry
|
50
|
+
end
|
51
|
+
raise e
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
When /^I run hudson server with arguments "(.*)"/ do |arguments|
|
56
|
+
@stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
|
57
|
+
executable = File.expand_path(File.join(File.dirname(__FILE__), "/../../bin","hudson"))
|
58
|
+
in_project_folder do
|
59
|
+
system "ruby #{executable} server #{arguments} > #{@stdout} 2>#{@stdout}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
Then /^I should see a hudson server on port (\d+)$/ do |port|
|
65
|
+
require 'json'
|
66
|
+
try(15, 2) do
|
67
|
+
res = Net::HTTP.start("localhost", port) { |http| http.get('/api/json') }
|
68
|
+
JSON.parse(res.body)['nodeDescription'].should == "the master Hudson node"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module CommonHelpers
|
2
|
+
def in_tmp_folder(&block)
|
3
|
+
FileUtils.chdir(@tmp_root, &block)
|
4
|
+
end
|
5
|
+
|
6
|
+
def in_project_folder(&block)
|
7
|
+
project_folder = @active_project_folder || @tmp_root
|
8
|
+
FileUtils.chdir(project_folder, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def in_home_folder(&block)
|
12
|
+
FileUtils.chdir(@home_path, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def force_local_lib_override(project_name = @project_name)
|
16
|
+
rakefile = File.read(File.join(project_name, 'Rakefile'))
|
17
|
+
File.open(File.join(project_name, 'Rakefile'), "w+") do |f|
|
18
|
+
f << "$:.unshift('#{@lib_path}')\n"
|
19
|
+
f << rakefile
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup_active_project_folder project_name
|
24
|
+
@active_project_folder = File.join(@tmp_root, project_name)
|
25
|
+
@project_name = project_name
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
World(CommonHelpers)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
$:.unshift(File.expand_path(File.dirname(File.dirname(__FILE__) + "/../../lib/hudson.rb")))
|
2
|
+
require File.dirname(__FILE__) + "/../../lib/hudson.rb"
|
3
|
+
|
4
|
+
gem 'cucumber'
|
5
|
+
require 'cucumber'
|
6
|
+
gem 'rspec'
|
7
|
+
require 'spec'
|
8
|
+
|
9
|
+
Before do
|
10
|
+
@tmp_root = File.dirname(__FILE__) + "/../../tmp"
|
11
|
+
@home_path = File.expand_path(File.join(@tmp_root, "home"))
|
12
|
+
@lib_path = File.expand_path(File.dirname(__FILE__) + "/../../lib")
|
13
|
+
FileUtils.rm_rf @tmp_root
|
14
|
+
FileUtils.mkdir_p @home_path
|
15
|
+
ENV['HOME'] = @home_path
|
16
|
+
end
|