litmus_paper 0.9.6 → 0.9.7

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.
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
- }