process-group 0.2.0 → 0.2.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 372a5e01e0eec6598278b7b6d9d7752f59190b66
4
+ data.tar.gz: ef2061f5503a85c60a0e56a81efaff25b1d95dc6
5
+ SHA512:
6
+ metadata.gz: ffff6097b47894fef08ad2e083d0a5834929393d278085b00c3e6a5dfc508801266c0a2752f437feea24b7b1f43fcc9f368584df45d3dbcdf00fd04e87c97dcb
7
+ data.tar.gz: bff7b9a0140d6e6c5655824ac4b7110b75a2095b281a1d5e143870dac6dfc6454d792e7a21f4fc1403de4bae53243863796296afd75bf9906521ba887fea878c
data/Rakefile CHANGED
@@ -1,9 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
- require "rake/testtask"
2
+ require "rspec/core/rake_task"
3
3
 
4
- Rake::TestTask.new do |t|
5
- t.libs << 'test'
6
- end
4
+ RSpec::Core::RakeTask.new(:spec)
7
5
 
8
- desc "Run tests"
9
- task :default => :test
6
+ task :default => :spec
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Copyright, 2014, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative '../lib/process/group'
24
+
25
+ group = Process::Group.new
26
+
27
+ 5.times do
28
+ Fiber.new do
29
+ result = group.fork do
30
+ begin
31
+ sleep 1 while true
32
+ rescue Interrupt
33
+ puts "Interrupted in child #{Process.pid}"
34
+ end
35
+ end
36
+ end.resume
37
+ end
38
+
39
+ begin
40
+ group.wait
41
+ rescue Interrupt
42
+ puts "Interrupted in parent #{Process.pid}"
43
+ end
@@ -1,5 +1,25 @@
1
+ # Copyright, 2014, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
1
21
  module Process
2
22
  class Group
3
- VERSION = "0.2.0"
23
+ VERSION = "0.2.1"
4
24
  end
5
25
  end
@@ -21,7 +21,6 @@ Gem::Specification.new do |spec|
21
21
  spec.require_paths = ["lib"]
22
22
 
23
23
  spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rspec", "~> 3.0.0.rc1"
24
25
  spec.add_development_dependency "rake"
25
- spec.add_development_dependency "betatest"
26
- spec.add_development_dependency "mocha"
27
26
  end
