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,83 @@
1
+ require 'celluloid'
2
+
3
+ class Eye::SystemResources
4
+
5
+ # cached system resources
6
+ class << self
7
+
8
+ def memory(pid)
9
+ ps_aux[pid].try :[], :rss
10
+ end
11
+
12
+ def cpu(pid)
13
+ ps_aux[pid].try :[], :cpu
14
+ end
15
+
16
+ def childs(parent_pid)
17
+ parent_pid = parent_pid.to_i
18
+
19
+ childs = []
20
+ ps_aux.each do |pid, h|
21
+ childs << pid if h[:ppid] == parent_pid
22
+ end
23
+
24
+ childs
25
+ end
26
+
27
+ def cmd(pid)
28
+ ps_aux[pid].try :[], :cmd
29
+ end
30
+
31
+ def start_time(pid)
32
+ ps_aux[pid].try :[], :start_time
33
+ end
34
+
35
+ def resources(pid)
36
+ return {} unless ps_aux[pid]
37
+
38
+ { :memory => memory(pid),
39
+ :cpu => cpu(pid),
40
+ :start_time => start_time(pid),
41
+ :cmd => cmd(pid),
42
+ :pid => pid
43
+ }
44
+ end
45
+
46
+ # initialize actor, call 1 time before using
47
+ def setup
48
+ @actor ||= PsAxActor.new
49
+ end
50
+
51
+ private
52
+
53
+ def ps_aux
54
+ setup
55
+ @actor.get
56
+ end
57
+
58
+ end
59
+
60
+ class PsAxActor
61
+ include Celluloid
62
+
63
+ UPDATE_INTERVAL = 5 # seconds
64
+
65
+ def initialize
66
+ set
67
+ end
68
+
69
+ def get
70
+ set! if @at + UPDATE_INTERVAL < Time.now
71
+ @ps_aux
72
+ end
73
+
74
+ private
75
+
76
+ def set
77
+ @ps_aux = Eye::System.ps_aux
78
+ @at = Time.now
79
+ end
80
+
81
+ end
82
+
83
+ end
@@ -0,0 +1,53 @@
1
+ class Eye::Trigger
2
+ include Eye::Logger::Helpers
3
+
4
+ autoload :Flapping, 'eye/trigger/flapping'
5
+
6
+ # ex: { :type => :flapping, :times => 2, :within => 30.seconds}
7
+
8
+ TYPES = {:flapping => "Flapping"}
9
+
10
+ attr_reader :message, :options
11
+
12
+ def self.get_class(type)
13
+ klass = eval("Eye::Trigger::#{TYPES[type]}") rescue nil
14
+ raise "Unknown trigger #{type}" unless klass
15
+ klass
16
+ end
17
+
18
+ def self.create(options = {}, logger_prefix = nil)
19
+ get_class(options[:type]).new(options, logger_prefix)
20
+ end
21
+
22
+ def self.validate!(options = {})
23
+ get_class(options[:type]).validate(options)
24
+ end
25
+
26
+ def initialize(options = {}, logger_prefix = nil)
27
+ @options = options
28
+ @logger = Eye::Logger.new(logger_prefix, "trigger")
29
+
30
+ debug "add trigger #{options}"
31
+ end
32
+
33
+ def check(states_history)
34
+ @states_history = states_history
35
+
36
+ res = good?
37
+
38
+ if res
39
+ debug 'check flapping'
40
+ else
41
+ debug "!!! #{self.class} recognized !!!"
42
+ end
43
+
44
+ res
45
+ end
46
+
47
+ def good?
48
+ raise 'realize me'
49
+ end
50
+
51
+ extend Eye::Checker::Validation
52
+
53
+ end
@@ -0,0 +1,24 @@
1
+ class Eye::Trigger::Flapping < Eye::Trigger
2
+
3
+ # triggers :flapping, :times => 10, :within => 1.minute
4
+
5
+ param :times, [Fixnum], true
6
+ param :within, [Float, Fixnum], true
7
+
8
+ def good?
9
+ return true unless within
10
+
11
+ states = @states_history.states_for_period( within )
12
+
13
+ starting_count = states.count{|st| st == :starting}
14
+ down_count = states.count{|st| st == :down}
15
+ times_count = times || 5
16
+
17
+ if (starting_count >= times_count) && (down_count >= times_count)
18
+ false
19
+ else
20
+ true
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,5 @@
1
+ module Eye::Utils
2
+ autoload :Tail, 'eye/utils/tail'
3
+ autoload :AliveArray, 'eye/utils/alive_array'
4
+ autoload :CelluloidChain, 'eye/utils/celluloid_chain'
5
+ end
@@ -0,0 +1,31 @@
1
+ class Eye::Utils::AliveArray
2
+ extend Forwardable
3
+ include Enumerable
4
+
5
+ def_delegators :@arr, :[], :<<, :clear, :delete, :size, :empty?
6
+
7
+ def initialize(arr = [])
8
+ @arr = arr
9
+ end
10
+
11
+ def each(&block)
12
+ @arr.each{|elem| elem && elem.alive? && block[elem] }
13
+ end
14
+
15
+ def to_a
16
+ map{|x| x }
17
+ end
18
+
19
+ def full_size
20
+ @arr.size
21
+ end
22
+
23
+ def pure
24
+ @arr
25
+ end
26
+
27
+ def sort_by(&block)
28
+ self.class.new super
29
+ end
30
+
31
+ end
@@ -0,0 +1,51 @@
1
+ require 'celluloid'
2
+
3
+ class Eye::Utils::CelluloidChain
4
+ include Celluloid
5
+
6
+ def initialize(target)
7
+ @target = target
8
+ @calls = []
9
+ @running = false
10
+ end
11
+
12
+ def add(method_name, *args, &block)
13
+ @calls << {:method_name => method_name, :args => args, :block => block}
14
+ process! unless @running
15
+ end
16
+
17
+ def add_wo_dups(method_name, *args, &block)
18
+ h = {:method_name => method_name, :args => args, :block => block}
19
+ @calls << h if @calls[-1] != h
20
+ process! unless @running
21
+ end
22
+
23
+ def list
24
+ @calls
25
+ end
26
+
27
+ def names_list
28
+ list.map{|el| el[:method_name].to_sym }
29
+ end
30
+
31
+ def clear
32
+ @calls = []
33
+ end
34
+
35
+ # need, because of https://github.com/celluloid/celluloid/issues/22
36
+ def inspect
37
+ "Celluloid::Chain(#{@target.class}: #{@calls.inspect})"
38
+ end
39
+
40
+ attr_reader :running
41
+
42
+ private
43
+
44
+ def process
45
+ while call = @calls.shift
46
+ @running = true
47
+ @target.send(call[:method_name], *call[:args], &call[:block]) if @target.alive?
48
+ end
49
+ @running = false
50
+ end
51
+ end
@@ -0,0 +1,7 @@
1
+ # http://stackoverflow.com/questions/7263268/ruby-symbolto-proc-leaks-references-in-1-9-2-p180
2
+
3
+ class Symbol
4
+ def to_proc
5
+ lambda { |x| x.send(self) }
6
+ end
7
+ end
@@ -0,0 +1,20 @@
1
+ class Eye::Utils::Tail < Array
2
+
3
+ # limited array
4
+
5
+ def initialize(max_size = 100)
6
+ @max_size = max_size
7
+ super()
8
+ end
9
+
10
+ def push(el)
11
+ super(el)
12
+ shift if length > @max_size
13
+ self
14
+ end
15
+
16
+ def << (el)
17
+ push(el)
18
+ end
19
+
20
+ end
@@ -0,0 +1,58 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ def chcpu(cfg = {})
4
+ Eye::Checker.create(123, {:type => :cpu, :every => 5.seconds,
5
+ :times => 1}.merge(cfg))
6
+ end
7
+
8
+ describe "Eye::Checker::Cpu" do
9
+
10
+ describe "without below" do
11
+ subject{ chcpu }
12
+
13
+ it "get_value" do
14
+ mock(Eye::SystemResources).cpu(123){ 65 }
15
+ subject.get_value.should == 65
16
+ end
17
+
18
+ it "without below always true" do
19
+ stub(subject).get_value{ 15 }
20
+ subject.check.should == true
21
+
22
+ stub(subject).get_value{ 20 }
23
+ subject.check.should == true
24
+ end
25
+ end
26
+
27
+ describe "with below" do
28
+ subject{ chcpu(:below => 30) }
29
+
30
+ it "good" do
31
+ stub(subject).get_value{ 20 }
32
+ subject.check.should == true
33
+
34
+ stub(subject).get_value{ 25 }
35
+ subject.check.should == true
36
+ end
37
+
38
+ it "good" do
39
+ stub(subject).get_value{ 25 }
40
+ subject.check.should == true
41
+
42
+ stub(subject).get_value{ 35 }
43
+ subject.check.should == false
44
+ end
45
+
46
+ end
47
+
48
+ describe "validates" do
49
+ it "ok" do
50
+ Eye::Checker.validate!({:type => :cpu, :every => 5.seconds, :times => 1, :below => 100})
51
+ end
52
+
53
+ it "bad param below" do
54
+ expect{ Eye::Checker.validate!({:type => :cpu, :every => 5.seconds, :times => 1, :below => {1 => 2}}) }.to raise_error(Eye::Checker::Validation::Error)
55
+ end
56
+ end
57
+
58
+ end
@@ -0,0 +1,34 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ def chctime(cfg = {})
4
+ Eye::Checker.create(nil, {:type => :ctime, :every => 5.seconds,
5
+ :file => $logger_path, :times => 1}.merge(cfg))
6
+ end
7
+
8
+ describe "Eye::Checker::FileCTime" do
9
+
10
+ describe "" do
11
+ subject{ chctime }
12
+
13
+ it "get_value" do
14
+ subject.get_value.should == File.ctime($logger_path)
15
+ end
16
+
17
+ it "not good if size equal prevous" do
18
+ stub(subject).get_value{ Time.parse('00:00:01') }
19
+ subject.check.should == true
20
+
21
+ stub(subject).get_value{ Time.parse('00:00:01') }
22
+ subject.check.should == false
23
+ end
24
+
25
+ it "good when little different with previous" do
26
+ stub(subject).get_value{ Time.parse('00:00:01') }
27
+ subject.check.should == true
28
+
29
+ stub(subject).get_value{ Time.parse('00:00:02') }
30
+ subject.check.should == true
31
+ end
32
+ end
33
+
34
+ end
@@ -0,0 +1,107 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ def chfsize(cfg = {})
4
+ Eye::Checker.create(nil, {:type => :fsize, :every => 5.seconds,
5
+ :file => $logger_path, :times => 1}.merge(cfg))
6
+ end
7
+
8
+ describe "Eye::Checker::FileSize" do
9
+
10
+ describe "" do
11
+ subject{ chfsize }
12
+
13
+ it "get_value" do
14
+ subject.get_value.should be_within(10).of(File.size($logger_path))
15
+ end
16
+
17
+ it "not good if size equal prevous" do
18
+ stub(subject).get_value{1001}
19
+ subject.check.should == true
20
+
21
+ stub(subject).get_value{1001}
22
+ subject.check.should == false
23
+ end
24
+
25
+ it "good when little different with previous" do
26
+ stub(subject).get_value{1001}
27
+ subject.check.should == true
28
+
29
+ stub(subject).get_value{1002}
30
+ subject.check.should == true
31
+ end
32
+ end
33
+
34
+ describe "below" do
35
+ subject{ chfsize(:below => 10) }
36
+
37
+ it "good" do
38
+ stub(subject).get_value{1001}
39
+ subject.check.should == true
40
+
41
+ stub(subject).get_value{1005}
42
+ subject.check.should == true
43
+ end
44
+
45
+ it "bad" do
46
+ stub(subject).get_value{1001}
47
+ subject.check.should == true
48
+
49
+ stub(subject).get_value{1015}
50
+ subject.check.should == false
51
+ end
52
+
53
+ end
54
+
55
+ describe "above" do
56
+ subject{ chfsize(:above => 10) }
57
+
58
+ it "good" do
59
+ stub(subject).get_value{1001}
60
+ subject.check.should == true
61
+
62
+ stub(subject).get_value{1005}
63
+ subject.check.should == false
64
+ end
65
+
66
+ it "bad" do
67
+ stub(subject).get_value{1001}
68
+ subject.check.should == true
69
+
70
+ stub(subject).get_value{1015}
71
+ subject.check.should == true
72
+ end
73
+
74
+ end
75
+
76
+
77
+ describe "above and below" do
78
+ subject{ chfsize(:above => 10, :below => 30) }
79
+
80
+ it "bad" do
81
+ stub(subject).get_value{1001}
82
+ subject.check.should == true
83
+
84
+ stub(subject).get_value{1005}
85
+ subject.check.should == false
86
+ end
87
+
88
+ it "good" do
89
+ stub(subject).get_value{1001}
90
+ subject.check.should == true
91
+
92
+ stub(subject).get_value{1021}
93
+ subject.check.should == true
94
+ end
95
+
96
+ it "bad" do
97
+ stub(subject).get_value{1001}
98
+ subject.check.should == true
99
+
100
+ stub(subject).get_value{1045}
101
+ subject.check.should == false
102
+ end
103
+
104
+ end
105
+
106
+
107
+ end