hercules 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +10 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +36 -0
- data/LICENSE +20 -0
- data/README.md +71 -0
- data/Rakefile +76 -0
- data/VERSION +1 -0
- data/bin/hercules +6 -0
- data/hdi/README.md +4 -0
- data/hdi/config.rb +7 -0
- data/hdi/site/index.html +267 -0
- data/hdi/site/stylesheets/style.css +1 -0
- data/hdi/src/configuration.rb +5 -0
- data/hdi/src/layouts/application.haml +12 -0
- data/hdi/src/pages/_hdi.haml +71 -0
- data/hdi/src/pages/_header.haml +8 -0
- data/hdi/src/pages/_jquery.haml +155 -0
- data/hdi/src/pages/index.haml +10 -0
- data/hdi/src/stylesheets/style.sass +173 -0
- data/hercules.gemspec +120 -0
- data/lib/command_runner.rb +73 -0
- data/lib/config.rb +82 -0
- data/lib/deployer.rb +95 -0
- data/lib/git_handler.rb +78 -0
- data/lib/hercules.rb +167 -0
- data/lib/http_handler.rb +41 -0
- data/lib/request_handler.rb +142 -0
- data/tests/command_runner_test.rb +35 -0
- data/tests/config_test.rb +39 -0
- data/tests/fixtures/Gemfile +1 -0
- data/tests/fixtures/Gemfile.lock +8 -0
- data/tests/fixtures/Gemfile.with_git_gem +2 -0
- data/tests/fixtures/Gemfile.with_git_gem.lock +10 -0
- data/tests/fixtures/bogus_config.yml +9 -0
- data/tests/fixtures/bogus_deployer.rb +2 -0
- data/tests/fixtures/config.yml +12 -0
- data/tests/fixtures/config_empty.yml +1 -0
- data/tests/fixtures/config_empty_branches.yml +8 -0
- data/tests/fixtures/config_empty_projects.yml +2 -0
- data/tests/fixtures/config_global.yml +14 -0
- data/tests/fixtures/config_partial_1.yml +7 -0
- data/tests/fixtures/config_partial_2.yml +7 -0
- data/tests/fixtures/config_partial_3.yml +7 -0
- data/tests/fixtures/deployer_branch.rb +11 -0
- data/tests/fixtures/deployer_exception.rb +11 -0
- data/tests/fixtures/deployer_false.rb +11 -0
- data/tests/fixtures/deployer_path.rb +11 -0
- data/tests/fixtures/deployer_true.rb +11 -0
- data/tests/fixtures/deployer_undefined_variable.rb +11 -0
- data/tests/fixtures/startup_checkout_config.yml +12 -0
- data/tests/fixtures/startup_checkout_error_config.yml +12 -0
- data/tests/git_handler_test.rb +95 -0
- data/tests/git_setup.rb +70 -0
- data/tests/hercules_test.rb +128 -0
- data/tests/http_handler_test.rb +88 -0
- data/tests/request_handler_test.rb +242 -0
- data/tests/startup.rb +36 -0
- metadata +251 -0
@@ -0,0 +1,12 @@
|
|
1
|
+
---
|
2
|
+
test_project:
|
3
|
+
token: abc
|
4
|
+
repository: file:///tmp/hercules_test_repository
|
5
|
+
target_directory: /tmp/hercules_test_checkout
|
6
|
+
master:
|
7
|
+
checkout_on_startup: false
|
8
|
+
checkouts_to_keep: 1
|
9
|
+
test:
|
10
|
+
checkout_on_startup: false
|
11
|
+
checkouts_to_keep: 3
|
12
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
---
|
@@ -0,0 +1,14 @@
|
|
1
|
+
---
|
2
|
+
host: "127.0.0.1"
|
3
|
+
port: 8081
|
4
|
+
test_project:
|
5
|
+
token: abc
|
6
|
+
repository: file:///tmp/hercules_test_repository
|
7
|
+
target_directory: /tmp/hercules_test_checkout
|
8
|
+
master:
|
9
|
+
checkout_on_startup: false
|
10
|
+
checkouts_to_keep: 1
|
11
|
+
test:
|
12
|
+
checkout_on_startup: false
|
13
|
+
checkouts_to_keep: 3
|
14
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
---
|
2
|
+
test_project:
|
3
|
+
token: abc
|
4
|
+
repository: file:///tmp/hercules_test_repository
|
5
|
+
target_directory: /tmp/hercules_test_checkout
|
6
|
+
master:
|
7
|
+
checkout_on_startup: true
|
8
|
+
checkouts_to_keep: 1
|
9
|
+
test:
|
10
|
+
checkout_on_startup: false
|
11
|
+
checkouts_to_keep: 3
|
12
|
+
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'tests/git_setup'
|
3
|
+
require 'lib/git_handler'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
class GitHandlerTest < Test::Unit::TestCase
|
7
|
+
include GitSetup
|
8
|
+
def setup
|
9
|
+
git_setup
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_get_last_commit
|
13
|
+
g = Hercules::GitHandler.new(@config['test_project'])
|
14
|
+
g.export_branch('master')
|
15
|
+
assert_equal @head_sha, g.last_commit
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_export_branch
|
19
|
+
g = Hercules::GitHandler.new(@config['test_project'])
|
20
|
+
g.export_branch('master')
|
21
|
+
assert_is_checkout @config['test_project']['target_directory'] + '/checkouts/master/' + @head_sha
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_export_non_existent_branch
|
25
|
+
g = Hercules::GitHandler.new(@config['test_project'])
|
26
|
+
g.export_branch('branch_that_will_not_exist') rescue nil
|
27
|
+
assert !File.exists?(@config['test_project']['target_directory'] + '/checkouts/branch_that_will_not_exist/' + @head_sha)
|
28
|
+
assert_equal 2, Dir.glob(@config['test_project']['target_directory'] + '/checkouts/branch_that_will_not_exist/.*').size
|
29
|
+
assert_equal 0, Dir.glob(@config['test_project']['target_directory'] + '/checkouts/branch_that_will_not_exist/*').size
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_export_non_existent_or_invalid_repository
|
33
|
+
@config['test_project']['repository'] = 'repository_that_does_not_exist_or_is_invalid'
|
34
|
+
g = Hercules::GitHandler.new(@config['test_project'])
|
35
|
+
begin
|
36
|
+
g.export_branch('branch_that_will_not_exist')
|
37
|
+
assert false
|
38
|
+
rescue Exception => e
|
39
|
+
assert_match /Error while cloning/, e.message
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_create_branches_dir
|
45
|
+
g = Hercules::GitHandler.new(@config['test_project'])
|
46
|
+
g.create_branches_dir
|
47
|
+
assert (File.exists?(@config['test_project']['target_directory'] + '/branches'))
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_branches_dir
|
51
|
+
g = Hercules::GitHandler.new(@config['test_project'])
|
52
|
+
assert_equal @config['test_project']['target_directory'] + '/branches', g.branches_path
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_deploy_branch
|
56
|
+
g = Hercules::GitHandler.new(@config['test_project'])
|
57
|
+
g.deploy_branch('master')
|
58
|
+
assert_is_checkout @config['test_project']['target_directory'] + '/branches/master'
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_should_deploy_test_branch
|
62
|
+
@g.branch('test').checkout
|
63
|
+
g = Hercules::GitHandler.new(@config['test_project'])
|
64
|
+
g.deploy_branch('test')
|
65
|
+
assert_is_checkout @config['test_project']['target_directory'] + '/branches/test'
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_should_maintain_at_most_three_test_checkouts
|
69
|
+
@g.branch('test').checkout
|
70
|
+
g = Hercules::GitHandler.new(@config['test_project'])
|
71
|
+
FileUtils.mkdir_p(@config['test_project']['target_directory'] + '/logs')
|
72
|
+
4.times do |t|
|
73
|
+
sha1 = generate_commit "new_commit#{t}"
|
74
|
+
g.deploy_branch('test')
|
75
|
+
# Here we must simulate the log creating which will be done by the deployer
|
76
|
+
FileUtils.touch("#{@config['test_project']['target_directory']}/logs/#{sha1}.log")
|
77
|
+
assert File.exists?(@config['test_project']['target_directory'] + "/logs")
|
78
|
+
assert File.exists?(@config['test_project']['target_directory'] + "/branches/test/new_commit#{t}")
|
79
|
+
# The checkouts_to_keep in config.yml is set to 3 (so 5 is the maximum: 3 + '.' + '..')
|
80
|
+
assert_equal (3+t > 5 ? 5 : 3+t), Dir.entries(@config['test_project']['target_directory'] + '/checkouts/test').size
|
81
|
+
assert_equal (3+t > 5 ? 5 : 3+t), Dir.entries(@config['test_project']['target_directory'] + '/logs').size
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_should_maintain_only_one_master_checkout
|
86
|
+
g = Hercules::GitHandler.new(@config['test_project'])
|
87
|
+
g.deploy_branch('master')
|
88
|
+
generate_commit 'new_commit'
|
89
|
+
g.deploy_branch('master')
|
90
|
+
assert File.exists?(@config['test_project']['target_directory'] + '/branches/master/new_commit')
|
91
|
+
assert_equal 3, Dir.entries(@config['test_project']['target_directory'] + '/checkouts/master').size
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
data/tests/git_setup.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'rubygems'
|
3
|
+
require 'git'
|
4
|
+
require 'lib/git_handler'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
module GitSetup
|
8
|
+
def git_setup
|
9
|
+
@config = YAML.load_file(File.dirname(__FILE__) + '/fixtures/config.yml')
|
10
|
+
dir = @config['test_project']['repository'].gsub(/file:\/\//, '')
|
11
|
+
FileUtils.rm_rf(dir)
|
12
|
+
FileUtils.rm_rf(@config['test_project']['target_directory'])
|
13
|
+
FileUtils.mkdir_p(dir)
|
14
|
+
FileUtils.cp(File.dirname(__FILE__) + '/fixtures/config.yml', "#{dir}/config.yml")
|
15
|
+
FileUtils.cp(File.dirname(__FILE__) + '/fixtures/Gemfile', "#{dir}/Gemfile")
|
16
|
+
FileUtils.cp(File.dirname(__FILE__) + '/fixtures/Gemfile.lock', "#{dir}/Gemfile.lock")
|
17
|
+
@g = Git.init(dir)
|
18
|
+
@g.chdir do
|
19
|
+
@g.config('user.name', 'Test User')
|
20
|
+
@g.config('user.email', 'email@email.com')
|
21
|
+
@g.add("./config.yml")
|
22
|
+
@g.add("./Gemfile")
|
23
|
+
@g.add("./Gemfile.lock")
|
24
|
+
@g.commit_all('message')
|
25
|
+
@head_sha = @g.gcommit('HEAD').sha
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def generate_bogus_gemfile
|
30
|
+
change_repository do
|
31
|
+
File.open('./Gemfile', 'a'){|f| f.write('gem syntax error "Gem_That_Does_Not_Exist", "0.0.0", - % $ ') }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def generate_gemfile_with_gem
|
36
|
+
path = File.expand_path( File.dirname(__FILE__) )
|
37
|
+
change_repository do
|
38
|
+
FileUtils.cp("#{path}/fixtures/Gemfile.with_git_gem", "./Gemfile")
|
39
|
+
FileUtils.cp("#{path}/fixtures/Gemfile.with_git_gem.lock", "./Gemfile.lock")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def generate_deployer(deployer_name)
|
44
|
+
path = File.expand_path( File.dirname(__FILE__) )
|
45
|
+
change_repository do
|
46
|
+
FileUtils.mkdir_p("./lib")
|
47
|
+
FileUtils.cp("#{path}/fixtures/#{deployer_name}.rb", "./lib/hercules_triggers.rb")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def generate_commit file_name
|
52
|
+
change_repository{ FileUtils.touch file_name }
|
53
|
+
end
|
54
|
+
|
55
|
+
def change_repository
|
56
|
+
head_sha = @head_sha
|
57
|
+
@g.chdir do
|
58
|
+
yield
|
59
|
+
@g.add("./*")
|
60
|
+
@g.commit_all("added files")
|
61
|
+
head_sha = @g.gcommit('HEAD').sha
|
62
|
+
end
|
63
|
+
return head_sha
|
64
|
+
end
|
65
|
+
|
66
|
+
def assert_is_checkout(dir)
|
67
|
+
assert_equal File.open(File.dirname(__FILE__) + '/fixtures/config.yml').read, File.open(dir + '/config.yml').read
|
68
|
+
assert !File.exists?(dir + '/.git')
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'tests/startup'
|
3
|
+
require 'tests/git_setup'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
class HerculesTest < Test::Unit::TestCase
|
7
|
+
include Startup
|
8
|
+
include GitSetup
|
9
|
+
|
10
|
+
def setup
|
11
|
+
prepare_startup
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_startup_validations
|
15
|
+
verbose(false) do
|
16
|
+
# Here we test for config file require
|
17
|
+
sh "src/hercules.rb -l /dev/null > /dev/null 2>&1" rescue nil
|
18
|
+
sleep 1
|
19
|
+
assert !File.exist?(@pidfile)
|
20
|
+
|
21
|
+
# Test with an invalid yaml
|
22
|
+
sh "src/hercules.rb -c src/hercules.rb -l /dev/null > /dev/null 2>&1" rescue nil
|
23
|
+
sleep 1
|
24
|
+
assert !File.exist?(@pidfile)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_logfile_and_piddir
|
29
|
+
start_hercules do |pid,log|
|
30
|
+
assert File.exist?(@logfile)
|
31
|
+
assert_match /Start/, log.read()
|
32
|
+
assert File.exist?(@pidfile)
|
33
|
+
assert_match /\d+/, pid
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_send_term
|
38
|
+
start_hercules do |pid,log|
|
39
|
+
Process.kill("TERM", pid.to_i)
|
40
|
+
sleep 1
|
41
|
+
assert !File.exist?(@pidfile)
|
42
|
+
assert_match /Terminating hercules/, log.read
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_send_hup
|
47
|
+
start_hercules do |pid,log|
|
48
|
+
Process.kill("HUP", pid.to_i)
|
49
|
+
sleep 1
|
50
|
+
assert File.exist?(@pidfile)
|
51
|
+
log_content = log.read
|
52
|
+
assert_match /Reloading config/, log_content
|
53
|
+
assert_no_match /Error reading/, log_content
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_send_hup_with_bad_config_file
|
58
|
+
start_hercules do |pid,log|
|
59
|
+
FileUtils.mv "tests/fixtures/config.yml", "tests/fixtures/config.old.yml"
|
60
|
+
FileUtils.mv "tests/fixtures/bogus_config.yml", "tests/fixtures/config.yml"
|
61
|
+
Process.kill("HUP", pid.to_i)
|
62
|
+
sleep 1
|
63
|
+
assert File.exist?(@pidfile)
|
64
|
+
log_content = log.read
|
65
|
+
FileUtils.mv "tests/fixtures/config.yml", "tests/fixtures/bogus_config.yml"
|
66
|
+
FileUtils.mv "tests/fixtures/config.old.yml", "tests/fixtures/config.yml"
|
67
|
+
assert_match /Reloading config/, log_content
|
68
|
+
assert_match /Error reading/, log_content
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_checkouts_on_startup_with_errors
|
73
|
+
git_setup
|
74
|
+
FileUtils.mv "tests/fixtures/config.yml", "tests/fixtures/config.old.yml"
|
75
|
+
FileUtils.mv "tests/fixtures/startup_checkout_error_config.yml", "tests/fixtures/config.yml"
|
76
|
+
begin
|
77
|
+
log_content = ""
|
78
|
+
start_hercules do |pid,log|
|
79
|
+
sleep 5
|
80
|
+
log_content = log.read
|
81
|
+
assert_match /Branch master deployed/, log_content
|
82
|
+
assert File.exist?(@pidfile)
|
83
|
+
end
|
84
|
+
ensure
|
85
|
+
FileUtils.mv "tests/fixtures/config.yml", "tests/fixtures/startup_checkout_error_config.yml"
|
86
|
+
FileUtils.mv "tests/fixtures/config.old.yml", "tests/fixtures/config.yml"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_checkouts_on_startup
|
91
|
+
git_setup
|
92
|
+
FileUtils.mv "tests/fixtures/config.yml", "tests/fixtures/config.old.yml"
|
93
|
+
FileUtils.mv "tests/fixtures/startup_checkout_config.yml", "tests/fixtures/config.yml"
|
94
|
+
start_hercules do |pid,log|
|
95
|
+
FileUtils.mv "tests/fixtures/config.yml", "tests/fixtures/startup_checkout_config.yml"
|
96
|
+
FileUtils.mv "tests/fixtures/config.old.yml", "tests/fixtures/config.yml"
|
97
|
+
sleep 5
|
98
|
+
log_content = log.read
|
99
|
+
assert_match /Branch master deployed/, log_content
|
100
|
+
assert_is_checkout @config['test_project']['target_directory'] + '/branches/master'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_no_checkouts_on_startups_with_default_config
|
105
|
+
git_setup
|
106
|
+
start_hercules do |pid,log|
|
107
|
+
sleep 5
|
108
|
+
log_content = log.read
|
109
|
+
assert_no_match /Branch master deployed/, log_content
|
110
|
+
assert !File.exist?(@config['test_project']['target_directory'] + '/branches/master')
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_checkouts_on_startup_with_hidden_tmp
|
115
|
+
git_setup
|
116
|
+
FileUtils.mv "tests/fixtures/config.yml", "tests/fixtures/config.old.yml"
|
117
|
+
FileUtils.mv "tests/fixtures/startup_checkout_config.yml", "tests/fixtures/config.yml"
|
118
|
+
FileUtils.mkdir_p @config['test_project']['target_directory'] + '/checkouts/master/.tmp'
|
119
|
+
start_hercules do |pid,log|
|
120
|
+
FileUtils.mv "tests/fixtures/config.yml", "tests/fixtures/startup_checkout_config.yml"
|
121
|
+
FileUtils.mv "tests/fixtures/config.old.yml", "tests/fixtures/config.yml"
|
122
|
+
sleep 20
|
123
|
+
log_content = log.read
|
124
|
+
assert_match /Branch master deployed/, log_content
|
125
|
+
assert_is_checkout @config['test_project']['target_directory'] + '/branches/master'
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|