costan-zerg_support 0.0.9

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,78 @@
1
+ require 'English'
2
+ require 'test/unit'
3
+
4
+ require 'zerg_support'
5
+
6
+ class TestProcess < Test::Unit::TestCase
7
+ def teardown
8
+ @pid_files.each { |f| File.delete f rescue nil } if @pid_files
9
+ super
10
+ end
11
+
12
+ def test_process_info
13
+ info = Zerg::Support::Process.process_info($PID)
14
+ assert info, 'Failed to find current process'
15
+
16
+ $ARGV.each do |arg|
17
+ assert info[:command_line].index(arg),
18
+ "Command line for current process does not contain argument #{arg}"
19
+ end
20
+ end
21
+
22
+ def test_process_list_contains_current_process
23
+ list = Zerg::Support::Process.processes_by_id
24
+
25
+ assert list[$PID], 'Process list does not contain current process'
26
+ end
27
+
28
+ # spawn 2^(exp+1)-1 children, and their command lines will contain "cookie"
29
+ def spawn_sleepers(exp, cookie)
30
+ Thread.new { system "ruby test/fork_tree.rb -- #{exp} 100 #{cookie}" }
31
+ on_windows = RUBY_PLATFORM =~ /win/ && RUBY_PLATFORM !~ /darwin/
32
+ sleep on_windows ? 0.5 : 0.1
33
+ pid_file = "#{cookie}.pid"
34
+ @pid_files ||= []
35
+ @pid_files << pid_file
36
+ pid = File.read(pid_file).to_i
37
+ sleep on_windows ? 0.4 : 0.5
38
+ return pid
39
+ end
40
+
41
+ def now_cookie
42
+ "zerg_test_#{Time.now.to_f}s"
43
+ end
44
+
45
+ def test_process_tree
46
+ cookie = now_cookie
47
+ root_pid = spawn_sleepers 3, cookie
48
+
49
+ tree_processes = Zerg::Support::Process.process_tree root_pid
50
+ assert_equal 15, tree_processes.length, 'Missed some processes'
51
+ assert tree_processes.all? { |info| info[:command_line].index cookie },
52
+ 'Got the wrong processes'
53
+
54
+ Zerg::Support::Process.kill_tree root_pid
55
+ end
56
+
57
+ def test_kill
58
+ cookie = now_cookie
59
+ victim_pid = spawn_sleepers 0, cookie
60
+
61
+ Zerg::Support::Process.kill victim_pid
62
+ sleep 0.5
63
+ processes = Zerg::Support::Process.processes
64
+ assert_equal nil, processes[victim_pid], 'Victim was not killed'
65
+ end
66
+
67
+ def test_kill_tree
68
+ cookie = now_cookie
69
+ root_pid = spawn_sleepers 3, cookie
70
+
71
+ Zerg::Support::Process.kill_tree root_pid
72
+ sleep 0.5
73
+ processes = Zerg::Support::Process.processes
74
+ escaped = processes.select { |info| info[:command_line].index cookie }
75
+
76
+ assert_equal [], escaped, 'Some process(es) escaped'
77
+ end
78
+ end
@@ -0,0 +1,163 @@
1
+ require 'digest/sha1'
2
+ require 'test/unit'
3
+
4
+ require 'zerg_support'
5
+
6
+ require 'rubygems'
7
+ require 'flexmock/test_unit'
8
+
9
+ class TestSpawn < Test::Unit::TestCase
10
+ def temp_file
11
+ now_cookie = "zerg_test_#{Time.now.to_f}s"
12
+ File.open(now_cookie, 'w') {}
13
+ return now_cookie
14
+ end
15
+
16
+ def setup
17
+ super
18
+ @in_file = temp_file
19
+ @out_file = temp_file
20
+ end
21
+
22
+ def teardown
23
+ File.delete @in_file rescue nil
24
+ File.delete @out_file rescue nil
25
+ super
26
+ end
27
+
28
+ def test_stdout_redirect
29
+ pid = Zerg::Support::Process.spawn 'ruby', ['-e', 'print "1234\n"'],
30
+ STDOUT => @out_file
31
+ Process.waitpid pid
32
+
33
+ assert_equal "1234\n", File.read(@out_file)
34
+ end
35
+
36
+ def test_stdin_redirect
37
+ File.open(@in_file, 'w') { |f| f.write "1234\n" }
38
+
39
+ pid = Zerg::Support::Process.spawn 'ruby', ['-e', "print gets"],
40
+ STDIN => @in_file, STDOUT => @out_file
41
+ Process.waitpid pid
42
+ assert_equal "1234\n", File.read(@out_file)
43
+ end
44
+
45
+ def test_stderr_redirect
46
+ pid = Zerg::Support::Process.spawn 'ruby', ['-e', "raise 'zerg_stderr'"],
47
+ STDERR => @out_file
48
+ Process.waitpid pid
49
+ assert_equal "-e:1: zerg_stderr (RuntimeError)\n", File.read(@out_file)
50
+ end
51
+
52
+ def test_redirect_cascade
53
+ pid = Zerg::Support::Process.spawn 'ruby',
54
+ ['-e', "print 1; raise 'zerg_stderr'"],
55
+ STDOUT => @out_file, STDERR => STDOUT
56
+ Process.waitpid pid
57
+ assert_operator ["1-e:1: zerg_stderr (RuntimeError)\n",
58
+ "-e:1: zerg_stderr (RuntimeError)\n1"],
59
+ :include?, File.read(@out_file)
60
+ end
61
+
62
+ def test_redirect_share
63
+ pid = Zerg::Support::Process.spawn 'ruby',
64
+ ['-e', "print 1; raise 'zerg_stderr'"],
65
+ STDOUT => @out_file, STDERR => @out_file
66
+ Process.waitpid pid
67
+ assert_operator ["1-e:1: zerg_stderr (RuntimeError)\n",
68
+ "-e:1: zerg_stderr (RuntimeError)\n1"],
69
+ :include?, File.read(@out_file)
70
+ end
71
+
72
+ def test_async
73
+ t0 = Time.now
74
+ pid = Zerg::Support::Process.spawn 'ruby', ['-e', 'sleep 0.5']
75
+ t1 = Time.now
76
+ Process.waitpid pid
77
+ t2 = Time.now
78
+
79
+ assert_operator t1 - t0, :<, 0.2, 'Spawning is not asynchronous'
80
+ assert_operator t2 - t0, :>, 0.5,
81
+ 'The spawned program did not sleep for 1 second'
82
+ end
83
+
84
+ def test_set_environment
85
+ pid = Zerg::Support::Process.spawn 'ruby', ['-e', 'print ENV[\'XA\']'],
86
+ STDOUT => @out_file, :env => {'XA' => "1234\n"}
87
+ Process.waitpid pid
88
+ assert_equal "1234\n", File.read(@out_file)
89
+
90
+ pid = Zerg::Support::Process.spawn 'ruby', ['-e', 'print ENV[\'PATH\']'],
91
+ STDOUT => @in_file, :env => {'XA' => "1234\n"}, :unsetenv_others => true
92
+ Process.waitpid pid
93
+ # clearing the environment will reset PATH, so ruby might not run at all
94
+ output = File.read(@in_file)
95
+ assert output == 'nil' || output == '', 'The environment was not cleared'
96
+ end
97
+
98
+ def test_close_fd
99
+ in_file = File.open(@in_file, 'w')
100
+ in_file.sync = true
101
+ in_file.write "1234\n"
102
+ in_file.close
103
+
104
+ in_file = File.open(@in_file, 'r')
105
+
106
+ in_fd = in_file.fileno
107
+ read_fd_code = "File.open(#{in_fd}).read"
108
+ assert_equal "1234\n", eval(read_fd_code), 'File reading code is broken'
109
+
110
+ pid = Zerg::Support::Process.spawn 'ruby', ['-e', "print #{read_fd_code}"],
111
+ STDOUT => @out_file, STDERR => STDOUT
112
+ Process.waitpid pid
113
+ in_file.close
114
+
115
+ assert_equal "-e:1:", File.read(@out_file)[0, 5],
116
+ 'Spawn does not close file descriptors'
117
+ end
118
+
119
+ def test_rlimit_processing
120
+ if RUBY_PLATFORM =~ /win/ and RUBY_PLATFORM !~ /darwin/
121
+ Process.const_set :RLIMIT_CPU, 'rlimit_cpu'
122
+ Process.const_set :RLIMIT_RSS, 'rlimit_rss'
123
+ end
124
+
125
+ flexmock(Process).should_receive(:setrlimit).
126
+ with(Process::RLIMIT_CPU, 1, 5).once.and_return(nil)
127
+ flexmock(Process).should_receive(:setrlimit).
128
+ with(Process::RLIMIT_RSS, 64 * 1024 * 1024).once.
129
+ and_return(nil)
130
+
131
+ Zerg::Support::Process::Helpers.set_rlimits :rlimit_cpu => [1, 5],
132
+ :rlimit_rss => 64 * 1024 * 1024
133
+ end
134
+
135
+ def test_process_group_processing
136
+ flexmock(Process).should_receive(:setpgid).with(0, 42).once.and_return(nil)
137
+ flexmock(Process).should_receive(:setsid).with().once.and_return(nil)
138
+
139
+ Zerg::Support::Process::Helpers.set_process_group :pgroup => 42
140
+ Zerg::Support::Process::Helpers.set_process_group :pgroup => true
141
+ end
142
+
143
+ def test_process_group
144
+ pid = Zerg::Support::Process.spawn 'ruby', ['-e', "sleep 0.5"],
145
+ :pgroup => true
146
+ pinfo = Zerg::Support::Process::process_info pid
147
+ Process.waitpid pid
148
+
149
+ assert pinfo[:state].index('s'), 'Failed to become session leader'
150
+ end
151
+
152
+ def test_rlimits
153
+ t0 = Time.now
154
+ pid = Zerg::Support::Process.spawn 'ruby',
155
+ ['-e', "i = 0; t0 = Time.now; i += 1 while Time.now - t0 < 3.0"],
156
+ :rlimit_cpu => 1
157
+ Process.waitpid pid
158
+ t1 = Time.now
159
+
160
+ assert_operator t1 - t0, :>=, 0.95, 'Spawning failed'
161
+ assert_operator t1 - t0, :<=, 2.0, 'Failed to apply rlimit_cpu'
162
+ end
163
+ end
@@ -0,0 +1,41 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{zerg_support}
5
+ s.version = "0.0.9"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Victor Costan"]
9
+ s.date = %q{2009-03-28}
10
+ s.description = %q{Support libraries used by Zergling.Net deployment code.}
11
+ s.email = %q{victor@zergling.net}
12
+ s.extra_rdoc_files = ["CHANGELOG", "lib/zerg_support/event_machine/connection_mocks.rb", "lib/zerg_support/event_machine/frame_protocol.rb", "lib/zerg_support/event_machine/object_protocol.rb", "lib/zerg_support/gems.rb", "lib/zerg_support/open_ssh.rb", "lib/zerg_support/process.rb", "lib/zerg_support/spawn.rb", "lib/zerg_support.rb", "LICENSE", "README"]
13
+ s.files = ["CHANGELOG", "lib/zerg_support/event_machine/connection_mocks.rb", "lib/zerg_support/event_machine/frame_protocol.rb", "lib/zerg_support/event_machine/object_protocol.rb", "lib/zerg_support/gems.rb", "lib/zerg_support/open_ssh.rb", "lib/zerg_support/process.rb", "lib/zerg_support/spawn.rb", "lib/zerg_support.rb", "LICENSE", "Manifest", "Rakefile", "README", "RUBYFORGE", "test/fork_tree.rb", "test/test_connection_mocks.rb", "test/test_frame_protocol.rb", "test/test_gems.rb", "test/test_object_protocol.rb", "test/test_open_ssh.rb", "test/test_process.rb", "test/test_spawn.rb", "zerg_support.gemspec"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://www.zergling.net}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Zerg_support", "--main", "README"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{zerglings}
19
+ s.rubygems_version = %q{1.3.1}
20
+ s.summary = %q{Support libraries used by Zergling.Net deployment code.}
21
+ s.test_files = ["test/test_connection_mocks.rb", "test/test_frame_protocol.rb", "test/test_gems.rb", "test/test_object_protocol.rb", "test/test_open_ssh.rb", "test/test_process.rb", "test/test_spawn.rb"]
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 2
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ s.add_development_dependency(%q<echoe>, [">= 3.0.2"])
29
+ s.add_development_dependency(%q<event_machine>, [">= 0.12.2"])
30
+ s.add_development_dependency(%q<flexmock>, [">= 0.8.3"])
31
+ else
32
+ s.add_dependency(%q<echoe>, [">= 3.0.2"])
33
+ s.add_dependency(%q<event_machine>, [">= 0.12.2"])
34
+ s.add_dependency(%q<flexmock>, [">= 0.8.3"])
35
+ end
36
+ else
37
+ s.add_dependency(%q<echoe>, [">= 3.0.2"])
38
+ s.add_dependency(%q<event_machine>, [">= 0.12.2"])
39
+ s.add_dependency(%q<flexmock>, [">= 0.8.3"])
40
+ end
41
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: costan-zerg_support
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.9
5
+ platform: ruby
6
+ authors:
7
+ - Victor Costan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-28 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: echoe
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 3.0.2
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: event_machine
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.12.2
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: flexmock
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.8.3
44
+ version:
45
+ description: Support libraries used by Zergling.Net deployment code.
46
+ email: victor@zergling.net
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - CHANGELOG
53
+ - lib/zerg_support/event_machine/connection_mocks.rb
54
+ - lib/zerg_support/event_machine/frame_protocol.rb
55
+ - lib/zerg_support/event_machine/object_protocol.rb
56
+ - lib/zerg_support/gems.rb
57
+ - lib/zerg_support/open_ssh.rb
58
+ - lib/zerg_support/process.rb
59
+ - lib/zerg_support/spawn.rb
60
+ - lib/zerg_support.rb
61
+ - LICENSE
62
+ - README
63
+ files:
64
+ - CHANGELOG
65
+ - lib/zerg_support/event_machine/connection_mocks.rb
66
+ - lib/zerg_support/event_machine/frame_protocol.rb
67
+ - lib/zerg_support/event_machine/object_protocol.rb
68
+ - lib/zerg_support/gems.rb
69
+ - lib/zerg_support/open_ssh.rb
70
+ - lib/zerg_support/process.rb
71
+ - lib/zerg_support/spawn.rb
72
+ - lib/zerg_support.rb
73
+ - LICENSE
74
+ - Manifest
75
+ - Rakefile
76
+ - README
77
+ - RUBYFORGE
78
+ - test/fork_tree.rb
79
+ - test/test_connection_mocks.rb
80
+ - test/test_frame_protocol.rb
81
+ - test/test_gems.rb
82
+ - test/test_object_protocol.rb
83
+ - test/test_open_ssh.rb
84
+ - test/test_process.rb
85
+ - test/test_spawn.rb
86
+ - zerg_support.gemspec
87
+ has_rdoc: true
88
+ homepage: http://www.zergling.net
89
+ post_install_message:
90
+ rdoc_options:
91
+ - --line-numbers
92
+ - --inline-source
93
+ - --title
94
+ - Zerg_support
95
+ - --main
96
+ - README
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: "0"
104
+ version:
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: "1.2"
110
+ version:
111
+ requirements: []
112
+
113
+ rubyforge_project: zerglings
114
+ rubygems_version: 1.2.0
115
+ signing_key:
116
+ specification_version: 2
117
+ summary: Support libraries used by Zergling.Net deployment code.
118
+ test_files:
119
+ - test/test_connection_mocks.rb
120
+ - test/test_frame_protocol.rb
121
+ - test/test_gems.rb
122
+ - test/test_object_protocol.rb
123
+ - test/test_open_ssh.rb
124
+ - test/test_process.rb
125
+ - test/test_spawn.rb