eye 0.1.11

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.
Files changed (190) hide show
  1. data/.gitignore +31 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +22 -0
  5. data/README.md +132 -0
  6. data/Rakefile +18 -0
  7. data/bin/eye +282 -0
  8. data/bin/loader_eye +56 -0
  9. data/examples/processes/em.rb +56 -0
  10. data/examples/processes/forking.rb +20 -0
  11. data/examples/processes/sample.rb +144 -0
  12. data/examples/rbenv.eye +11 -0
  13. data/examples/test.eye +65 -0
  14. data/examples/unicorn.eye +29 -0
  15. data/eye.gemspec +37 -0
  16. data/lib/eye.rb +25 -0
  17. data/lib/eye/application.rb +65 -0
  18. data/lib/eye/checker.rb +118 -0
  19. data/lib/eye/checker/cpu.rb +27 -0
  20. data/lib/eye/checker/file_ctime.rb +29 -0
  21. data/lib/eye/checker/file_size.rb +38 -0
  22. data/lib/eye/checker/http.rb +94 -0
  23. data/lib/eye/checker/memory.rb +27 -0
  24. data/lib/eye/checker/socket.rb +148 -0
  25. data/lib/eye/checker/validation.rb +49 -0
  26. data/lib/eye/child_process.rb +75 -0
  27. data/lib/eye/client.rb +32 -0
  28. data/lib/eye/control.rb +2 -0
  29. data/lib/eye/controller.rb +43 -0
  30. data/lib/eye/controller/commands.rb +64 -0
  31. data/lib/eye/controller/helpers.rb +61 -0
  32. data/lib/eye/controller/load.rb +224 -0
  33. data/lib/eye/controller/send_command.rb +88 -0
  34. data/lib/eye/controller/status.rb +136 -0
  35. data/lib/eye/dsl.rb +52 -0
  36. data/lib/eye/dsl/application_opts.rb +33 -0
  37. data/lib/eye/dsl/chain.rb +12 -0
  38. data/lib/eye/dsl/child_process_opts.rb +7 -0
  39. data/lib/eye/dsl/config_opts.rb +11 -0
  40. data/lib/eye/dsl/group_opts.rb +27 -0
  41. data/lib/eye/dsl/helpers.rb +12 -0
  42. data/lib/eye/dsl/main.rb +58 -0
  43. data/lib/eye/dsl/opts.rb +88 -0
  44. data/lib/eye/dsl/process_opts.rb +21 -0
  45. data/lib/eye/dsl/pure_opts.rb +132 -0
  46. data/lib/eye/dsl/validate.rb +41 -0
  47. data/lib/eye/group.rb +125 -0
  48. data/lib/eye/group/chain.rb +68 -0
  49. data/lib/eye/io/unix_server.rb +44 -0
  50. data/lib/eye/io/unix_socket.rb +39 -0
  51. data/lib/eye/loader.rb +13 -0
  52. data/lib/eye/logger.rb +80 -0
  53. data/lib/eye/process.rb +83 -0
  54. data/lib/eye/process/child.rb +61 -0
  55. data/lib/eye/process/commands.rb +256 -0
  56. data/lib/eye/process/config.rb +70 -0
  57. data/lib/eye/process/controller.rb +72 -0
  58. data/lib/eye/process/data.rb +46 -0
  59. data/lib/eye/process/monitor.rb +97 -0
  60. data/lib/eye/process/notify.rb +17 -0
  61. data/lib/eye/process/scheduler.rb +50 -0
  62. data/lib/eye/process/states.rb +92 -0
  63. data/lib/eye/process/states_history.rb +62 -0
  64. data/lib/eye/process/system.rb +60 -0
  65. data/lib/eye/process/trigger.rb +32 -0
  66. data/lib/eye/process/watchers.rb +67 -0
  67. data/lib/eye/server.rb +51 -0
  68. data/lib/eye/settings.rb +35 -0
  69. data/lib/eye/system.rb +145 -0
  70. data/lib/eye/system_resources.rb +83 -0
  71. data/lib/eye/trigger.rb +53 -0
  72. data/lib/eye/trigger/flapping.rb +24 -0
  73. data/lib/eye/utils.rb +5 -0
  74. data/lib/eye/utils/alive_array.rb +31 -0
  75. data/lib/eye/utils/celluloid_chain.rb +51 -0
  76. data/lib/eye/utils/leak_19.rb +7 -0
  77. data/lib/eye/utils/tail.rb +20 -0
  78. data/spec/checker/cpu_spec.rb +58 -0
  79. data/spec/checker/file_ctime_spec.rb +34 -0
  80. data/spec/checker/file_size_spec.rb +107 -0
  81. data/spec/checker/http_spec.rb +109 -0
  82. data/spec/checker/memory_spec.rb +64 -0
  83. data/spec/checker/socket_spec.rb +116 -0
  84. data/spec/checker_spec.rb +188 -0
  85. data/spec/child_process/child_process_spec.rb +46 -0
  86. data/spec/client_server_spec.rb +34 -0
  87. data/spec/controller/commands_spec.rb +92 -0
  88. data/spec/controller/controller_spec.rb +133 -0
  89. data/spec/controller/find_objects_spec.rb +150 -0
  90. data/spec/controller/group_spec.rb +110 -0
  91. data/spec/controller/intergration_spec.rb +327 -0
  92. data/spec/controller/load_spec.rb +326 -0
  93. data/spec/controller/races_spec.rb +70 -0
  94. data/spec/controller/stop_on_delete_spec.rb +157 -0
  95. data/spec/dsl/chain_spec.rb +140 -0
  96. data/spec/dsl/checks_spec.rb +202 -0
  97. data/spec/dsl/config_spec.rb +44 -0
  98. data/spec/dsl/dsl_spec.rb +73 -0
  99. data/spec/dsl/getter_spec.rb +223 -0
  100. data/spec/dsl/integration_spec.rb +311 -0
  101. data/spec/dsl/load_spec.rb +52 -0
  102. data/spec/dsl/process_spec.rb +330 -0
  103. data/spec/dsl/sub_procs_spec.rb +93 -0
  104. data/spec/dsl/with_server_spec.rb +104 -0
  105. data/spec/example/em.rb +57 -0
  106. data/spec/example/forking.rb +20 -0
  107. data/spec/example/sample.rb +154 -0
  108. data/spec/fixtures/dsl/0.rb +8 -0
  109. data/spec/fixtures/dsl/0a.rb +8 -0
  110. data/spec/fixtures/dsl/0c.rb +8 -0
  111. data/spec/fixtures/dsl/1.rb +5 -0
  112. data/spec/fixtures/dsl/bad.eye +6 -0
  113. data/spec/fixtures/dsl/configs/1.eye +3 -0
  114. data/spec/fixtures/dsl/configs/2.eye +1 -0
  115. data/spec/fixtures/dsl/configs/3.eye +1 -0
  116. data/spec/fixtures/dsl/configs/4.eye +3 -0
  117. data/spec/fixtures/dsl/empty.eye +20 -0
  118. data/spec/fixtures/dsl/include_test.eye +5 -0
  119. data/spec/fixtures/dsl/include_test/1.rb +6 -0
  120. data/spec/fixtures/dsl/include_test/ha.rb +4 -0
  121. data/spec/fixtures/dsl/include_test2.eye +5 -0
  122. data/spec/fixtures/dsl/integration.eye +30 -0
  123. data/spec/fixtures/dsl/integration2.eye +32 -0
  124. data/spec/fixtures/dsl/integration_locks.eye +30 -0
  125. data/spec/fixtures/dsl/integration_sor.eye +32 -0
  126. data/spec/fixtures/dsl/integration_sor2.eye +27 -0
  127. data/spec/fixtures/dsl/integration_sor3.eye +32 -0
  128. data/spec/fixtures/dsl/load.eye +25 -0
  129. data/spec/fixtures/dsl/load2.eye +7 -0
  130. data/spec/fixtures/dsl/load2_dup2.eye +13 -0
  131. data/spec/fixtures/dsl/load2_dup_pid.eye +7 -0
  132. data/spec/fixtures/dsl/load3.eye +10 -0
  133. data/spec/fixtures/dsl/load4.eye +7 -0
  134. data/spec/fixtures/dsl/load5.eye +8 -0
  135. data/spec/fixtures/dsl/load6.eye +17 -0
  136. data/spec/fixtures/dsl/load_dubls.eye +36 -0
  137. data/spec/fixtures/dsl/load_dup_ex_names.eye +15 -0
  138. data/spec/fixtures/dsl/load_error.eye +5 -0
  139. data/spec/fixtures/dsl/load_error_folder/load3.eye +10 -0
  140. data/spec/fixtures/dsl/load_error_folder/load4.eye +7 -0
  141. data/spec/fixtures/dsl/load_folder/load3.eye +10 -0
  142. data/spec/fixtures/dsl/load_folder/load4.eye +7 -0
  143. data/spec/fixtures/dsl/load_int.eye +8 -0
  144. data/spec/fixtures/dsl/load_int2.eye +13 -0
  145. data/spec/fixtures/dsl/load_logger.eye +26 -0
  146. data/spec/fixtures/dsl/load_logger2.eye +3 -0
  147. data/spec/fixtures/dsl/long_load.eye +5 -0
  148. data/spec/fixtures/dsl/subfolder1/proc1.rb +3 -0
  149. data/spec/fixtures/dsl/subfolder2.eye +9 -0
  150. data/spec/fixtures/dsl/subfolder2/common.rb +1 -0
  151. data/spec/fixtures/dsl/subfolder2/proc2.rb +3 -0
  152. data/spec/fixtures/dsl/subfolder2/sub/proc3.rb +6 -0
  153. data/spec/fixtures/dsl/subfolder3.eye +8 -0
  154. data/spec/fixtures/dsl/subfolder3/common.rb +1 -0
  155. data/spec/fixtures/dsl/subfolder3/proc4.rb +3 -0
  156. data/spec/fixtures/dsl/subfolder3/sub/proc5.rb +6 -0
  157. data/spec/fixtures/dsl/subfolder4.eye +6 -0
  158. data/spec/fixtures/dsl/subfolder4/a.rb +2 -0
  159. data/spec/fixtures/dsl/subfolder4/b.rb +1 -0
  160. data/spec/fixtures/dsl/subfolder4/c.rb +1 -0
  161. data/spec/mock_spec.rb +32 -0
  162. data/spec/process/checks/child_checks_spec.rb +79 -0
  163. data/spec/process/checks/cpu_spec.rb +114 -0
  164. data/spec/process/checks/ctime_spec.rb +43 -0
  165. data/spec/process/checks/fsize_spec.rb +22 -0
  166. data/spec/process/checks/http_spec.rb +52 -0
  167. data/spec/process/checks/intergration_spec.rb +32 -0
  168. data/spec/process/checks/memory_spec.rb +113 -0
  169. data/spec/process/child_process_spec.rb +125 -0
  170. data/spec/process/config_spec.rb +75 -0
  171. data/spec/process/controller_spec.rb +173 -0
  172. data/spec/process/monitoring_spec.rb +180 -0
  173. data/spec/process/restart_spec.rb +174 -0
  174. data/spec/process/scheduler_spec.rb +150 -0
  175. data/spec/process/start_spec.rb +261 -0
  176. data/spec/process/states_history_spec.rb +118 -0
  177. data/spec/process/stop_spec.rb +150 -0
  178. data/spec/process/system_spec.rb +100 -0
  179. data/spec/process/triggers/flapping_spec.rb +81 -0
  180. data/spec/process/update_config_spec.rb +63 -0
  181. data/spec/spec_helper.rb +120 -0
  182. data/spec/support/rr_celluloid.rb +36 -0
  183. data/spec/support/scheduler_hack.rb +16 -0
  184. data/spec/support/spec_support.rb +164 -0
  185. data/spec/system_resources_spec.rb +59 -0
  186. data/spec/system_spec.rb +170 -0
  187. data/spec/utils/alive_array_spec.rb +50 -0
  188. data/spec/utils/celluloid_chain_spec.rb +82 -0
  189. data/spec/utils/tail_spec.rb +21 -0
  190. metadata +558 -0
