litmus_paper 0.9.6 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -20,8 +20,8 @@ Or install it yourself as:
20
20
 
21
21
  ## Usage
22
22
 
23
- Use the sample config to run it under unicorn. Or when running it as an
24
- agent-check for HAProxy use the sample xinetd config.
23
+ Use the sample config to run it under unicorn. Or execute litmus-agent-check to
24
+ use it as an agent-check for HAProxy.
25
25
 
26
26
  ## Contributing
27
27
 
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'optparse'
4
3
  require 'litmus_paper'
5
4
  require 'litmus_paper/cli/agent_check'
6
5
 
data/config.ru CHANGED
@@ -1,5 +1,6 @@
1
1
  $LOAD_PATH.unshift File.expand_path('lib', File.dirname(__FILE__))
2
2
  require 'litmus_paper'
3
+ require 'litmus_paper/app'
3
4
 
4
5
  LitmusPaper.configure
5
6
  use Rack::CommonLogger, LitmusPaper.logger
@@ -0,0 +1,28 @@
1
+ module LitmusPaper
2
+ class AgentCheckHandler
3
+ def self.handle(service)
4
+ output = []
5
+ health = LitmusPaper.check_service(service)
6
+ if health.nil?
7
+ output << "failed#NOT_FOUND"
8
+ else
9
+ case health.direction
10
+ when :up, :health
11
+ output << "ready" # administrative state
12
+ output << "up" # operational state
13
+ when :down
14
+ output << "drain" # administrative state
15
+ when :none
16
+ if health.ok?
17
+ output << "ready" # administrative state
18
+ output << "up" # operational state
19
+ else
20
+ output << "down" # operational state
21
+ end
22
+ end
23
+ output << "#{health.value.to_s}%"
24
+ end
25
+ output.join("\t")
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,97 @@
1
+ # Preforking TCP server, mostly stolen from Jesse Storimer's Book Working with
2
+ # TCP Sockets
3
+
4
+ require 'socket'
5
+ require 'litmus_paper/agent_check_handler'
6
+
7
+ module LitmusPaper
8
+ class AgentCheckServer
9
+ CRLF = "\r\n"
10
+
11
+ def initialize(litmus_paper_config, services, workers, pid_file, daemonize)
12
+ LitmusPaper.configure(litmus_paper_config)
13
+ @services = services
14
+ @workers = workers
15
+ @pid_file = pid_file
16
+ @daemonize = daemonize
17
+ @control_sockets = @services.keys.map do |port|
18
+ TCPServer.new(port)
19
+ end
20
+ trap(:INT) { exit }
21
+ trap(:TERM) { exit }
22
+ end
23
+
24
+ # Stolen pattern from ruby Socket, modified to return the service based on
25
+ # the accepting port
26
+ def accept_loop(sockets)
27
+ if sockets.empty?
28
+ raise ArgumentError, "no sockets"
29
+ end
30
+ loop {
31
+ readable, _, _ = IO.select(sockets)
32
+ readable.each { |r|
33
+ begin
34
+ sock, addr = r.accept_nonblock
35
+ service = @services[r.local_address.ip_port]
36
+ rescue IO::WaitReadable
37
+ next
38
+ end
39
+ yield sock, service
40
+ }
41
+ }
42
+ end
43
+
44
+ def respond(sock, message)
45
+ sock.write(message)
46
+ sock.write(CRLF)
47
+ end
48
+
49
+ def write_pid(pid_file)
50
+ File.open(pid_file, 'w') do |f|
51
+ f.write(Process.pid)
52
+ end
53
+ end
54
+
55
+ def run
56
+ if @daemonize
57
+ Process.daemon
58
+ end
59
+ write_pid(@pid_file)
60
+ child_pids = []
61
+
62
+ @workers.times do
63
+ child_pids << spawn_child
64
+ end
65
+
66
+ kill_children = Proc.new { |signo|
67
+ child_pids.each do |cpid|
68
+ begin
69
+ Process.kill(:INT, cpid)
70
+ rescue Errno::ESRCH
71
+ end
72
+ end
73
+ File.delete(@pid_file) if File.exists?(@pid_file)
74
+ exit
75
+ }
76
+
77
+ trap(:INT, &kill_children)
78
+ trap(:TERM, &kill_children)
79
+
80
+ loop do
81
+ pid = Process.wait
82
+ LitmusPaper.logger.error("Process #{pid} quit unexpectedly")
83
+ child_pids.delete(pid)
84
+ child_pids << spawn_child
85
+ end
86
+ end
87
+
88
+ def spawn_child
89
+ fork do
90
+ accept_loop(@control_sockets) do |sock, service|
91
+ respond(sock, AgentCheckHandler.handle(service))
92
+ sock.close
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -1,3 +1,6 @@
1
+ require 'sinatra/base'
2
+ require 'litmus_paper/terminal_output'
3
+
1
4
  module LitmusPaper
2
5
  class App < Sinatra::Base
3
6
  disable :show_exceptions
@@ -1,15 +1,28 @@
1
+ require 'optparse'
2
+ require 'litmus_paper/agent_check_server'
3
+
1
4
  module LitmusPaper
2
5
  module CLI
3
6
  class AgentCheck
4
7
 
5
8
  def parse_args(args)
6
9
  options = {}
10
+ options[:pid_file] = '/tmp/litmus-agent-check.pid'
7
11
  optparser = OptionParser.new do |opts|
8
- opts.on("-s", "--service SERVICE", "Service to check") do |s|
9
- options[:service] = s
12
+ opts.on("-s", "--service SERVICE:PORT,...", Array, "agent-check service to port mappings") do |s|
13
+ options[:services] = s
14
+ end
15
+ opts.on("-c", "--config CONFIG", "Path to litmus paper config file") do |c|
16
+ options[:litmus_paper_config] = c
17
+ end
18
+ opts.on("-p", "--pid-file PID_FILE", String, "Where to write the pid") do |p|
19
+ options[:pid_file] = p
10
20
  end