@@ -0,0 +1,62 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'process/group'
22
+
23
+ module Process::Group::ForkSpec
24
+ describe Process::Group do
25
+ it "should fork and write to pipe" do
26
+ group = Process::Group.new
27
+
28
+ input, output = IO.pipe
29
+
30
+ Fiber.new do
31
+ result = group.fork do
32
+ output.puts "Hello World"
33
+
34
+ exit(1)
35
+ end
36
+
37
+ expect(result.exitstatus).to be == 1
38
+ end.resume
39
+
40
+ output.close
41
+
42
+ group.wait
43
+
44
+ expect(input.read).to be == "Hello World\n"
45
+ end
46
+
47
+ it "should not throw interrupt from fork" do
48
+ group = Process::Group.new
49
+
50
+ Fiber.new do
51
+ result = group.fork do
52
+ raise Interrupt
53
+ end
54
+
55
+ expect(result.exitstatus).not_to be == 0
56
+ end.resume
57
+
58
+ # Shouldn't raise any errors:
59
+ group.wait
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,150 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'process/group'
22
+
23
+ module Process::Group::InterruptSpec
24
+ describe Process::Group do
25
+ it "should raise interrupt exception" do
26
+ group = Process::Group.new
27
+ checkpoint = ""
28
+
29
+ Fiber.new do
30
+ checkpoint += 'X'
31
+
32
+ result = group.fork { sleep 0.1 }
33
+
34
+ expect(result).to be == 0
35
+
36
+ checkpoint += 'Y'
37
+
38
+ # Simulate the user pressing Ctrl-C after 0.5 seconds:
39
+ raise Interrupt
40
+ end.resume
41
+
42
+ Fiber.new do
43
+ checkpoint += 'A'
44
+
45
+ # This never returns:
46
+ result = group.fork { sleep 0.2 }
47
+
48
+ checkpoint += 'B'
49
+ end.resume
50
+
51
+ expect(group).to receive(:kill).with(:INT).once
52
+ expect(group).to receive(:kill).with(:TERM).once
53
+
54
+ expect do
55
+ group.wait
56
+ end.to raise_error(Interrupt)
57
+
58
+ expect(checkpoint).to be == 'XAY'
59
+ end
60
+
61
+ it "should raise an exception" do
62
+ group = Process::Group.new
63
+ checkpoint = ""
64
+
65
+ Fiber.new do
66
+ checkpoint += 'X'
67
+
68
+ result = group.fork { sleep 0.1 }
69
+ expect(result).to be == 0
70
+
71
+ checkpoint += 'Y'
72
+
73
+ # Raises a RuntimeError
74
+ fail "Error"
75
+ end.resume
76
+
77
+ Fiber.new do
78
+ checkpoint += 'A'
79
+
80
+ # This never returns:
81
+ result = group.fork { sleep 0.2 }
82
+
83
+ checkpoint += 'B'
84
+ end.resume
85
+
86
+ expect do
87
+ expect(group).to receive(:kill).with(:TERM).once
88
+
89
+ group.wait
90
+ end.to raise_error(RuntimeError)
91
+
92
+ expect(checkpoint).to be == 'XAY'
93
+ end
94
+
95
+ class Timeout < StandardError
96
+ end
97
+
98
+ it "should pass back out exceptions" do
99
+ group = Process::Group.new
100
+ checkpoint = ""
101
+
102
+ Fiber.new do
103
+ # Wait for 2 seconds, let other processes run:
104
+ group.fork { sleep 2 }
105
+ checkpoint += 'A'
106
+ #puts "Finished waiting #1..."
107
+
108
+ # If no other processes are running, we are done:
109
+ Fiber.yield unless group.running?
110
+ checkpoint += 'B'
111
+ #puts "Sending SIGINT..."
112
+
113
+ # Send SIGINT to currently running processes:
114
+ group.kill(:INT)
115
+
116
+ # Wait for 2 seconds, let other processes run:
117
+ group.fork { sleep 2 }
118
+ checkpoint += 'C'
119
+ #puts "Finished waiting #2..."
120
+
121
+ # If no other processes are running, we are done:
122
+ Fiber.yield unless group.running?
123
+ checkpoint += 'D'
124
+ #puts "Sending SIGTERM..."
125
+
126
+ # Send SIGTERM to currently running processes:
127
+ group.kill(:TERM)
128
+
129
+ # Raise an Timeout exception which is pased back out:
130
+ raise Timeout
131
+ end.resume
132
+
133
+ # Run some other long task:
134
+ group.run("sleep 10")
135
+
136
+ start_time = Time.now
137
+
138
+ # Wait for fiber to complete:
139
+ expect do
140
+ group.wait
141
+ checkpoint += 'E'
142
+ end.not_to raise_error
143
+
144
+ end_time = Time.now
145
+
146
+ expect(checkpoint).to be == 'ABCE'
147
+ expect(end_time - start_time).to be_within(0.1).of 4.0
148
+ end
149
+ end
150
+ end
@@ -18,45 +18,39 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
- require 'betatest/autorun'
22
-
23
21
  require 'process/group'
24
22
 
25
- class TestFork < Betatest::Test
26
- def test_fork_io
27
- group = Process::Group.new
23
+ module Process::Group::IOSpec
24
+ describe Process::Group do
25
+ it "should read line on separate thread" do
26
+ group = Process::Group.new
28
27
 
29
- input, output = IO.pipe
28
+ input, output = IO.pipe
30
29
 
31
- Fiber.new do
32
- result = group.fork do
33
- output.puts "Hello World"
30
+ Fiber.new do
31
+ result = group.fork do
32
+ 3.times do
33
+ output.puts "Hello World"
34
+ sleep 0.1
35
+ end
34
36
 
35
- exit(1)
36
- end
37
+ exit(0)
38
+ end
39
+
40
+ expect(result).to be == 0
41
+ end.resume
37
42
 
38
- assert_equal 1, result.exitstatus
39
- end.resume
40
-
41
- output.close
42
-
43
- group.wait
44
-
45
- assert_equal "Hello World\n", input.read
46
- end
47
-
48
- def test_fork_interrupt
49
- group = Process::Group.new
50
-
51
- Fiber.new do
52
- result = group.fork do
53
- raise Interrupt
43
+ output.close
44
+
45
+ lines = nil
46
+ io_thread = Thread.new do
47
+ lines = input.read
54
48
  end