@@ -0,0 +1,180 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "Process Monitoring" do
4
+
5
+ [C.p1, C.p2].each do |cfg|
6
+ it "process crushed, should restart #{cfg[:name]}" do
7
+ start_ok_process(cfg)
8
+ old_pid = @pid
9
+
10
+ die_process!(@pid)
11
+ mock(@process).notify(:warn, anything)
12
+
13
+ sleep 10 # wait until monitor upping process
14
+
15
+ @pid = @process.pid
16
+ @pid.should_not == old_pid
17
+
18
+ Eye::System.pid_alive?(old_pid).should == false
19
+ Eye::System.pid_alive?(@pid).should == true
20
+
21
+ @process.state_name.should == :up
22
+ @process.states_history.seq?(:down, :starting, :up).should == true
23
+ @process.watchers.keys.should == [:check_alive]
24
+ @process.load_pid_from_file.should == @process.pid
25
+ end
26
+
27
+ it "someone remove pid_file. should rewrite" do
28
+ start_ok_process(cfg)
29
+ old_pid = @pid
30
+ File.exists?(cfg[:pid_file]).should == true
31
+
32
+ FileUtils.rm(cfg[:pid_file]) # someone removes it (bad man)
33
+ File.exists?(cfg[:pid_file]).should == false
34
+
35
+ sleep 10 # wait until monitor understand it
36
+
37
+ File.exists?(cfg[:pid_file]).should == true
38
+ @process.pid.should == old_pid
39
+ @process.load_pid_from_file.should == @process.pid
40
+ @process.state_name.should == :up
41
+ end
42
+
43
+ it "someone rewrite pid_file. should rewrite for daemonize only" do
44
+ start_ok_process(cfg)
45
+ old_pid = @pid
46
+ @process.load_pid_from_file.should == @pid
47
+
48
+ File.open(cfg[:pid_file], 'w'){|f| f.write(99999) }
49
+ @process.load_pid_from_file.should == 99999
50
+
51
+ sleep 10 # wait until monitor understand it
52
+
53
+ if cfg[:daemonize]
54
+ @process.load_pid_from_file.should == @pid
55
+ else
56
+ @process.load_pid_from_file.should == 99999
57
+ end
58
+
59
+ @process.pid.should == old_pid
60
+ @process.state_name.should == :up
61
+ end
62
+
63
+ it "someone rewrite pid_file. and ctime > limit, should rewrite for both" do
64
+ start_ok_process(cfg)
65
+ old_pid = @pid
66
+ @process.load_pid_from_file.should == @pid
67
+
68
+ silence_warnings{ Eye::Process::Monitor::REWRITE_FACKUP_PIDFILE_PERIOD = 4.seconds }
69
+
70
+ File.open(cfg[:pid_file], 'w'){|f| f.write(99999) }
71
+ @process.load_pid_from_file.should == 99999
72
+
73
+ sleep 15 # wait until monitor understand it
74
+
75
+ @process.load_pid_from_file.should == @pid
76
+
77
+ @process.pid.should == old_pid
78
+ @process.state_name.should == :up
79
+
80
+ silence_warnings{ Eye::Process::Monitor::REWRITE_FACKUP_PIDFILE_PERIOD = 2.minutes }
81
+ end
82
+
83
+ it "EMULATE UNICORN someone rewrite pid_file and process die (should read actual pid from file)" do
84
+ start_ok_process(cfg)
85
+ old_pid = @pid
86
+
87
+ # rewrite by another :)
88
+ @pid = Eye::System.daemonize("ruby sample.rb", {:environment => {"ENV1" => "SECRET1"},
89
+ :working_dir => cfg[:working_dir], :stdout => @log})[:pid]
90
+
91
+ File.open(cfg[:pid_file], 'w'){|f| f.write(@pid) }
92
+
93
+ die_process!(old_pid)
94
+
95
+ sleep 10 # wait until monitor upping process
96
+
97
+ @process.pid.should == @pid
98
+ old_pid.should_not == @pid
99
+
100
+ Eye::System.pid_alive?(old_pid).should == false
101
+ Eye::System.pid_alive?(@pid).should == true
102
+
103
+ @process.state_name.should == :up
104
+ @process.watchers.keys.should == [:check_alive]
105
+ @process.load_pid_from_file.should == @process.pid
106
+ end
107
+
108
+ end
109
+
110
+ it "EMULATE UNICORN2 hard understanding restart case" do
111
+ start_ok_process(C.p2)
112
+ old_pid = @pid
113
+
114
+ # rewrite by another :)
115
+ @pid = Eye::System.daemonize("ruby sample.rb", {:environment => {"ENV1" => "SECRET1"},
116
+ :working_dir => C.p2[:working_dir], :stdout => @log})[:pid]
117
+
118
+ File.open(C.p2[:pid_file], 'w'){|f| f.write(@pid) }
119
+
120
+ sleep 5
121
+
122
+ # both processes exists now
123
+ # and in pid_file writed second pid
124
+ @process.load_pid_from_file.should == @pid
125
+ @process.pid.should == old_pid
126
+
127
+ die_process!(old_pid)
128
+
129
+ sleep 5 # wait until monitor upping process
130
+
131
+ @process.pid.should == @pid
132
+ old_pid.should_not == @pid
133
+ @process.load_pid_from_file.should == @pid
134
+
135
+ Eye::System.pid_alive?(old_pid).should == false
136
+ Eye::System.pid_alive?(@pid).should == true
137
+
138
+ @process.state_name.should == :up
139
+ @process.watchers.keys.should == [:check_alive]
140
+ @process.load_pid_from_file.should == @process.pid
141
+ end
142
+
143
+ it "if keep_alive disabled, process should not up" do
144
+ start_ok_process(C.p1.merge(:keep_alive => false))
145
+ old_pid = @process.pid
146
+
147
+ die_process!(@pid)
148
+
149
+ sleep 10 # wait until monitor upping process
150
+
151
+ @process.pid.should == nil
152
+ Eye::System.pid_alive?(@pid).should == false
153
+
154
+ @process.state_name.should == :unmonitored
155
+ @process.watchers.keys.should == []
156
+ @process.states_history.end?(:up, :down, :unmonitored).should == true
157
+ @process.load_pid_from_file.should == old_pid # i think this ok
158
+ end
159
+
160
+ it "process in status unmonitored should not up automatically" do
161
+ start_ok_process(C.p1)
162
+ old_pid = @pid
163
+
164
+ @process.unmonitor
165
+ @process.state_name.should == :unmonitored
166
+
167
+ die_process!(@pid)
168
+
169
+ sleep 10 # wait until monitor upping process
170
+
171
+ @process.pid.should == nil
172
+
173
+ Eye::System.pid_alive?(old_pid).should == false
174
+
175
+ @process.state_name.should == :unmonitored
176
+ @process.watchers.keys.should == []
177
+ @process.load_pid_from_file.should == old_pid
178
+ end
179
+
180
+ end
@@ -0,0 +1,174 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "Process Restart" do
4
+ [C.p1, C.p2].each do |cfg|
5
+ it "restart by default command #{cfg[:name]}" do
6
+ start_ok_process(cfg)
7
+ old_pid = @pid
8
+
9
+ dont_allow(@process).check_crush
10
+ @process.restart
11
+
12
+ @process.pid.should_not == old_pid
13
+ @process.pid.should > 0
14
+
15
+ Eye::System.pid_alive?(@pid).should == false
16
+ Eye::System.pid_alive?(@process.pid).should == true
17
+
18
+ @process.state_name.should == :up
19
+ @process.states_history.seq?(:up, :restarting, :stopping, :down, :starting, :up).should == true
20
+ @process.watchers.keys.should == [:check_alive]
21
+
22
+ @process.load_pid_from_file.should == @process.pid
23
+ end
24
+
25
+ it "stop_command is #{cfg[:name]}" do
26
+ start_ok_process(cfg.merge(:stop_command => "kill -9 {{PID}}"))
27
+ old_pid = @pid
28
+
29
+ dont_allow(@process).check_crush
30
+ @process.restart
31
+
32
+ @process.pid.should_not == old_pid
33
+ @process.pid.should > 0
34
+
35
+ Eye::System.pid_alive?(@pid).should == false
36
+ Eye::System.pid_alive?(@process.pid).should == true
37
+
38
+ @process.state_name.should == :up
39
+ @process.watchers.keys.should == [:check_alive]
40
+
41
+ @process.load_pid_from_file.should == @process.pid
42
+ end
43
+
44
+ it "emulate restart_command that cant kill (USR1)" do
45
+ # not trully test, but its ok as should send signal (unicorn case)
46
+ start_ok_process(cfg.merge(:restart_command => "kill -USR1 {{PID}}"))
47
+ old_pid = @pid
48
+
49
+ dont_allow(@process).check_crush
50
+ @process.restart
51
+
52
+ sleep 3
53
+ @process.pid.should == old_pid
54
+
55
+ Eye::System.pid_alive?(@pid).should == true
56
+
57
+ @process.state_name.should == :up
58
+ @process.watchers.keys.should == [:check_alive]
59
+
60
+ @process.load_pid_from_file.should == @process.pid
61
+ @process.states_history.end?(:up, :restarting, :up).should == true
62
+
63
+ File.read(@log).should include("USR1")
64
+ end
65
+
66
+ it "emulate restart as stop,start where stop command does not kill" do
67
+ # should send command, than wait grace time,
68
+ # and than even if old process doesnot die, start another one, (looks like bug, but this is not, it just bad using, commands)
69
+
70
+ # same situation, when stop command kills so long time, that process cant stop
71
+ start_ok_process(cfg.merge(:stop_command => "kill -USR1 {{PID}}"))
72
+ old_pid = @pid
73
+
74
+ dont_allow(@process).check_crush
75
+ @process.restart
76
+
77
+ sleep 3
78
+ @process.pid.should_not == old_pid
79
+
80
+ Eye::System.pid_alive?(@pid).should == true
81
+
82
+ @process.state_name.should == :up
83
+ @process.watchers.keys.should == [:check_alive]
84
+
85
+ @process.load_pid_from_file.should == @process.pid
86
+ @process.states_history.end?(:up, :restarting, :stopping, :unmonitored, :starting, :up).should == true
87
+
88
+ File.read(@log).should include("USR1")
89
+ end
90
+
91
+ it "bad restart_command is #{cfg[:name]} and its kills" do
92
+ # not really restartin, just killing
93
+ # so monitor should see that process died, and up it
94
+ start_ok_process(cfg.merge(:restart_command => "kill -9 {{PID}}"))
95
+
96
+ mock(@process).check_crush
97
+
98
+ @process.restart
99
+ Eye::System.pid_alive?(@pid).should == false
100
+ @process.states_history.seq?(:up, :restarting, :down).should == true
101
+ end
102
+
103
+ it "Bad restart command, invalid" do
104
+ start_ok_process(cfg.merge(:restart_command => "asdfasdf sdf asd fasdf asdf"))
105
+
106
+ dont_allow(@process).check_crush
107
+
108
+ @process.restart
109
+ Eye::System.pid_alive?(@pid).should == true
110
+ @process.states_history.seq?(:up, :restarting, :up).should == true
111
+ end
112
+
113
+ it "restart command timeouted" do
114
+ start_ok_process(cfg.merge(:restart_command => "sleep 5", :restart_timeout => 3))
115
+ @process.restart
116
+
117
+ sleep 1
118
+ @process.pid.should == @pid
119
+
120
+ Eye::System.pid_alive?(@pid).should == true
121
+
122
+ @process.state_name.should == :up
123
+ @process.watchers.keys.should == [:check_alive]
124
+
125
+ @process.load_pid_from_file.should == @process.pid
126
+ @process.states_history.end?(:up, :restarting, :up).should == true
127
+ end
128
+ end
129
+
130
+ [:down, :unmonitored, :up].each do |st|
131
+ it "ok restart from #{st}" do
132
+ start_ok_process(C.p1)
133
+ @process.state = st.to_s
134
+ old_pid = @pid
135
+
136
+ dont_allow(@process).check_crush
137
+ @process.restart
138
+
139
+ @process.pid.should_not == old_pid
140
+ @process.pid.should > 0
141
+
142
+ Eye::System.pid_alive?(@pid).should == false
143
+ Eye::System.pid_alive?(@process.pid).should == true
144
+
145
+ @process.state_name.should == :up
146
+ @process.watchers.keys.should == [:check_alive]
147
+ @process.states_history.seq?(:restarting, :stopping, :down, :starting, :up).should == true
148
+
149
+ @process.load_pid_from_file.should == @process.pid
150
+ end
151
+ end
152
+
153
+ [:starting, :restarting, :stopping].each do |st|
154
+ it "not restart from #{st}" do
155
+ @process = process(C.p1)
156
+ @process.state = st.to_s # force set state
157
+
158
+ dont_allow(@process).stop
159
+ dont_allow(@process).start
160
+
161
+ @process.restart.should == nil
162
+ @process.state_name.should == st
163
+ end
164
+ end
165
+
166
+ it "restart process without start command" do
167
+ @process = process(C.p2.merge(:start_command => nil))
168
+ @process.restart
169
+ sleep 1
170
+ @process.unmonitored?.should == true
171
+ end
172
+
173
+
174
+ end
@@ -0,0 +1,150 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ class Eye::Process
4
+ attr_reader :test1, :test2, :test3, :test1_call
5
+
6
+ def scheduler_test1(a)
7
+ sleep 0.3
8
+ @test1_call ||= 0
9
+ @test1_call += 1
10
+ @test1 = a
11
+ end
12
+
13
+ def scheduler_test2(a, b)
14
+ sleep 0.6
15
+ @test2 = [a, b]
16
+ end
17
+
18
+ def scheduler_test3(*args)
19
+ @test3 = args
20
+ end
21
+
22
+ public :scheduler
23
+
24
+ end
25
+
26
+ describe "Scheduler" do
27
+ before :each do
28
+ @process = process C.p1
29
+ end
30
+
31
+ it "should schedule action" do
32
+ @process.test1.should == nil
33
+ @process.schedule :scheduler_test1, 1
34
+ sleep 0.1
35
+ @process.current_scheduled_command.should == :scheduler_test1
36
+ @process.test1.should == nil
37
+ sleep 0.4
38
+ @process.test1.should == 1
39
+ @process.current_scheduled_command.should == nil
40
+ end
41
+
42
+ it "should one after another" do
43
+ @process.test1.should == nil
44
+ @process.test2.should == nil
45
+
46
+ @process.schedule :scheduler_test1, 1
47
+ @process.schedule :scheduler_test2, 1, 2
48
+
49
+ sleep 0.4
50
+ @process.test1.should == 1
51
+ @process.test2.should == nil
52
+
53
+ sleep 0.6
54
+ @process.test1.should == 1
55
+ @process.test2.should == [1, 2]
56
+ end
57
+
58
+ it "should one after another2" do
59
+ @process.test1.should == nil
60
+ @process.test2.should == nil
61
+
62
+ @process.schedule :scheduler_test2, 1, 2
63
+ @process.schedule :scheduler_test1, 1
64
+
65
+ sleep 0.4
66
+ @process.test1.should == nil
67
+ @process.test2.should == nil
68
+
69
+ sleep 0.3
70
+ @process.test1.should == nil
71
+ @process.test2.should == [1, 2]
72
+
73
+ sleep 0.3
74
+ @process.test1.should == 1
75
+ @process.test2.should == [1, 2]
76
+ end
77
+
78
+ it "should not scheduler dublicates" do
79
+ @process.schedule :scheduler_test1, 1
80
+ @process.schedule :scheduler_test1, 1
81
+ @process.schedule :scheduler_test1, 1
82
+
83
+ sleep 1
84
+ @process.test1_call.should == 2
85
+ end
86
+
87
+ it "should scheduler dublicates by with different params" do
88
+ @process.schedule :scheduler_test1, 1
89
+ @process.schedule :scheduler_test1, 2
90
+ @process.schedule :scheduler_test1, 3
91
+
92
+ sleep 1
93
+ @process.test1_call.should == 3
94
+ end
95
+
96
+ it "should terminate when actor die" do
97
+ scheduler = @process.scheduler
98
+ @process.alive?.should == true
99
+ scheduler.alive?.should == true
100
+ @process.terminate
101
+ @process.alive?.should == false
102
+ scheduler.alive?.should == false
103
+ end
104
+
105
+ it "should terminate even with tasks" do
106
+ scheduler = @process.scheduler
107
+ @process.schedule :scheduler_test1, 1
108
+ @process.schedule :scheduler_test1, 1
109
+ @process.schedule :scheduler_test1, 1
110
+
111
+ @process.terminate
112
+ scheduler.alive?.should == false
113
+ end
114
+
115
+ it "when scheduling terminate of the parent actor" do
116
+ scheduler = @process.scheduler
117
+ @process.schedule :terminate
118
+ @process.schedule(:scheduler_test1, 1) rescue nil
119
+
120
+ sleep 0.2
121
+ @process.alive?.should == false
122
+ scheduler.alive?.should == false
123
+ end
124
+
125
+ describe "reasons" do
126
+ it "1 param without reason" do
127
+ @process.schedule :scheduler_test3, 1
128
+ sleep 0.1
129
+ @process.last_scheduled_command.should == :scheduler_test3
130
+ @process.last_scheduled_reason.should == nil
131
+ @process.test3.should == [1]
132
+ end
133
+
134
+ it "1 param with reason" do
135
+ @process.schedule :scheduler_test3, 1, "reason"
136
+ sleep 0.1
137
+ @process.last_scheduled_command.should == :scheduler_test3
138
+ @process.last_scheduled_reason.should == 'reason'
139
+ @process.test3.should == [1]
140
+ end
141
+
142
+ it "many params with reason" do
143
+ @process.schedule :scheduler_test3, 1, :bla, 3, "reason"
144
+ sleep 0.1
145
+ @process.last_scheduled_command.should == :scheduler_test3
146
+ @process.last_scheduled_reason.should == 'reason'
147
+ @process.test3.should == [1, :bla, 3]
148
+ end
149
+ end
150
+ end