11
- opts.on("-c", "--config CONFIG", "Path to config file") do |c|
12
- options[:config] = c
21
+ opts.on("-w", "--workers WORKERS", Integer, "Number of worker processes") do |w|
22
+ options[:workers] = w
23
+ end
24
+ opts.on("-D", "--daemonize", "Daemonize the process") do |d|
25
+ options[:daemonize] = d
13
26
  end
14
27
  opts.on("-h", "--help", "Help text") do |h|
15
28
  options[:help] = h
@@ -29,43 +42,45 @@ module LitmusPaper
29
42
  exit 0
30
43
  end
31
44
 
32
- if !options.has_key?(:service)
33
- puts "Error: `-s SERVICE` required"
45
+ if !options.has_key?(:services)
46
+ puts "Error: `-s SERVICE:PORT,...` required"
34
47
  puts optparser
35
48
  exit 1
36
49
  end
37
- options
38
- end
39
50
 
40
- def output_service_status(service, stdout)
41
- output = []
42
- health = LitmusPaper.check_service(service)
43
- if health.nil?
44
- output << "failed#NOT_FOUND"
45
- else
46
- case health.direction
47
- when :up, :health
48
- output << "ready" # administrative state
49
- output << "up" # operational state
50
- when :down
51
- output << "drain" # administrative state
52
- when :none
53
- if health.ok?
54
- output << "ready" # administrative state
55
- output << "up" # operational state
56
- else
57
- output << "down" # operational state
58
- end
51
+ if !options.has_key?(:workers) || options[:workers] <= 0
52
+ puts "Error: `-w WORKERS` required, and must be greater than 0"
53
+ puts " Use a value equal to the number of expected concurrent"
54
+ puts " agent checks from HAProxy"
55
+ puts optparser
56
+ exit 1
57
+ end
58
+
59
+ options[:services] = options[:services].reduce({}) do |memo, service|
60
+ if service.split(':').length == 2
61
+ service, port = service.split(':')
62
+ memo[port.to_i] = service
63
+ memo
64
+ else
65
+ puts "Error: Incorrect service port arg `-s SERVICE:PORT,...`"
66
+ puts optparser
67
+ exit 1
59
68
  end
60
- output << "#{health.value.to_s}%"
61
69
  end
62
- stdout.printf("%s\r\n", output.join("\t"))
70
+
71
+ options
63
72
  end
64
73
 
65
74
  def run(args)
66
75
  options = parse_args(args)
67
- LitmusPaper.configure(options[:config])
68
- output_service_status(options[:service], $stdout)
76
+ agent_check_server = LitmusPaper::AgentCheckServer.new(
77
+ options[:litmus_paper_config],
78
+ options[:services],
79
+ options[:workers],
80
+ options[:pid_file],
81
+ options[:daemonize],
82
+ )
83
+ agent_check_server.run
69
84
  end
70
85
 
71
86
  end
@@ -1,3 +1,5 @@
1
+ require 'open3'
2
+
1
3
  module LitmusPaper
2
4
  module Dependency
3
5
  class Script
@@ -9,23 +11,27 @@ module LitmusPaper
9
11
  end
10
12
 
11
13
  def available?
12
- Timeout.timeout(@timeout) do
13
- script_stdout = script_stderr = nil
14
- script_status = POpen4.popen4(@command) do |stdout, stderr, stdin, pid|
15
- @script_pid = pid
16
- script_stdout = stdout.read.strip
17
- script_stderr = stderr.read.strip
18
- end
19
- unless script_status.success?
20
- LitmusPaper.logger.info("Available check to #{@command} failed with status #{$CHILD_STATUS.exitstatus}")
21
- LitmusPaper.logger.info("Failed stdout: #{script_stdout}")
22
- LitmusPaper.logger.info("Failed stderr: #{script_stderr}")
14
+ script_status = script_stdout = script_stderr = nil
15
+ Open3.popen3(@command, :pgroup=>true) do |stdin, stdout, stderr, wait_thr|
16
+ @script_pid = wait_thr.pid
17
+ thstderr = Thread.new { stderr.read }
18
+ thstdout = Thread.new { stdout.read }
19
+ if !wait_thr.join(@timeout) # wait thread does not end within timeout
20
+ kill_and_reap_script(-@script_pid) # kill the process group
21
+ raise Timeout::Error
23
22
  end
24
- script_status.success?
23
+ script_stderr = thstderr.value
24
+ script_stdout = thstdout.value
25
+ script_status = wait_thr.value
26
+ end
27
+ unless script_status.success?
28
+ LitmusPaper.logger.info("Available check to #{@command} failed with status #{script_status.exitstatus}")
29
+ LitmusPaper.logger.info("Failed stdout: #{script_stdout}")
30
+ LitmusPaper.logger.info("Failed stderr: #{script_stderr}")
25
31
  end
32
+ script_status.success?
26
33
  rescue Timeout::Error
27
34
  LitmusPaper.logger.info("Timeout running command: '#{@command}'")
28
- kill_and_reap_script(@script_pid)
29
35
  false
30
36
  rescue => e
31
37
  LitmusPaper.logger.info("Available check to #{@uri} failed with #{e.message}")
@@ -1,9 +1,8 @@
1
1
  module LitmusPaper
2
2
  module Metric
3
3
  class CPULoad
4
- def initialize(weight, facter = Facter)
4
+ def initialize(weight)
5
5
  @weight = weight
6
- @facter = facter
7
6
  end
8
7
 
9
8
  def current_health
@@ -11,11 +10,18 @@ module LitmusPaper
11
10
  end
12
11
 
13
12
  def processor_count
14
- @processor_count ||= @facter.value('processorcount').to_i
13
+ @processor_count ||= File.readlines('/proc/cpuinfo').reduce(0) do |memo, line|
14
+ if line =~ /^processor/
15
+ memo + 1
16
+ else
17
+ memo
18
+ end
19
+ end
20
+
15
21
  end
16
22
 
17
23
  def load_average
18
- @facter.value('loadaverage').split(' ').first.to_f
24
+ File.read('/proc/loadavg').split(' ').first.to_f
19
25
  end
20
26
 
21
27
  def to_s
@@ -1,3 +1,5 @@
1
+ require 'open3'
2
+
1
3
  module LitmusPaper
2
4
  module Metric
3
5
  class Script