55
49
 
56
- refute_equal 0, result.exitstatus
57
- end.resume
58
-
59
- # Shouldn't raise any errors:
60
- group.wait
50
+ group.wait
51
+
52
+ io_thread.join
53
+ expect(lines).to be == ("Hello World\n" * 3)
54
+ end
61
55
  end
62
56
  end
@@ -0,0 +1,109 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'process/group'
22
+
23
+ module Process::Group::SpawnSpec
24
+ describe Process::Group do
25
+ it "should execute fibers concurrently" do
26
+ group = Process::Group.new
27
+
28
+ start_time = Time.now
29
+
30
+ Fiber.new do
31
+ result = group.fork { sleep 1.0 }
32
+
33
+ expect(result).to be == 0
34
+ end.resume
35
+
36
+ Fiber.new do
37
+ result = group.fork { sleep 2.0 }
38
+
39
+ expect(result).to be == 0
40
+ end.resume
41
+
42
+ group.wait
43
+
44
+ end_time = Time.now
45
+
46
+ # Check that the execution time was roughly 2 seconds:
47
+ expect(end_time - start_time).to be_within(0.1).of(2.0)
48
+ end
49
+
50
+ it "should kill commands" do
51
+ group = Process::Group.new
52
+
53
+ start_time = Time.now
54
+
55
+ group.run("sleep 1") do |exit_status|
56
+ expect(exit_status).to_not be 0
57
+ end
58
+
59
+ group.run("sleep 2") do |exit_status|
60
+ expect(exit_status).to_not be 0
61
+ end
62
+
63
+ group.kill(:KILL)
64
+
65
+ group.wait
66
+
67
+ end_time = Time.now
68
+
69
+ # Check that processes killed almost immediately:
70
+ expect(end_time - start_time).to be < 0.2
71
+ end
72
+
73
+ it "should pass environment to child process" do
74
+ group = Process::Group.new
75
+
76
+ env = {'FOO' => 'BAR'}
77
+
78
+ # Make a pipe to receive output from child process:
79
+ input, output = IO.pipe
80
+
81
+ group.run(env, "echo $FOO", out: output) do |exit_status|
82
+ output.close
83
+ end
84
+
85
+ group.wait
86
+
87
+ expect(input.read).to be == "BAR\n"
88
+ end
89
+
90
+ it "should yield exit status" do
91
+ group = Process::Group.new
92
+
93
+ start_time = Time.now
94
+
95
+ group.run("sleep 1")
96
+
97
+ group.run("sleep 1") do |exit_status|
98
+ expect(exit_status).to be == 0
99
+ end
100
+
101
+ group.wait
102
+
103
+ end_time = Time.now
104
+
105
+ # Check that the execution time was roughly 1 second:
106
+ expect(end_time - start_time).to be_within(0.1).of(1.0)
107
+ end
108
+ end
109
+ end
metadata CHANGED
@@ -1,81 +1,58 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: process-group
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
5
- prerelease:
4
+ version: 0.2.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Samuel Williams
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-05-18 00:00:00.000000000 Z
11
+ date: 2014-06-04 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: bundler
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
19
  version: '1.3'
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
26
  version: '1.3'
30
27
  - !ruby/object:Gem::Dependency
31
- name: rake
28
+ name: rspec
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - "~>"
36
32
  - !ruby/object:Gem::Version
37
- version: '0'
33
+ version: 3.0.0.rc1
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
- version: '0'
40
+ version: 3.0.0.rc1
46
41
  - !ruby/object:Gem::Dependency
47
- name: betatest
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ! '>='
52
- - !ruby/object:Gem::Version
53
- version: '0'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ! '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- - !ruby/object:Gem::Dependency
63
- name: mocha
42
+ name: rake
64
43
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
44
  requirements:
67
- - - ! '>='
45
+ - - ">="
68
46
  - !ruby/object:Gem::Version
69
47
  version: '0'
70
48
  type: :development
71
49
  prerelease: false
72
50
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
51
  requirements:
75
- - - ! '>='
52
+ - - ">="
76
53
  - !ruby/object:Gem::Version
77
54
  version: '0'
