specjour 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.markdown +12 -0
- data/README.markdown +22 -6
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/lib/specjour/cpu.rb +9 -3
- data/lib/specjour/manager.rb +1 -0
- data/lib/specjour/rsync_daemon.rb +42 -16
- data/lib/specjour.rb +1 -1
- data/spec/cpu_spec.rb +28 -0
- data/spec/manager_spec.rb +20 -0
- data/spec/rsync_daemon_spec.rb +43 -20
- data/spec/spec_helper.rb +1 -1
- metadata +23 -5
data/History.markdown
CHANGED
@@ -1,6 +1,18 @@
|
|
1
1
|
History
|
2
2
|
=======
|
3
3
|
|
4
|
+
0.2.3
|
5
|
+
-----
|
6
|
+
*2010-04-25*
|
7
|
+
|
8
|
+
* [fixed] Absolute paths in rsyncd.conf restrict portability. The rsync daemon
|
9
|
+
completely fails when it can't find the path to serve which typically happens
|
10
|
+
running specjour on another computer. Remove your rsyncd.conf to regenerate a
|
11
|
+
new one. Back it up first if you've made changes to it.
|
12
|
+
**Backwards Incompatible**
|
13
|
+
|
14
|
+
* [fixed] CPU core detection works on OSX Core i7 (thanks Hashrocket!)
|
15
|
+
|
4
16
|
0.2.2
|
5
17
|
-----
|
6
18
|
*2010-04-22*
|
data/README.markdown
CHANGED
@@ -37,19 +37,31 @@ Run the rake task to distribute the features among the managers you started.
|
|
37
37
|
$ rake specjour:cucumber
|
38
38
|
|
39
39
|
## Rails
|
40
|
-
Edit your config/environment.rb
|
41
|
-
|
42
|
-
config.gem 'specjour'
|
43
|
-
|
44
40
|
Each worker should run their specs in an isolated database. Modify the test database name in your `config/database.yml` to include the following environment variable (Influenced by [parallel_tests](http://github.com/grosser/parallel_tests)):
|
45
41
|
|
46
42
|
test:
|
47
43
|
database: blog_test<%=ENV['TEST_ENV_NUMBER']%>
|
48
44
|
|
49
|
-
|
45
|
+
Add the specjour gem to your project:
|
46
|
+
|
47
|
+
config.gem 'specjour'
|
48
|
+
|
49
|
+
Doing this enables a rails plugin wherein each worker will attempt to clear its database tables before running any specs via `DELETE FROM <table_name>;`. Additionally, test databases will be created if they don't exist (i.e. `CREATE DATABASE blog_test8` for the 8th worker) and your schema will be loaded when the database is out of date.
|
50
|
+
|
51
|
+
### Customizing database setup
|
52
|
+
If the plugin doesn't set up the database properly for your test suite, bypass it entirely. Remove specjour as a project gem and create your own initializer to setup the database. Specjour sets the environment variable PREPARE_DB when it runs your specs so you can look for that when setting up the database.
|
53
|
+
|
54
|
+
# config/initializers/specjour.rb
|
55
|
+
|
56
|
+
if ENV['PREPARE_DB']
|
57
|
+
load 'Rakefile'
|
58
|
+
|
59
|
+
# clear the db and load db/seeds.rb
|
60
|
+
Rake::Task['db:reset'].invoke
|
61
|
+
end
|
50
62
|
|
51
63
|
## Only listen to supported projects
|
52
|
-
By default, a manager will listen to all projects trying to distribute specs over the network. Sometimes you'll only want a manager to respond to one specific spec suite. You can accomplish this with the `--projects`
|
64
|
+
By default, a manager will listen to all projects trying to distribute specs over the network. Sometimes you'll only want a manager to respond to one specific spec suite. You can accomplish this with the `--projects` flag.
|
53
65
|
|
54
66
|
$ specjour --projects bizconf # only run specs for the bizconf project
|
55
67
|
|
@@ -72,10 +84,14 @@ Distributed testing doesn't have to happen over multiple machines, just multiple
|
|
72
84
|
* shayarnett - Cucumber support, pairing and other various patches
|
73
85
|
* voxdolo - Endless support, alpha testing, various patches
|
74
86
|
* leshill - Made rsync daemon configurable
|
87
|
+
* testjour - Ripped off your name
|
88
|
+
* parallel_tests - Made my test suite twice as fast
|
75
89
|
|
76
90
|
## Note on Patches/Pull Requests
|
77
91
|
|
78
92
|
* Fork the project.
|
93
|
+
* `$ source .dev` to ensure you're using the local specjour binary, not the
|
94
|
+
rubygems version
|
79
95
|
* Make your feature addition or bug fix.
|
80
96
|
* Add tests for it. This is important so I don't break it in a
|
81
97
|
future version unintentionally.
|
data/Rakefile
CHANGED
@@ -13,6 +13,7 @@ begin
|
|
13
13
|
gem.add_dependency "dnssd", "1.3.1"
|
14
14
|
gem.add_dependency "rspec"
|
15
15
|
gem.add_development_dependency "rspec", "1.3.0"
|
16
|
+
gem.add_development_dependency "rr", "0.10.11"
|
16
17
|
gem.add_development_dependency "yard", "0.5.3"
|
17
18
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
19
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.3
|
data/lib/specjour/cpu.rb
CHANGED
@@ -1,13 +1,19 @@
|
|
1
1
|
module Specjour
|
2
2
|
module CPU
|
3
|
-
# inspired by github.com/grosser/parallel
|
4
3
|
def self.cores
|
5
4
|
case RUBY_PLATFORM
|
6
5
|
when /darwin/
|
7
|
-
|
6
|
+
command('hostinfo') =~ /^(\d+).+logically/
|
7
|
+
$1.to_i
|
8
8
|
when /linux/
|
9
|
-
|
9
|
+
command('grep --count processor /proc/cpuinfo').to_i
|
10
10
|
end
|
11
11
|
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def self.command(cmd)
|
16
|
+
%x(#{cmd})
|
17
|
+
end
|
12
18
|
end
|
13
19
|
end
|
data/lib/specjour/manager.rb
CHANGED
@@ -3,6 +3,12 @@ module Specjour
|
|
3
3
|
require 'fileutils'
|
4
4
|
include SocketHelpers
|
5
5
|
|
6
|
+
# Corresponds to the version of specjour that changed the configuration
|
7
|
+
# file.
|
8
|
+
CONFIG_VERSION = "0.2.3".freeze
|
9
|
+
CONFIG_FILE_NAME = "rsyncd.conf"
|
10
|
+
PID_FILE_NAME = "rsyncd.pid"
|
11
|
+
|
6
12
|
attr_reader :project_path, :project_name
|
7
13
|
|
8
14
|
def initialize(project_path, project_name)
|
@@ -15,7 +21,7 @@ module Specjour
|
|
15
21
|
end
|
16
22
|
|
17
23
|
def config_file
|
18
|
-
@config_file ||= File.join(config_directory,
|
24
|
+
@config_file ||= File.join(config_directory, CONFIG_FILE_NAME)
|
19
25
|
end
|
20
26
|
|
21
27
|
def pid
|
@@ -25,13 +31,15 @@ module Specjour
|
|
25
31
|
end
|
26
32
|
|
27
33
|
def pid_file
|
28
|
-
File.join(config_directory,
|
34
|
+
File.join(config_directory, PID_FILE_NAME)
|
29
35
|
end
|
30
36
|
|
31
37
|
def start
|
32
38
|
write_config
|
33
|
-
|
34
|
-
|
39
|
+
Dir.chdir(project_path) do
|
40
|
+
Kernel.system *command
|
41
|
+
end
|
42
|
+
Kernel.at_exit { stop }
|
35
43
|
end
|
36
44
|
|
37
45
|
def stop
|
@@ -43,38 +51,56 @@ module Specjour
|
|
43
51
|
|
44
52
|
protected
|
45
53
|
|
54
|
+
def command
|
55
|
+
["rsync", "--daemon", "--config=#{config_file}", "--port=8989"]
|
56
|
+
end
|
57
|
+
|
58
|
+
def check_config_version
|
59
|
+
File.read(config_file) =~ /\A# (\d+.\d+.\d+)/
|
60
|
+
if out_of_date? Regexp.last_match(1)
|
61
|
+
$stderr.puts <<-WARN
|
62
|
+
|
63
|
+
Specjour has made changes to the way #{CONFIG_FILE_NAME} is generated.
|
64
|
+
Back up '#{config_file}'
|
65
|
+
and re-run the dispatcher to generate the new config file.
|
66
|
+
|
67
|
+
WARN
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def out_of_date?(version)
|
72
|
+
CONFIG_VERSION != version
|
73
|
+
end
|
74
|
+
|
46
75
|
def write_config
|
47
|
-
|
76
|
+
if File.exists? config_file
|
77
|
+
check_config_version
|
78
|
+
else
|
48
79
|
FileUtils.mkdir_p config_directory
|
49
|
-
|
50
80
|
File.open(config_file, 'w') do |f|
|
51
81
|
f.write config
|
52
82
|
end
|
53
83
|
end
|
54
84
|
end
|
55
85
|
|
56
|
-
def command
|
57
|
-
["rsync", "--daemon", "--config=#{config_file}", "--port=8989"]
|
58
|
-
end
|
59
|
-
|
60
86
|
def config
|
61
87
|
<<-CONFIG
|
62
|
-
# #{
|
63
|
-
#
|
88
|
+
# #{CONFIG_VERSION}
|
89
|
+
# Rsync daemon config for #{project_name}
|
64
90
|
#
|
65
91
|
# Serve this project with the following command:
|
66
|
-
# $ #{command.join(' ')}
|
92
|
+
# $ #{(command | ['--no-detach']).join(' ')}
|
67
93
|
#
|
68
94
|
# Rsync with the following command:
|
69
|
-
# $ rsync -a --port=8989 #{hostname}::#{project_name}
|
95
|
+
# $ rsync -a --port=8989 #{hostname}::#{project_name} /tmp/#{project_name}
|
70
96
|
#
|
71
97
|
use chroot = no
|
72
98
|
timeout = 20
|
73
99
|
read only = yes
|
74
|
-
pid file =
|
100
|
+
pid file = ./.specjour/#{PID_FILE_NAME}
|
75
101
|
|
76
102
|
[#{project_name}]
|
77
|
-
path =
|
103
|
+
path = .
|
78
104
|
exclude = .git* .specjour doc tmp/* log script
|
79
105
|
CONFIG
|
80
106
|
end
|
data/lib/specjour.rb
CHANGED
data/spec/cpu_spec.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Specjour::CPU do
|
4
|
+
context "on a Mac" do
|
5
|
+
let(:hostinfo) do
|
6
|
+
%(
|
7
|
+
Mach kernel version:
|
8
|
+
Darwin Kernel Version 10.2.0: Tue Nov 3 10:37:10 PST 2009; root:xnu-1486.2.11~1/RELEASE_I386
|
9
|
+
Kernel configured for up to 2 processors.
|
10
|
+
2 processors are physically available.
|
11
|
+
220 processors are logically available.
|
12
|
+
Processor type: i486 (Intel 80486)
|
13
|
+
Processors active: 0 1
|
14
|
+
Primary memory available: 4.00 gigabytes
|
15
|
+
Default processor set: 72 tasks, 310 threads, 2 processors
|
16
|
+
Load average: 0.09, Mach factor: 1.90
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
before do
|
21
|
+
stub(Specjour::CPU).command.returns(hostinfo)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returns the number of logically available processors" do
|
25
|
+
Specjour::CPU.cores.should == 220
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Specjour::Manager do
|
4
|
+
describe "#available_for?" do
|
5
|
+
it "is available for all projects by default" do
|
6
|
+
subject.available_for?(rand.to_s).should be_true
|
7
|
+
end
|
8
|
+
|
9
|
+
it "is available for one project" do
|
10
|
+
manager = Specjour::Manager.new :registered_projects => %w(one)
|
11
|
+
manager.available_for?('one').should be_true
|
12
|
+
end
|
13
|
+
|
14
|
+
it "is available for many projects" do
|
15
|
+
manager = Specjour::Manager.new :registered_projects => %w(one two)
|
16
|
+
manager.available_for?('one').should be_true
|
17
|
+
manager.available_for?('two').should be_true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/rsync_daemon_spec.rb
CHANGED
@@ -6,32 +6,31 @@ describe Specjour::RsyncDaemon do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
before do
|
9
|
-
stub(
|
10
|
-
stub(
|
11
|
-
|
9
|
+
stub(Kernel).system
|
10
|
+
stub(Kernel).at_exit
|
11
|
+
stub(Dir).chdir
|
12
|
+
stub(File).open
|
13
|
+
stub(File).read
|
12
14
|
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
describe "#config_file" do
|
19
|
-
specify { subject.config_file.should == '/tmp/seasonal/.specjour/rsyncd.conf' }
|
20
|
-
end
|
16
|
+
specify { subject.config_directory.should == '/tmp/seasonal/.specjour' }
|
17
|
+
specify { subject.config_file.should == '/tmp/seasonal/.specjour/rsyncd.conf' }
|
21
18
|
|
22
19
|
describe "#start" do
|
23
20
|
it "writes the config" do
|
24
|
-
subject.
|
21
|
+
mock(subject).write_config
|
25
22
|
subject.start
|
26
23
|
end
|
27
24
|
|
28
|
-
it "executes the system command" do
|
29
|
-
|
25
|
+
it "executes the system command in the project directory" do
|
26
|
+
mock(Kernel).system(*subject.send(:command))
|
27
|
+
mock(Dir).chdir(subject.project_path).yields
|
30
28
|
subject.start
|
31
29
|
end
|
32
30
|
|
33
31
|
it "stops at_exit" do
|
34
|
-
subject.
|
32
|
+
mock(subject).stop
|
33
|
+
mock.proxy(Kernel).at_exit.yields(subject)
|
35
34
|
subject.start
|
36
35
|
end
|
37
36
|
end
|
@@ -39,27 +38,51 @@ describe Specjour::RsyncDaemon do
|
|
39
38
|
describe "#stop" do
|
40
39
|
context "with pid" do
|
41
40
|
before do
|
42
|
-
subject.
|
43
|
-
Process.
|
44
|
-
FileUtils.
|
41
|
+
stub(subject).pid.returns(100_000_000)
|
42
|
+
stub(Process).kill
|
43
|
+
stub(FileUtils).rm
|
45
44
|
end
|
46
45
|
|
47
46
|
it "kills the pid with TERM" do
|
48
|
-
Process.
|
47
|
+
mock(Process).kill('TERM', subject.pid)
|
49
48
|
subject.stop
|
50
49
|
end
|
51
50
|
|
52
51
|
it "removes the pid file" do
|
53
|
-
FileUtils.
|
52
|
+
mock(FileUtils).rm(subject.pid_file)
|
54
53
|
subject.stop
|
55
54
|
end
|
56
55
|
end
|
57
56
|
|
58
57
|
context "without pid" do
|
59
58
|
it "does nothing" do
|
60
|
-
subject.
|
59
|
+
stub(subject).pid
|
61
60
|
subject.stop.should be_nil
|
62
61
|
end
|
63
62
|
end
|
64
63
|
end
|
64
|
+
|
65
|
+
describe "#check_config_version" do
|
66
|
+
it "warns when the version is out of date" do
|
67
|
+
stub(File).read { "# 0.0.0\n" }
|
68
|
+
mock($stderr).puts(/made changes/)
|
69
|
+
subject.send(:check_config_version)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "doesn't warn when the version isn't out of date" do
|
73
|
+
stub(File).read { "# #{Specjour::RsyncDaemon::CONFIG_VERSION}\n" }
|
74
|
+
dont_allow($stderr).puts
|
75
|
+
subject.send(:check_config_version)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#write_config" do
|
80
|
+
context "config exists" do
|
81
|
+
it "checks if the config is out of date" do
|
82
|
+
stub(File).exists?(anything) { true }
|
83
|
+
mock(subject).check_config_version
|
84
|
+
subject.send(:write_config)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
65
88
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
8
|
+
- 3
|
9
|
+
version: 0.2.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Sandro Turriate
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-04-
|
17
|
+
date: 2010-04-26 00:00:00 -04:00
|
18
18
|
default_executable: specjour
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -58,9 +58,23 @@ dependencies:
|
|
58
58
|
type: :development
|
59
59
|
version_requirements: *id003
|
60
60
|
- !ruby/object:Gem::Dependency
|
61
|
-
name:
|
61
|
+
name: rr
|
62
62
|
prerelease: false
|
63
63
|
requirement: &id004 !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
- 10
|
70
|
+
- 11
|
71
|
+
version: 0.10.11
|
72
|
+
type: :development
|
73
|
+
version_requirements: *id004
|
74
|
+
- !ruby/object:Gem::Dependency
|
75
|
+
name: yard
|
76
|
+
prerelease: false
|
77
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
78
|
requirements:
|
65
79
|
- - "="
|
66
80
|
- !ruby/object:Gem::Version
|
@@ -70,7 +84,7 @@ dependencies:
|
|
70
84
|
- 3
|
71
85
|
version: 0.5.3
|
72
86
|
type: :development
|
73
|
-
version_requirements: *
|
87
|
+
version_requirements: *id005
|
74
88
|
description: Distribute your spec suite amongst your LAN via Bonjour.
|
75
89
|
email: sandro.turriate@gmail.com
|
76
90
|
executables:
|
@@ -112,7 +126,9 @@ files:
|
|
112
126
|
- lib/specjour/tasks/specjour.rb
|
113
127
|
- lib/specjour/worker.rb
|
114
128
|
- rails/init.rb
|
129
|
+
- spec/cpu_spec.rb
|
115
130
|
- spec/lib/specjour/worker_spec.rb
|
131
|
+
- spec/manager_spec.rb
|
116
132
|
- spec/rsync_daemon_spec.rb
|
117
133
|
- spec/spec.opts
|
118
134
|
- spec/spec_helper.rb
|
@@ -148,7 +164,9 @@ signing_key:
|
|
148
164
|
specification_version: 3
|
149
165
|
summary: Distribute your spec suite amongst your LAN via Bonjour.
|
150
166
|
test_files:
|
167
|
+
- spec/cpu_spec.rb
|
151
168
|
- spec/lib/specjour/worker_spec.rb
|
169
|
+
- spec/manager_spec.rb
|
152
170
|
- spec/rsync_daemon_spec.rb
|
153
171
|
- spec/spec_helper.rb
|
154
172
|
- spec/specjour_spec.rb
|