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 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
- 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 will load your schema when it has fallen behind.
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` flags.
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.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
- `hwprefs cpu_count`.to_i
6
+ command('hostinfo') =~ /^(\d+).+logically/
7
+ $1.to_i
8
8
  when /linux/
9
- `grep --count processor /proc/cpuinfo`.to_i
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
@@ -61,6 +61,7 @@ module Specjour
61
61
 
62
62
  def start
63
63
  drb_start
64
+ puts "Workers ready: #{worker_size}"
64
65
  bonjour_announce
65
66
  Signal.trap('INT') { puts; puts "Shutting down manager..."; exit }
66
67
  DRb.thread.join
@@ -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, "rsyncd.conf")
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, "rsync_daemon.pid")
34
+ File.join(config_directory, PID_FILE_NAME)
29
35
  end
30
36
 
31
37
  def start
32
38
  write_config
33
- system *command
34
- at_exit { stop }
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
- unless File.exists? config_file
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
- # #{Specjour::VERSION}
63
- # Anonymous rsync daemon config for #{project_name}
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} ~/#{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 = #{pid_file}
100
+ pid file = ./.specjour/#{PID_FILE_NAME}
75
101
 
76
102
  [#{project_name}]
77
- path = #{project_path}
103
+ path = .
78
104
  exclude = .git* .specjour doc tmp/* log script
79
105
  CONFIG
80
106
  end
data/lib/specjour.rb CHANGED
@@ -23,7 +23,7 @@ module Specjour
23
23
  autoload :Cucumber, 'specjour/cucumber'
24
24
  autoload :Rspec, 'specjour/rspec'
25
25
 
26
- VERSION = "0.2.2".freeze
26
+ VERSION = "0.2.3".freeze
27
27
 
28
28
  class Error < StandardError; end
29
29
 
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
@@ -6,32 +6,31 @@ describe Specjour::RsyncDaemon do
6
6
  end
7
7
 
8
8
  before do
9
- stub(:system)
10
- stub(:at_exit)
11
- subject.stub(:write_config)
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
- describe "#config_directory" do
15
- specify { subject.config_directory.should == '/tmp/seasonal/.specjour' }
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.should_receive(:write_config)
21
+ mock(subject).write_config
25
22
  subject.start
26
23
  end
27
24
 
28
- it "executes the system command" do
29
- subject.should_receive(:system).with(*subject.send(:command))
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.should_receive(:at_exit)
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.stub(:pid => 100_000_000)
43
- Process.stub(:kill)
44
- FileUtils.stub(:rm)
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.should_receive(:kill).with('TERM', subject.pid)
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.should_receive(:rm).with(subject.pid_file)
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.stub(:pid => nil)
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
@@ -4,5 +4,5 @@ require 'specjour'
4
4
  require 'spec/autorun'
5
5
 
6
6
  Spec::Runner.configure do |config|
7
-
7
+ config.mock_with :rr
8
8
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 2
9
- version: 0.2.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-22 00:00:00 -04:00
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: yard
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: *id004
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