78
- description: ! "\tManages a unix process group for running multiple processes, keeps
55
+ description: "\tManages a unix process group for running multiple processes, keeps
79
56
  track of multiple processes and leverages fibers to provide predictable behaviour
80
57
  in complicated process-based scripts.\n"
81
58
  email:
@@ -84,43 +61,45 @@ executables: []
84
61
  extensions: []
85
62
  extra_rdoc_files: []
86
63
  files:
87
- - .gitignore
88
- - .travis.yml
64
+ - ".gitignore"
65
+ - ".travis.yml"
89
66
  - Gemfile
90
67
  - README.md
91
68
  - Rakefile
69
+ - examples/terminal.rb
92
70
  - lib/process/group.rb
93
71
  - lib/process/group/version.rb
94
72
  - process-group.gemspec
95
- - test/test_fork.rb
96
- - test/test_interrupt.rb
97
- - test/test_spawn.rb
73
+ - spec/process/group/fork_spec.rb
74
+ - spec/process/group/interrupt_spec.rb
75
+ - spec/process/group/io_spec.rb
76
+ - spec/process/group/spawn_spec.rb
98
77
  homepage: ''
99
78
  licenses:
100
79
  - MIT
80
+ metadata: {}
101
81
  post_install_message:
102
82
  rdoc_options: []
103
83
  require_paths:
104
84
  - lib
105
85
  required_ruby_version: !ruby/object:Gem::Requirement
106
- none: false
107
86
  requirements:
108
- - - ! '>='
87
+ - - ">="
109
88
  - !ruby/object:Gem::Version
110
89
  version: '0'
111
90
  required_rubygems_version: !ruby/object:Gem::Requirement
112
- none: false
113
91
  requirements:
114
- - - ! '>='
92
+ - - ">="
115
93
  - !ruby/object:Gem::Version
116
94
  version: '0'
117
95
  requirements: []
118
96
  rubyforge_project:
119
- rubygems_version: 1.8.23
97
+ rubygems_version: 2.2.2
120
98
  signing_key:
121
- specification_version: 3
99
+ specification_version: 4
122
100
  summary: Run processes concurrently in separate fibers with predictable behaviour.
123
101
  test_files:
