costan-zerg_support 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -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