@@ -15,24 +17,28 @@ module LitmusPaper
15
17
 
16
18
  def result
17
19
  value = 0
18
- Timeout.timeout(@timeout) do
19
- script_stdout = script_stderr = nil
20
- script_status = POpen4.popen4(@command) do |stdout, stderr, stdin, pid|
21
- @script_pid = pid
22
- value = script_stdout = stdout.read.strip
23
- script_stderr = stderr.read.strip
24
- end
25
- unless script_status.success?
26
- LitmusPaper.logger.info("Available check to #{@command} failed with status #{$CHILD_STATUS.exitstatus}")
27
- LitmusPaper.logger.info("Failed stdout: #{script_stdout}")
28
- LitmusPaper.logger.info("Failed stderr: #{script_stderr}")
20
+ script_status = script_stdout = script_stderr = nil
21
+ Open3.popen3(@command, :pgroup=>true) do |stdin, stdout, stderr, wait_thr|
22
+ @script_pid = wait_thr.pid
23
+ thstderr = Thread.new { stderr.read }
24
+ thstdout = Thread.new { stdout.read }
25
+ if !wait_thr.join(@timeout) # wait thread does not end within timeout
26
+ kill_and_reap_script(-@script_pid) # kill the process group
27
+ raise Timeout::Error
29
28
  end
30
-
31
- value.to_f
29
+ script_stderr = thstderr.value
30
+ script_stdout = thstdout.value
31
+ value = script_stdout.strip
32
+ script_status = wait_thr.value
33
+ end
34
+ unless script_status.success?
35
+ LitmusPaper.logger.info("Available check to #{@command} failed with status #{script_status.exitstatus}")
36
+ LitmusPaper.logger.info("Failed stdout: #{script_stdout}")
37
+ LitmusPaper.logger.info("Failed stderr: #{script_stderr}")
32
38
  end
39
+ value.to_f
33
40
  rescue Timeout::Error
34
41
  LitmusPaper.logger.info("Available check to '#{@command}' timed out")
35
- kill_and_reap_script(@script_pid)
36
42
  0
37
43
  end
38
44
 
@@ -1,4 +1,6 @@
1
1
  # encoding: UTF-8
2
+ require 'colorize'
3
+
2
4
  module LitmusPaper
3
5
  class TerminalOutput
4
6
  def self.service_status
@@ -1,3 +1,3 @@
1
1
  module LitmusPaper
2
- VERSION = "0.9.6"
2
+ VERSION = "0.9.7"
3
3
  end
data/lib/litmus_paper.rb CHANGED
@@ -1,11 +1,3 @@
1
- require 'pathname'
2
- require 'net/http'
3
- require 'net/https'
4
- require 'uri'
5
- require 'forwardable'
6
- require 'English'
7
- require 'colorize'
8
-
9
1
  # Ruby's stock DNS resolution, by default, blocks the entire Ruby VM from
10
2
  # processing while the lookup is happening, because it calls out to the native
11
3
  # libc resolver code. A slow DNS server can cause your entire Ruby process to
@@ -15,15 +7,13 @@ require 'colorize'
15
7
  # 'resolv-replace' monkeypatches the various Ruby Socket objects to use resolv
16
8
  #
17
9
  require 'resolv-replace'
10
+ require 'net/http'
11
+ require 'net/https'
12
+ require 'uri'
13
+ require 'forwardable'
18
14
 
19
- require 'popen4'
20
- require 'sinatra/base'
21
- require 'facter'
22
15
  require 'remote_syslog_logger'
23
16
 
24
- require 'facts/loadaverage'
25
-
26
- require 'litmus_paper/app'
27
17
  require 'litmus_paper/configuration'
28
18
  require 'litmus_paper/configuration_file'
29
19
  require 'litmus_paper/dependency/file_contents'
@@ -33,7 +23,6 @@ require 'litmus_paper/dependency/script'
33
23
  require 'litmus_paper/dependency/tcp'
34
24
  require 'litmus_paper/health'
35
25
  require 'litmus_paper/logger'
36
- require 'litmus_paper/metric/available_memory'
37
26
  require 'litmus_paper/metric/big_brother_service'
38
27
  require 'litmus_paper/metric/constant_metric'
39
28
  require 'litmus_paper/metric/cpu_load'
@@ -41,7 +30,6 @@ require 'litmus_paper/metric/internet_health'
41
30
  require 'litmus_paper/metric/script'
42
31
  require 'litmus_paper/service'
43
32
  require 'litmus_paper/status_file'
44
- require 'litmus_paper/terminal_output'
45
33
  require 'litmus_paper/version'
46
34
 
47
35
  module LitmusPaper
@@ -54,8 +42,6 @@ module LitmusPaper
54
42
  self.logger = Logger.new
55
43
 
56
44
  def self.check_service(service_name)
57
- Facter.flush
58
-
59
45
  if service = services[service_name]
60
46
  service.current_health
61
47
  else