124
- - test/test_fork.rb
125
- - test/test_interrupt.rb
126
- - test/test_spawn.rb
102
+ - spec/process/group/fork_spec.rb
103
+ - spec/process/group/interrupt_spec.rb
104
+ - spec/process/group/io_spec.rb
105
+ - spec/process/group/spawn_spec.rb
@@ -1,151 +0,0 @@
1
- # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
20
-
21
- require 'betatest/autorun'
22
-
23
- require 'process/group'
24
-
25
- class TestInterrupt < Betatest::Test
26
- def test_raise_interrupt
27
- group = Process::Group.new
28
- checkpoint = ""
29
-
30
- Fiber.new do
31
- checkpoint += 'X'
32
-
33
- result = group.fork { sleep 0.1 }
34
-
35
- assert_equal 0, result
36
-
37
- checkpoint += 'Y'
38
-
39
- # Simulate the user pressing Ctrl-C after 0.5 seconds:
40
- raise Interrupt
41
- end.resume
42
-
43
- Fiber.new do
44
- checkpoint += 'A'
45
-
46
- # This never returns:
47
- result = group.fork { sleep 0.2 }
48
-
49
- checkpoint += 'B'
50
- end.resume
51
-
52
- #group.expects(:kill).with(:INT).once
53
- #group.expects(:kill).with(:TERM).once
54
-
55
- assert_raises Interrupt do
56
- group.wait
57
- end
58
-
59
- assert_equal 'XAY', checkpoint
60
- end
61
-
62
- def test_raise_exception
63
- group = Process::Group.new
64
- checkpoint = ""
65
-
66
- Fiber.new do
67
- checkpoint += 'X'
68
-
69
- result = group.fork { sleep 0.1 }
70
- assert_equal 0, result
71
-
72
- checkpoint += 'Y'
73
-
74
- # Raises a RuntimeError
75
- fail "Error"
76
- end.resume
77
-
78
- Fiber.new do
79
- checkpoint += 'A'
80
-
81
- # This never returns:
82
- result = group.fork { sleep 0.2 }
83
-
84
- checkpoint += 'B'
85
- end.resume
86
-
87
- assert_raises RuntimeError do
88
- #group.expects(:kill).with(:TERM).once
89
-
90
- group.wait
91
- end
92
-
93
- assert_equal 'XAY', checkpoint
94
- end
95
-
96
- class Timeout < StandardError
97
- end
98
-
99
- def test_timeout
100
- group = Process::Group.new
101
- checkpoint = ""
102
-
103
- Fiber.new do
104
- # Wait for 2 seconds, let other processes run:
105
- group.fork { sleep 2 }
106
- checkpoint += 'A'
107
- #puts "Finished waiting #1..."
108
-
109
- # If no other processes are running, we are done:
110
- Fiber.yield unless group.running?
111
- checkpoint += 'B'
112
- #puts "Sending SIGINT..."
113
-
114
- # Send SIGINT to currently running processes:
115
- group.kill(:INT)
116
-
117
- # Wait for 2 seconds, let other processes run:
118
- group.fork { sleep 2 }
119
- checkpoint += 'C'
120
- #puts "Finished waiting #2..."
121
-
122
- # If no other processes are running, we are done:
123
- Fiber.yield unless group.running?
124
- checkpoint += 'D'
125
- #puts "Sending SIGTERM..."
126
-
127
- # Send SIGTERM to currently running processes:
128
- group.kill(:TERM)
129
-
130
- # Raise an Timeout exception which is based back out:
131
- raise Timeout
132
- end.resume
133
-
134
- # Run some other long task:
135
- group.run("sleep 10")
136
-
137
- start_time = Time.now
138
-
139
- # Wait for fiber to complete:
140
- #assert_nothing_raised Timeout do
141
- group.wait
142
- checkpoint += 'E'
143
- #end
144
-
145
- end_time = Time.now
146
-
147
- assert_equal 'ABCE', checkpoint
148
-
149
- assert (3.8..4.2).include?(end_time - start_time), "Process took approximately 4 seconds: #{end_time - start_time}"
150
- end
151
- end
@@ -1,108 +0,0 @@
1
- # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
20
-
21
- require 'betatest/autorun'
22
-
23
- require 'process/group'
24
-
25
- class TestSpawn < Betatest::Test
26
- def test_fibers
27
- group = Process::Group.new
28
-
29
- start_time = Time.now
30
-
31
- Fiber.new do
32
- result = group.fork { sleep 1.0 }
33
-
34
- assert_equal 0, result
35
- end.resume
36
-
37
- Fiber.new do
38
- result = group.fork { sleep 2.0 }
39
-
40
- assert_equal 0, result
41
- end.resume
42
-
43
- group.wait
44
-
45
- end_time = Time.now
46
-
47
- # Check that the execution time was roughly 2 seconds:
48
- assert (1.9..2.1).include?(end_time - start_time)
49
- end
50
-
51
- def test_kill_commands
52
- group = Process::Group.new
53
-
54
- start_time = Time.now
55
-
56
- group.run("sleep 1") do |exit_status|
57
- refute_equal 0, exit_status
58
- end
59
-
60
- group.run("sleep 2") do |exit_status|
61
- refute_equal 0, exit_status
62
- end
63
-
64
- group.kill(:KILL)
65
-
66
- group.wait
67
-
68
- end_time = Time.now
69
-
70
- # Check that processes killed almost immediately:
71
- assert (end_time - start_time) < 0.2, "Process exited quickly #{end_time - start_time}"
72
- end
73
-
74
- def test_environment_options
75
- group = Process::Group.new
76
-
77
- env = {'FOO' => 'BAR'}
78
-
79
- # Make a pipe to receive output from child process:
80
- input, output = IO.pipe
81
-
82
- group.run(env, "echo $FOO", out: output) do |exit_status|
83
- output.close
84
- end
85
-
86
- group.wait
87
-
88
- assert_equal "BAR\n", input.read
89
- end
90
-
91
- def test_yield
92
- group = Process::Group.new
93
-
94
- start_time = Time.now
95
-
96
- group.run("sleep 1")
97
-
98
- group.run("sleep 1") do |exit_status|
99
- end
100
-
101
- group.wait
102
-
103
- end_time = Time.now
104
-
105
- # Check that the execution time was roughly 1 second:
106
- assert (0.9..1.1).include?(end_time - start_time)
107
- end
108
- end