@@ -0,0 +1,130 @@
1
+ #! /bin/sh
2
+ ### BEGIN INIT INFO
3
+ # Provides: litmus-agent-check
4
+ # Required-Start: $remote_fs $syslog
5
+ # Required-Stop: $remote_fs $syslog
6
+ # Default-Start: 2 3 4 5
7
+ # Default-Stop: 0 1 6
8
+ # Short-Description: Litmus agent-check for HAProxy
9
+ # Description: Provide an agent-check server for HAProxy
10
+ ### END INIT INFO
11
+
12
+ # Author: Braintreeps <code@getbraintree.com>
13
+
14
+ PATH=/sbin:/usr/sbin:/bin:/usr/bin
15
+ DESC="Litmus HAProxy agent-check server"
16
+ NAME=litmus-agent-check
17
+ DAEMON=/usr/bin/$NAME
18
+ PIDFILE=/var/run/litmus-agent-check/pid
19
+ DAEMON_ARGS="-D -p ${PIDFILE}"
20
+ SCRIPTNAME=/etc/init.d/$NAME
21
+
22
+ # Exit if the package is not installed
23
+ [ -x "$DAEMON" ] || exit 0
24
+
25
+ # Read configuration variable file if it is present
26
+ [ -r /etc/default/$NAME ] && . /etc/default/$NAME
27
+
28
+ # Define LSB log_* functions.
29
+ # Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
30
+ . /lib/lsb/init-functions
31
+
32
+ #
33
+ # Function that starts the daemon/service
34
+ #
35
+ do_start()
36
+ {
37
+ mkdir -p $(dirname $PIDFILE)
38
+ # Return
39
+ # 0 if daemon has been started
40
+ # 1 if daemon was already running
41
+ # 2 if daemon could not be started
42
+ start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
43
+ || return 1
44
+ start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
45
+ $DAEMON_ARGS $EXTRA_ARGS\
46
+ || return 2
47
+ # Add code here, if necessary, that waits for the process to be ready
48
+ # to handle requests from services started subsequently which depend
49
+ # on this one. As a last resort, sleep for some time.
50
+ }
51
+
52
+ #
53
+ # Function that stops the daemon/service
54
+ #
55
+ do_stop()
56
+ {
57
+ # Return
58
+ # 0 if daemon has been stopped
59
+ # 1 if daemon was already stopped
60
+ # 2 if daemon could not be stopped
61
+ # other if a failure occurred
62
+ start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
63
+ RETVAL="$?"
64
+ [ "$RETVAL" = 2 ] && return 2
65
+ # Many daemons don't delete their pidfiles when they exit.
66
+ rm -f $PIDFILE
67
+ return "$RETVAL"
68
+ }
69
+
70
+ #
71
+ # Function that sends a SIGHUP to the daemon/service
72
+ #
73
+ do_reload() {
74
+ #
75
+ # If the daemon can reload its configuration without
76
+ # restarting (for example, when it is sent a SIGHUP),
77
+ # then implement that here.
78
+ #
79
+ start-stop-daemon --stop --signal HUP --quiet --pidfile $PIDFILE
80
+ return 0
81
+ }
82
+
83
+ case "$1" in
84
+ start)
85
+ [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
86
+ do_start
87
+ case "$?" in
88
+ 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
89
+ 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
90
+ esac
91
+ ;;
92
+ stop)
93
+ [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
94
+ do_stop
95
+ case "$?" in
96
+ 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
97
+ 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
98
+ esac
99
+ ;;
100
+ status)
101
+ status_of_proc -p ${PIDFILE} && exit 0 || exit $?
102
+ ;;
103
+ reload|force-reload)
104
+ log_daemon_msg "Reloading $DESC" "$NAME"
105
+ do_reload
106
+ log_end_msg $?
107
+ ;;
108
+ restart)
109
+ log_daemon_msg "Restarting $DESC" "$NAME"
110
+ do_stop
111
+ case "$?" in
112
+ 0|1)
113
+ do_start
114
+ case "$?" in
115
+ 0) log_end_msg 0 ;;
116
+ 1) log_end_msg 1 ;; # Old process is still running
117
+ *) log_end_msg 1 ;; # Failed to start
118
+ esac
119
+ ;;
120
+ *)
121
+ # Failed to stop
122
+ log_end_msg 1
123
+ ;;
124
+ esac
125
+ ;;
126
+ *)
127
+ echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload|force-reload}" >&2
128
+ exit 3
129
+ ;;
130
+ esac
data/litmus_paper.gemspec CHANGED
@@ -17,9 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.version = LitmusPaper::VERSION
18
18
 
19
19
  gem.add_dependency "sinatra", "~> 1.3.2"
20
- gem.add_dependency "facter", "~> 1.7.5"
21
20
  gem.add_dependency "remote_syslog_logger", "~> 1.0.3"
22
- gem.add_dependency "popen4", "~> 0.1.2"
23
21
  gem.add_dependency "unicorn", "~> 4.6.2"
24
22
  gem.add_dependency "colorize"
25
23
 
@@ -1,47 +1,40 @@
1
1
  require 'spec_helper'
2
- require 'litmus_paper/cli/agent_check'
2
+ require 'litmus_paper/agent_check_handler'
3
3
 
4
- describe LitmusPaper::CLI::AgentCheck do
4
+ describe LitmusPaper::AgentCheckHandler do
5
5
  before :each do
6
6
  LitmusPaper.configure(TEST_CONFIG)
7
7
  end
8
8
 
9
- def agent_check(service)
10
- output = StringIO.new
11
- LitmusPaper::CLI::AgentCheck.new.output_service_status(service, output)
12
- output.rewind
13
- output.readline
14
- end
15
-
16
9
  describe "output_service_status" do
17
10
  it "returns the forced health value for a healthy service" do
18
11
  test_service = LitmusPaper::Service.new('test', [AlwaysAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
19
12
  LitmusPaper.services['test'] = test_service
20
13
  LitmusPaper::StatusFile.service_health_file("test").create("Forcing health", 88)
21
- agent_check("test").should == "ready\tup\t88%\r\n"
14
+ LitmusPaper::AgentCheckHandler.handle("test").should == "ready\tup\t88%"
22
15
  end
23
16
 
24
17
  it "returns the actual health value for an unhealthy service when the measured health is less than the forced value" do
25
18
  test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
26
19
  LitmusPaper.services['test'] = test_service
27
20
  LitmusPaper::StatusFile.service_health_file("test").create("Forcing health", 88)
28
- agent_check("test").should == "ready\tup\t0%\r\n"
21
+ LitmusPaper::AgentCheckHandler.handle("test").should == "ready\tup\t0%"
29
22
  end
30
23
 
31
24
  it "is 'ready' when the service is passing" do
32
25
  test_service = LitmusPaper::Service.new('test', [AlwaysAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
33
26
  LitmusPaper.services['test'] = test_service
34
- agent_check("test").should == "ready\tup\t100%\r\n"
27
+ LitmusPaper::AgentCheckHandler.handle("test").should == "ready\tup\t100%"
35
28
  end
36
29
 
37
30
  it "is 'down' when the check fails" do
38
31
  test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
39
32
  LitmusPaper.services['test'] = test_service
40
- agent_check("test").should == "down\t0%\r\n"
33
+ LitmusPaper::AgentCheckHandler.handle("test").should == "down\t0%"
41
34
  end
42
35
 
43
36
  it "is 'failed' when the service is unknown" do
44
- agent_check("unknown").should == "failed#NOT_FOUND\r\n"
37
+ LitmusPaper::AgentCheckHandler.handle("unknown").should == "failed#NOT_FOUND"
45
38
  end
46
39
 
47
40
  it "is 'drain' when an up file and down file exists" do
@@ -49,7 +42,7 @@ describe LitmusPaper::CLI::AgentCheck do
49
42
  LitmusPaper.services['test'] = test_service
50
43
  LitmusPaper::StatusFile.service_up_file("test").create("Up for testing")
51
44
  LitmusPaper::StatusFile.service_down_file("test").create("Down for testing")
52
- agent_check("test").should == "drain\t0%\r\n"
45
+ LitmusPaper::AgentCheckHandler.handle("test").should == "drain\t0%"
53
46
  end
54
47
 
55
48
  it "is 'drain' when a global down file and up file exists" do
@@ -57,28 +50,28 @@ describe LitmusPaper::CLI::AgentCheck do
57
50
  LitmusPaper.services['test'] = test_service
58
51
  LitmusPaper::StatusFile.global_down_file.create("Down for testing")
59
52
  LitmusPaper::StatusFile.global_up_file.create("Up for testing")
60
- agent_check("test").should == "drain\t0%\r\n"
53
+ LitmusPaper::AgentCheckHandler.handle("test").should == "drain\t0%"
61
54
  end
62
55
 
63
56
  it "is 'ready' when an up file exists" do
64
57
  test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
65
58
  LitmusPaper.services['test'] = test_service
66
59
  LitmusPaper::StatusFile.service_up_file("test").create("Up for testing")
67
- agent_check("test").should == "ready\tup\t100%\r\n"
60
+ LitmusPaper::AgentCheckHandler.handle("test").should == "ready\tup\t100%"
68
61
  end
69
62
 
70
63
  it "is 'drain' when a global down file exists" do
71
64
  test_service = LitmusPaper::Service.new('test', [AlwaysAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
72
65
  LitmusPaper.services['test'] = test_service
73
66
  LitmusPaper::StatusFile.global_down_file.create("Down for testing")
74
- agent_check("test").should == "drain\t0%\r\n"
67
+ LitmusPaper::AgentCheckHandler.handle("test").should == "drain\t0%"
75
68
  end
76
69
 
77
70
  it "is 'ready' when a global up file exists" do
78
71
  test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
79
72
  LitmusPaper.services['test'] = test_service
80
73
  LitmusPaper::StatusFile.global_up_file.create("Up for testing")
81
- agent_check("test").should == "ready\tup\t100%\r\n"
74
+ LitmusPaper::AgentCheckHandler.handle("test").should == "ready\tup\t100%"
82
75
  end
83
76
  end
84
77
  end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+ require 'litmus_paper/agent_check_server'
3
+
4
+ describe LitmusPaper::AgentCheckServer do
5
+ pid = nil
6
+
7
+ before :all do
8
+ if ! Kernel.system("bundle exec litmus-agent-check -s passing_test:9191,test:9192 -c spec/support/test.config -w 10 -D")
9
+ fail('Unable to start server')
10
+ end
11
+ port_open = false
12
+ while ! port_open do
13
+ begin
14
+ TCPSocket.new('localhost', 9191)
15
+ rescue StandardError => e
16
+ sleep 0.1
17
+ next
18
+ end
19
+ port_open = true
20
+ end
21
+ end
22
+
23
+ after :all do
24
+ Process.kill(:TERM, File.read('/tmp/litmus-agent-check.pid').to_i)
25
+ end
26
+
27
+ describe "The agent-check text protocol" do
28
+ it "returns the health from a passing test" do
29
+ TCPSocket.open('localhost', 9191) do |s|
30
+ s.gets.should match(/ready\tup\t\d+%\r\n/)
31
+ end
32
+ end
33
+ it "returns the health from a failing test" do
34
+ TCPSocket.open('localhost', 9192) do |s|
35
+ s.gets.should match(/down\t0%\r\n/)
36
+ end
37
+ end
38
+ end
39
+
40
+ describe "server" do
41
+ it "has the configured number of children running" do
42
+ pid = File.read('/tmp/litmus-agent-check.pid').to_i
43
+ children = `ps --no-headers --ppid #{pid}|wc -l`
44
+ children.strip.to_i == 10
45
+ end
46
+ end
47
+
48
+ describe "server" do
49
+ it "if a child dies you get a new one" do
50
+ pid = File.read('/tmp/litmus-agent-check.pid').to_i
51
+ Kernel.system("kill -9 $(ps --no-headers --ppid #{pid} -o pid=|tail -1)")
52
+ sleep 0.5
53
+ children = `ps --no-headers --ppid #{pid}|wc -l`
54
+ children.strip.to_i == 10
55
+ end
56
+ end
57
+ end
@@ -418,22 +418,6 @@ describe LitmusPaper::App do
418
418
  last_response.headers["X-Health-Forced"].should == "up"
419
419
  last_response.body.should match(/Up for testing/)
420
420
  end
421
-
422
- it "resets the Facter cache" do
423
- test_service = LitmusPaper::Service.new('test', [AlwaysAvailableDependency.new], [LitmusPaper::Metric::ConstantMetric.new(100)])
424
- LitmusPaper.services['test'] = test_service
425
-
426
- get "/test/status"
427
- last_response.should be_ok
428
-
429
- facter_uptime = Facter.value("uptime_seconds")
430
- sleep 1
431
-
432
- get "/test/status"
433
- last_response.should be_ok
434
-
435
- Facter.value("uptime_seconds").should > facter_uptime
436
- end
437
421
  end
438
422
 
439
423
  describe "server errors" do
@@ -33,7 +33,7 @@ describe 'litmusctl' do
33
33
  describe 'status' do
34
34
  it 'returns the status of a service' do
35
35
  _litmusctl('status test').should match("Health: 0")
36
- _litmusctl('status passing_test').should match(/Health: \d\d/)
36
+ _litmusctl('status passing_test').should match(/Health: \d+/)
37
37
  end
38
38
 
39
39
  it "returns 'NOT FOUND' for a service that doesn't exist" do
@@ -79,7 +79,7 @@ describe 'litmusctl' do
79
79
  _litmusctl('force up test -d').should match("File deleted")
80
80
 
81
81
  status = _litmusctl('status passing_test')
82
- status.should match(/Health: \d\d/)
82
+ status.should match(/Health: \d+/)
83
83
  status.should_not match(/for testing/)
84
84
  end
85
85
 
@@ -87,7 +87,7 @@ describe 'litmusctl' do
87
87
  _litmusctl('force health 88 test -r "for testing"').should match("File created")
88
88
  _litmusctl('force health test -d').should match("File deleted")
89
89
  status = _litmusctl('status passing_test')
90
- status.should match(/Health: \d\d/)
90
+ status.should match(/Health: \d+/)
91
91
  status.should_not match(/for testing/)
92
92
  end
93
93
 
@@ -7,8 +7,28 @@ describe LitmusPaper::Dependency::Script do
7
7
  check.should be_available
8
8
  end
9
9
 
10
+ it "is true when the script returns a lot of data" do
11
+ check = LitmusPaper::Dependency::Script.new("dd if=/dev/urandom bs=1M count=1|base64")
12
+ check.should be_available
13
+ end
14
+
10
15
  it "is false when the script returns 1" do
11
- check = LitmusPaper::Dependency::Script.new("false")
16
+ check = LitmusPaper::Dependency::Script.new("echo Hello && echo Goodbye 1>&2 && false")
17
+ check.should_not be_available
18
+ end
19
+
20
+ it "logs stdout and stderr when it fails" do
21
+ check = LitmusPaper::Dependency::Script.new("echo Hello && echo Goodbye 1>&2 && false")
22
+ count = 0
23
+ logs = [
24
+ "Available check to echo Hello && echo Goodbye 1>&2 && false failed with status 1",
25
+ "Failed stdout: Hello\n",
26
+ "Failed stderr: Goodbye\n",
27
+ ]
28
+ LitmusPaper.logger.should_receive(:info).exactly(3).times do |log|
29
+ log.should == logs[count]
30
+ count += 1
31
+ end
12
32
  check.should_not be_available
13
33
  end
14
34
 
@@ -3,14 +3,20 @@ require 'spec_helper'
3
3
  describe LitmusPaper::Metric::CPULoad do
4
4
  describe "#current_health" do
5
5
  it "is the percent of available cpu capacity" do
6
- facter = StubFacter.new({"processorcount" => "4", "loadaverage" => "1.00 0.40 0.10"})
7
- cpu_load = LitmusPaper::Metric::CPULoad.new(40, facter)
6
+ LitmusPaper::Metric::CPULoad.any_instance.stub(
7
+ :processor_count => 4,
8
+ :load_average => 1.00,
9
+ )
10
+ cpu_load = LitmusPaper::Metric::CPULoad.new(40)
8
11
  cpu_load.current_health.should == 30
9
12
  end
10
13
 
11
14
  it "is one when the load is above one per core" do
12
- facter = StubFacter.new({"processorcount" => "4", "loadaverage" => "20.00 11.40 10.00"})
13
- cpu_load = LitmusPaper::Metric::CPULoad.new(50, facter)
15
+ LitmusPaper::Metric::CPULoad.any_instance.stub(
16
+ :processor_count => 4,
17
+ :load_average => 20.00,
18
+ )
19
+ cpu_load = LitmusPaper::Metric::CPULoad.new(50)
14
20
  cpu_load.current_health.should == 1
15
21
  end
16
22
  end
@@ -22,7 +28,7 @@ describe LitmusPaper::Metric::CPULoad do
22
28
  end
23
29
 
24
30
  it "is cached" do
25
- Facter.should_receive(:value).once.and_return("10")
31
+ File.should_receive(:readlines).with('/proc/cpuinfo').once.and_return(["processor : 0\n"])
26
32
  cpu_load = LitmusPaper::Metric::CPULoad.new(50)
27
33
  cpu_load.processor_count
28
34
  cpu_load.processor_count
@@ -35,6 +41,13 @@ describe LitmusPaper::Metric::CPULoad do
35
41
  cpu_load = LitmusPaper::Metric::CPULoad.new(50)
36
42
  cpu_load.load_average.should > 0.0
37
43
  end
44
+
45
+ it "is not cached" do
46
+ File.should_receive(:read).with('/proc/loadavg').twice.and_return("0.08 0.12 0.15 2/1190 9152\n")
47
+ cpu_load = LitmusPaper::Metric::CPULoad.new(50)
48
+ cpu_load.load_average.should > 0.0
49
+ cpu_load.load_average.should > 0.0
50
+ end
38
51
  end
39
52
 
40
53
  describe "#to_s" do
@@ -7,6 +7,26 @@ describe LitmusPaper::Metric::Script do
7
7
  check.current_health.should == 1
8
8
  end
9
9
 
10
+ it "is true when the script returns a lot of data" do
11
+ check = LitmusPaper::Metric::Script.new("dd if=/dev/urandom bs=1M count=1|base64 >&2 && echo 1", 1)
12
+ check.current_health.should == 1
13
+ end
14
+
15
+ it "logs stdout and stderr when it fails" do
16
+ check = LitmusPaper::Metric::Script.new("echo Hello && echo Goodbye 1>&2 && false", 1)
17
+ count = 0
18
+ logs = [
19
+ "Available check to echo Hello && echo Goodbye 1>&2 && false failed with status 1",
20
+ "Failed stdout: Hello\n",
21
+ "Failed stderr: Goodbye\n",
22
+ ]
23
+ LitmusPaper.logger.should_receive(:info).exactly(3).times do |log|
24
+ log.should == logs[count]
25
+ count += 1
26
+ end
27
+ check.current_health.should == 0
28
+ end
29
+
10
30
  it "is zero when the script exits 1" do
11
31
  check = LitmusPaper::Metric::Script.new("false", 1)
12
32
  check.current_health.should == 0
data/spec/spec_helper.rb CHANGED
@@ -3,6 +3,7 @@ ENV['RACK_ENV'] = 'test'
3
3
  require 'rspec'
4
4
  require 'rack/test'
5
5
  require 'litmus_paper'
6
+ require 'litmus_paper/app'
6
7
  require 'tempfile'
7
8
 
8
9
  TEST_CONFIG_DIR = "/tmp/litmus_paper"
@@ -2,5 +2,4 @@
2
2
 
3
3
  service :passing_test do |s|
4
4
  s.measure_health Metric::CPULoad, :weight => 50
5
- s.measure_health Metric::AvailableMemory, :weight => 50
6
5
  end
@@ -4,5 +4,4 @@ service :test do |s|
4
4
  s.depends Dependency::HTTP, "http://localhost/heartbeat"
5
5
 
6
6
  s.measure_health Metric::CPULoad, :weight => 50
7
- s.measure_health Metric::AvailableMemory, :weight => 50
8
7
  end
@@ -8,10 +8,9 @@ service :test do |s|
8
8
  s.depends Dependency::HTTP, "http://localhost/heartbeat"
9
9
 
10
10
  s.measure_health Metric::CPULoad, :weight => 50
11
- s.measure_health Metric::AvailableMemory, :weight => 50
12
11
  end
13
12
 
14
13
  service :passing_test do |s|
15
14
  s.measure_health Metric::CPULoad, :weight => 50
16
- s.measure_health Metric::AvailableMemory, :weight => 50
15
+ s.depends Dependency::Script, "/bin/true"
17
16
  end
@@ -8,10 +8,8 @@ service :foo do |s|
8
8
  s.depends Dependency::HTTP, "http://localhost/heartbeat"
9
9
 
10
10
  s.measure_health Metric::CPULoad, :weight => 50
11
- s.measure_health Metric::AvailableMemory, :weight => 50
12
11
  end
13
12
 
14
13
  service :passing_test do |s|
15
14
  s.measure_health Metric::CPULoad, :weight => 50
16
- s.measure_health Metric::AvailableMemory, :weight => 50
17
15
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: litmus_paper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.6
4
+ version: 0.9.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-05-17 00:00:00.000000000 Z
12
+ date: 2017-06-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra
@@ -27,22 +27,6 @@ dependencies:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
29
  version: 1.3.2
30
- - !ruby/object:Gem::Dependency
31
- name: facter
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ~>
36
- - !ruby/object:Gem::Version
37
- version: 1.7.5
38
- type: :runtime
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ~>
44
- - !ruby/object:Gem::Version
45
- version: 1.7.5
46
30
  - !ruby/object:Gem::Dependency
47
31
  name: remote_syslog_logger
48
32
  requirement: !ruby/object:Gem::Requirement
@@ -59,22 +43,6 @@ dependencies:
59
43
  - - ~>
60
44
  - !ruby/object:Gem::Version
61
45
  version: 1.0.3
62
- - !ruby/object:Gem::Dependency
63
- name: popen4
64
- requirement: !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ~>
68
- - !ruby/object:Gem::Version
69
- version: 0.1.2
70
- type: :runtime
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
- requirements:
75
- - - ~>
76
- - !ruby/object:Gem::Version
77
- version: 0.1.2
78
46
  - !ruby/object:Gem::Dependency
79
47
  name: unicorn
80
48
  requirement: !ruby/object:Gem::Requirement
@@ -193,8 +161,9 @@ files:
193
161
  - bin/litmus-agent-check
194
162
  - bin/litmusctl
195
163
  - config.ru
196
- - lib/facts/loadaverage.rb
197
164
  - lib/litmus_paper.rb
165
+ - lib/litmus_paper/agent_check_handler.rb
166
+ - lib/litmus_paper/agent_check_server.rb
198
167
  - lib/litmus_paper/app.rb
199
168
  - lib/litmus_paper/cli/admin.rb
200
169
  - lib/litmus_paper/cli/admin/command.rb
@@ -212,7 +181,6 @@ files:
212
181
  - lib/litmus_paper/dependency/tcp.rb
213
182
  - lib/litmus_paper/health.rb
214
183
  - lib/litmus_paper/logger.rb
215
- - lib/litmus_paper/metric/available_memory.rb
216
184
  - lib/litmus_paper/metric/big_brother_service.rb
217
185
  - lib/litmus_paper/metric/constant_metric.rb
218
186
  - lib/litmus_paper/metric/cpu_load.rb
@@ -222,10 +190,12 @@ files:
222
190
  - lib/litmus_paper/status_file.rb
223
191
  - lib/litmus_paper/terminal_output.rb
224
192
  - lib/litmus_paper/version.rb
193
+ - litmus-agent-check.init.sh
225
194
  - litmus_paper.gemspec
195
+ - spec/litmus_paper/agent_check_handler_spec.rb
196
+ - spec/litmus_paper/agent_check_server_spec.rb
226
197
  - spec/litmus_paper/app_spec.rb
227
198
  - spec/litmus_paper/cli/admin_spec.rb
228
- - spec/litmus_paper/cli/agent_check_spec.rb
229
199
  - spec/litmus_paper/configuration_file_spec.rb
230
200
  - spec/litmus_paper/dependency/file_contents_spec.rb
231
201
  - spec/litmus_paper/dependency/haproxy_backends_spec.rb
@@ -233,7 +203,6 @@ files:
233
203
  - spec/litmus_paper/dependency/script_spec.rb
234
204
  - spec/litmus_paper/dependency/tcp_spec.rb
235
205
  - spec/litmus_paper/health_spec.rb
236
- - spec/litmus_paper/metric/available_memory_spec.rb
237
206
  - spec/litmus_paper/metric/big_brother_service_spec.rb
238
207
  - spec/litmus_paper/metric/constant_metric_spec.rb
239
208
  - spec/litmus_paper/metric/cpu_load_spec.rb
@@ -254,12 +223,10 @@ files:
254
223
  - spec/support/http_test_server_config.ru
255
224
  - spec/support/never_available_dependency.rb
256
225
  - spec/support/stdout_logger.rb
257
- - spec/support/stub_facter.rb
258
226
  - spec/support/test.config
259
227
  - spec/support/test.d.config
260
228
  - spec/support/test.reload.config
261
229
  - spec/support/test.unicorn.config
262
- - xinetd.conf
263
230
  homepage: https://github.com/braintree/litmus_paper
264
231
  licenses: []
265
232
  post_install_message:
@@ -285,9 +252,10 @@ signing_key:
285
252
  specification_version: 3
286
253
  summary: Backend health tester for HA Services, partner project of big_brother
287
254
  test_files:
255
+ - spec/litmus_paper/agent_check_handler_spec.rb
256
+ - spec/litmus_paper/agent_check_server_spec.rb
288
257
  - spec/litmus_paper/app_spec.rb
289
258
  - spec/litmus_paper/cli/admin_spec.rb
290
- - spec/litmus_paper/cli/agent_check_spec.rb
291
259
  - spec/litmus_paper/configuration_file_spec.rb
292
260
  - spec/litmus_paper/dependency/file_contents_spec.rb
293
261
  - spec/litmus_paper/dependency/haproxy_backends_spec.rb
@@ -295,7 +263,6 @@ test_files:
295
263
  - spec/litmus_paper/dependency/script_spec.rb
296
264
  - spec/litmus_paper/dependency/tcp_spec.rb
297
265
  - spec/litmus_paper/health_spec.rb
298
- - spec/litmus_paper/metric/available_memory_spec.rb
299
266
  - spec/litmus_paper/metric/big_brother_service_spec.rb
300
267
  - spec/litmus_paper/metric/constant_metric_spec.rb
301
268
  - spec/litmus_paper/metric/cpu_load_spec.rb
@@ -316,7 +283,6 @@ test_files:
316
283
  - spec/support/http_test_server_config.ru
317
284
  - spec/support/never_available_dependency.rb
318
285
  - spec/support/stdout_logger.rb
319
- - spec/support/stub_facter.rb
320
286
  - spec/support/test.config
321
287
  - spec/support/test.d.config
322
288
  - spec/support/test.reload.config
@@ -1,6 +0,0 @@
1
- Facter.add("loadaverage") do
2
- setcode do
3
- uptime = Facter::Util::Resolution.exec("uptime")
4
- uptime.split(":").last
5
- end
6
- end
@@ -1,36 +0,0 @@
1
- module LitmusPaper
2
- module Metric
3
- class AvailableMemory
4
- MULTIPLIER = {
5
- "GB" => 1024*1024*1024,
6
- "MB" => 1024*1024,
7
- "KB" => 1024
8
- }
9
-
10
- def initialize(weight, facter = Facter)
11
- @weight = weight
12
- @facter = facter
13
- end
14
-
15
- def current_health
16
- @weight * memory_free / memory_total
17
- end
18
-
19
- def memory_total
20
- return @memory_total unless @memory_total.nil?
21
-
22
- size, scale = @facter.value('memorysize').split(' ')
23
- @memory_total = (size.to_f * MULTIPLIER[scale]).to_i
24
- end
25
-
26
- def memory_free
27
- size, scale = @facter.value('memoryfree').split(' ')
28
- (size.to_f * MULTIPLIER[scale]).to_i
29
- end
30
-
31
- def to_s
32
- "Metric::AvailableMemory(#{@weight})"
33
- end
34
- end
35
- end
36
- end
@@ -1,58 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe LitmusPaper::Metric::AvailableMemory do
4
- describe "#current_health" do
5
- it "multiplies weight by memory available" do
6
- facter = StubFacter.new({"memorysize" => "10 GB", "memoryfree" => "5 GB"})
7
- memory = LitmusPaper::Metric::AvailableMemory.new(50, facter)
8
- memory.current_health.should == 25
9
- end
10
-
11
- it "multiplies weight by memory available when handling floating point values" do
12
- facter = StubFacter.new({"memorysize" => "2.0 GB", "memoryfree" => "1.8 GB"})
13
- memory = LitmusPaper::Metric::AvailableMemory.new(50, facter)
14
- memory.current_health.should == 44
15
- end
16
-
17
- describe "#memory_total" do
18
- it "is a positive integer" do
19
- metric = LitmusPaper::Metric::AvailableMemory.new(50)
20
- metric.memory_total.should > 1_000
21
- end
22
-
23
- it "handles floating point values properly" do
24
- facter = StubFacter.new("memorysize" => "1.80 GB")
25
- memory = LitmusPaper::Metric::AvailableMemory.new(50, facter)
26
- memory.memory_total.should == 1932735283
27
- end
28
-
29
- it "is cached" do
30
- Facter.should_receive(:value).once.and_return("10 MB")
31
- metric = LitmusPaper::Metric::AvailableMemory.new(50)
32
- metric.memory_total
33
- metric.memory_total
34
- metric.memory_total
35
- end
36
- end
37
-
38
- describe "#memory_free" do
39
- it "is a positive integer" do
40
- metric = LitmusPaper::Metric::AvailableMemory.new(50)
41
- metric.memory_free.should > 100
42
- end
43
-
44
- it "handles floating point values properly" do
45
- facter = StubFacter.new("memoryfree" => "1.80 GB")
46
- memory = LitmusPaper::Metric::AvailableMemory.new(50, facter)
47
- memory.memory_free.should == 1932735283
48
- end
49
- end
50
-
51
- describe "#to_s" do
52
- it "is the name of the check and the max weight" do
53
- metric = LitmusPaper::Metric::AvailableMemory.new(50)
54
- metric.to_s.should == "Metric::AvailableMemory(50)"
55
- end
56
- end
57
- end
58
- end
@@ -1,9 +0,0 @@
1
- class StubFacter
2
- def initialize(values)
3
- @values = values
4
- end
5
-
6
- def value(key)
7
- @values[key]
8
- end
9
- end
data/xinetd.conf DELETED
@@ -1,13 +0,0 @@
1
- service internet_health
2
- {
3
- disable = no
4
- socket_type = stream
5
- protocol = tcp
6
- port = 9191
7
- user = agent-check
8
- wait = no
9
- server = /usr/bin/litmus-agent-check
10
- server_args = -s isp
11
- type = UNLISTED
12
- instances = 10
13
- }