mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-05-01 07:58:54 +00:00
add integration tests + fixes
This commit is contained in:
parent
00152dbb63
commit
816f31c19f
13 changed files with 393 additions and 25 deletions
|
|
@ -61,22 +61,22 @@ ALL_STATUS = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class StatusValue(namedtuple("Status", "status, is_pending")):
|
class StatusValue(namedtuple("Status", "value, is_pending")):
|
||||||
MISSING = 0
|
MISSING = 0
|
||||||
OK = 1
|
OK = 1
|
||||||
NOT_MONITORED = 2
|
NOT_MONITORED = 2
|
||||||
INITIALIZING = 3
|
INITIALIZING = 3
|
||||||
DOES_NOT_EXIST = 4
|
DOES_NOT_EXIST = 4
|
||||||
|
|
||||||
def __new__(cls, status, is_pending=False):
|
def __new__(cls, value, is_pending=False):
|
||||||
return super(StatusValue, cls).__new__(cls, status, is_pending)
|
return super(StatusValue, cls).__new__(cls, value, is_pending)
|
||||||
|
|
||||||
def pending(self):
|
def pending(self):
|
||||||
return StatusValue(self.status, True)
|
return StatusValue(self.value, True)
|
||||||
|
|
||||||
def __getattr__(self, item):
|
def __getattr__(self, item):
|
||||||
if item in ('is_%s' % status for status in ALL_STATUS):
|
if item in ('is_%s' % status for status in ALL_STATUS):
|
||||||
return self.status == getattr(self, item[3:].upper())
|
return self.value == getattr(self, item[3:].upper())
|
||||||
|
|
||||||
|
|
||||||
class Status(object):
|
class Status(object):
|
||||||
|
|
@ -122,22 +122,24 @@ class Monit(object):
|
||||||
return Status.MISSING
|
return Status.MISSING
|
||||||
|
|
||||||
status_val = re.findall(r"^\s*status\s*([\w\- ]+)", output, re.MULTILINE)
|
status_val = re.findall(r"^\s*status\s*([\w\- ]+)", output, re.MULTILINE)
|
||||||
if status_val:
|
if not status_val:
|
||||||
status_val = status_val[0].strip().upper()
|
self.module.fail_json(msg="Unable to find process status")
|
||||||
if ' - ' not in status_val:
|
|
||||||
status_val.replace(' ', '_')
|
|
||||||
return getattr(Status, status_val)
|
|
||||||
else:
|
|
||||||
status_val, substatus = status_val.split(' - ')
|
|
||||||
action, state = substatus.split()
|
|
||||||
if action in ['START', 'INITIALIZING', 'RESTART', 'MONITOR']:
|
|
||||||
status = Status.OK
|
|
||||||
else:
|
|
||||||
status = Status.NOT_MONITORED
|
|
||||||
|
|
||||||
if state == 'pending':
|
status_val = status_val[0].strip().upper()
|
||||||
status = status.pending()
|
if ' - ' not in status_val:
|
||||||
return status
|
status_val = status_val.replace(' ', '_')
|
||||||
|
return getattr(Status, status_val)
|
||||||
|
else:
|
||||||
|
status_val, substatus = status_val.split(' - ')
|
||||||
|
action, state = substatus.split()
|
||||||
|
if action in ['START', 'INITIALIZING', 'RESTART', 'MONITOR']:
|
||||||
|
status = Status.OK
|
||||||
|
else:
|
||||||
|
status = Status.NOT_MONITORED
|
||||||
|
|
||||||
|
if state == 'pending':
|
||||||
|
status = status.pending()
|
||||||
|
return status
|
||||||
|
|
||||||
def is_process_present(self):
|
def is_process_present(self):
|
||||||
rc, out, err = self.module.run_command('%s summary -B' % (self.monit_bin_path), check_rc=True)
|
rc, out, err = self.module.run_command('%s summary -B' % (self.monit_bin_path), check_rc=True)
|
||||||
|
|
@ -155,7 +157,12 @@ class Monit(object):
|
||||||
timeout_time = time.time() + self.timeout
|
timeout_time = time.time() + self.timeout
|
||||||
|
|
||||||
running_status = self.get_status()
|
running_status = self.get_status()
|
||||||
while running_status.is_missing or running_status.is_pending or running_status.is_initializing:
|
waiting_status = [
|
||||||
|
StatusValue.MISSING,
|
||||||
|
StatusValue.INITIALIZING,
|
||||||
|
StatusValue.DOES_NOT_EXIST,
|
||||||
|
]
|
||||||
|
while running_status.is_pending or (running_status.value in waiting_status):
|
||||||
if time.time() >= timeout_time:
|
if time.time() >= timeout_time:
|
||||||
self.module.fail_json(
|
self.module.fail_json(
|
||||||
msg='waited too long for "pending", or "initiating" status to go away ({0})'.format(
|
msg='waited too long for "pending", or "initiating" status to go away ({0})'.format(
|
||||||
|
|
@ -184,12 +191,12 @@ class Monit(object):
|
||||||
def change_state(self, state, expected_status, invert_expected=None):
|
def change_state(self, state, expected_status, invert_expected=None):
|
||||||
self.run_command(STATE_COMMAND_MAP[state])
|
self.run_command(STATE_COMMAND_MAP[state])
|
||||||
status = self.get_status()
|
status = self.get_status()
|
||||||
status_match = status.status == expected_status.status
|
status_match = status.value == expected_status.value
|
||||||
if invert_expected:
|
if invert_expected:
|
||||||
status_match = not status_match
|
status_match = not status_match
|
||||||
if status_match:
|
if status_match:
|
||||||
self.module.exit_json(changed=True, name=self.process_name, state=state)
|
self.module.exit_json(changed=True, name=self.process_name, state=state)
|
||||||
self.module.fail_json(msg='%s process not %s' % (self.process_name, state), status=status)
|
self.module.fail_json(msg='%s process not %s' % (self.process_name, state), status=repr(status))
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.change_state('stopped', Status.NOT_MONITORED)
|
self.change_state('stopped', Status.NOT_MONITORED)
|
||||||
|
|
|
||||||
1
tests/integration/targets/monit/aliases
Normal file
1
tests/integration/targets/monit/aliases
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
destructive
|
||||||
124
tests/integration/targets/monit/files/daemon.py
Normal file
124
tests/integration/targets/monit/files/daemon.py
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
"""Generic linux daemon base class for python.
|
||||||
|
http://www.jejik.com/files/examples/daemon3x.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys, os, time, atexit, signal
|
||||||
|
|
||||||
|
|
||||||
|
class Daemon:
|
||||||
|
"""A generic daemon class.
|
||||||
|
|
||||||
|
Usage: subclass the daemon class and override the run() method."""
|
||||||
|
|
||||||
|
def __init__(self, pidfile):
|
||||||
|
self.pidfile = pidfile
|
||||||
|
|
||||||
|
def daemonize(self):
|
||||||
|
"""Deamonize class. UNIX double fork mechanism."""
|
||||||
|
|
||||||
|
try:
|
||||||
|
pid = os.fork()
|
||||||
|
if pid > 0:
|
||||||
|
# exit first parent
|
||||||
|
sys.exit(0)
|
||||||
|
except OSError as err:
|
||||||
|
sys.stderr.write('fork #1 failed: {0}\n'.format(err))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# decouple from parent environment
|
||||||
|
os.chdir('/')
|
||||||
|
os.setsid()
|
||||||
|
os.umask(0)
|
||||||
|
|
||||||
|
# do second fork
|
||||||
|
try:
|
||||||
|
pid = os.fork()
|
||||||
|
if pid > 0:
|
||||||
|
# exit from second parent
|
||||||
|
sys.exit(0)
|
||||||
|
except OSError as err:
|
||||||
|
sys.stderr.write('fork #2 failed: {0}\n'.format(err))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# redirect standard file descriptors
|
||||||
|
sys.stdout.flush()
|
||||||
|
sys.stderr.flush()
|
||||||
|
si = open(os.devnull, 'r')
|
||||||
|
so = open(os.devnull, 'a+')
|
||||||
|
se = open(os.devnull, 'a+')
|
||||||
|
|
||||||
|
os.dup2(si.fileno(), sys.stdin.fileno())
|
||||||
|
os.dup2(so.fileno(), sys.stdout.fileno())
|
||||||
|
os.dup2(se.fileno(), sys.stderr.fileno())
|
||||||
|
|
||||||
|
# write pidfile
|
||||||
|
atexit.register(self.delpid)
|
||||||
|
|
||||||
|
pid = str(os.getpid())
|
||||||
|
with open(self.pidfile, 'w+') as f:
|
||||||
|
f.write(pid + '\n')
|
||||||
|
|
||||||
|
def delpid(self):
|
||||||
|
os.remove(self.pidfile)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"""Start the daemon."""
|
||||||
|
|
||||||
|
# Check for a pidfile to see if the daemon already runs
|
||||||
|
try:
|
||||||
|
with open(self.pidfile, 'r') as pf:
|
||||||
|
|
||||||
|
pid = int(pf.read().strip())
|
||||||
|
except IOError:
|
||||||
|
pid = None
|
||||||
|
|
||||||
|
if pid:
|
||||||
|
message = "pidfile {0} already exist. " + \
|
||||||
|
"Daemon already running?\n"
|
||||||
|
sys.stderr.write(message.format(self.pidfile))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Start the daemon
|
||||||
|
self.daemonize()
|
||||||
|
self.run()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
"""Stop the daemon."""
|
||||||
|
|
||||||
|
# Get the pid from the pidfile
|
||||||
|
try:
|
||||||
|
with open(self.pidfile, 'r') as pf:
|
||||||
|
pid = int(pf.read().strip())
|
||||||
|
except IOError:
|
||||||
|
pid = None
|
||||||
|
|
||||||
|
if not pid:
|
||||||
|
message = "pidfile {0} does not exist. " + \
|
||||||
|
"Daemon not running?\n"
|
||||||
|
sys.stderr.write(message.format(self.pidfile))
|
||||||
|
return # not an error in a restart
|
||||||
|
|
||||||
|
# Try killing the daemon process
|
||||||
|
try:
|
||||||
|
while 1:
|
||||||
|
os.kill(pid, signal.SIGTERM)
|
||||||
|
time.sleep(0.1)
|
||||||
|
except OSError as err:
|
||||||
|
e = str(err.args)
|
||||||
|
if e.find("No such process") > 0:
|
||||||
|
if os.path.exists(self.pidfile):
|
||||||
|
os.remove(self.pidfile)
|
||||||
|
else:
|
||||||
|
print(str(err.args))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def restart(self):
|
||||||
|
"""Restart the daemon."""
|
||||||
|
self.stop()
|
||||||
|
self.start()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
"""You should override this method when you subclass Daemon.
|
||||||
|
|
||||||
|
It will be called after the process has been daemonized by
|
||||||
|
start() or restart()."""
|
||||||
57
tests/integration/targets/monit/files/httpd_echo.py
Normal file
57
tests/integration/targets/monit/files/httpd_echo.py
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
import sys
|
||||||
|
from daemon import Daemon
|
||||||
|
|
||||||
|
try:
|
||||||
|
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
|
||||||
|
|
||||||
|
def write_to_output(stream, content):
|
||||||
|
stream.write(content)
|
||||||
|
except ImportError:
|
||||||
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
|
|
||||||
|
def write_to_output(stream, content):
|
||||||
|
stream.write(bytes(content, "utf-8"))
|
||||||
|
|
||||||
|
|
||||||
|
hostname = "localhost"
|
||||||
|
server_port = 8082
|
||||||
|
|
||||||
|
|
||||||
|
class MyServer(BaseHTTPRequestHandler):
|
||||||
|
def do_GET(self):
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header("Content-type", "text/plain")
|
||||||
|
self.end_headers()
|
||||||
|
write_to_output(self.wfile, self.path)
|
||||||
|
|
||||||
|
|
||||||
|
class MyDaemon(Daemon):
|
||||||
|
def run(self):
|
||||||
|
webServer = HTTPServer((hostname, server_port), MyServer)
|
||||||
|
print("Server started http://%s:%s" % (hostname, server_port))
|
||||||
|
|
||||||
|
try:
|
||||||
|
webServer.serve_forever()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
||||||
|
webServer.server_close()
|
||||||
|
print("Server stopped.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
daemon = MyDaemon('/tmp/httpd_echo.pid')
|
||||||
|
if len(sys.argv) == 2:
|
||||||
|
if 'start' == sys.argv[1]:
|
||||||
|
daemon.start()
|
||||||
|
elif 'stop' == sys.argv[1]:
|
||||||
|
daemon.stop()
|
||||||
|
elif 'restart' == sys.argv[1]:
|
||||||
|
daemon.restart()
|
||||||
|
else:
|
||||||
|
print("Unknown command")
|
||||||
|
sys.exit(2)
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
print("usage: %s start|stop|restart" % sys.argv[0])
|
||||||
|
sys.exit(2)
|
||||||
16
tests/integration/targets/monit/handlers/main.yml
Normal file
16
tests/integration/targets/monit/handlers/main.yml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
- name: start monit
|
||||||
|
become: yes
|
||||||
|
service: name=monit state=started
|
||||||
|
|
||||||
|
- name: restart monit
|
||||||
|
become: yes
|
||||||
|
service: name=monit state=restarted
|
||||||
|
|
||||||
|
- name: reload monit
|
||||||
|
become: yes
|
||||||
|
service: name=monit state=reloaded
|
||||||
|
|
||||||
|
- name: stop monit
|
||||||
|
become: yes
|
||||||
|
service: name=monit state=stopped
|
||||||
2
tests/integration/targets/monit/meta/main.yml
Normal file
2
tests/integration/targets/monit/meta/main.yml
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
dependencies:
|
||||||
|
- setup_pkg_mgr
|
||||||
53
tests/integration/targets/monit/tasks/main.yml
Normal file
53
tests/integration/targets/monit/tasks/main.yml
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
####################################################################
|
||||||
|
# WARNING: These are designed specifically for Ansible tests #
|
||||||
|
# and should not be used as examples of how to write Ansible roles #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: install monit
|
||||||
|
become: yes
|
||||||
|
package:
|
||||||
|
name: monit
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: monit config
|
||||||
|
become: yes
|
||||||
|
template:
|
||||||
|
src: "monitrc.j2"
|
||||||
|
dest: "/etc/monit/monitrc"
|
||||||
|
|
||||||
|
- name: process monit config
|
||||||
|
become: yes
|
||||||
|
template:
|
||||||
|
src: "httpd_echo.j2"
|
||||||
|
dest: "/etc/monit/conf.d/httpd_echo"
|
||||||
|
|
||||||
|
- name: copy process file
|
||||||
|
become: yes
|
||||||
|
copy:
|
||||||
|
src: "{{item}}"
|
||||||
|
dest: "/opt/{{item}}"
|
||||||
|
loop:
|
||||||
|
- daemon.py
|
||||||
|
- httpd_echo.py
|
||||||
|
|
||||||
|
- name: restart monit
|
||||||
|
become: yes
|
||||||
|
service:
|
||||||
|
name: monit
|
||||||
|
state: restarted
|
||||||
|
|
||||||
|
- include_tasks: test.yml
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: stop monit
|
||||||
|
become: yes
|
||||||
|
service:
|
||||||
|
name: monit
|
||||||
|
state: stopped
|
||||||
|
|
||||||
|
- name: uninstall monit
|
||||||
|
become: yes
|
||||||
|
package:
|
||||||
|
name: monit
|
||||||
|
state: absent
|
||||||
26
tests/integration/targets/monit/tasks/test.yml
Normal file
26
tests/integration/targets/monit/tasks/test.yml
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
# order is important
|
||||||
|
- import_tasks: test_state.yml
|
||||||
|
vars:
|
||||||
|
state: stopped
|
||||||
|
initial_state: up
|
||||||
|
expected_state: down
|
||||||
|
|
||||||
|
- import_tasks: test_state.yml
|
||||||
|
vars:
|
||||||
|
state: started
|
||||||
|
initial_state: down
|
||||||
|
expected_state: up
|
||||||
|
|
||||||
|
- import_tasks: test_state.yml
|
||||||
|
vars:
|
||||||
|
state: unmonitored
|
||||||
|
initial_state: up
|
||||||
|
expected_state: down
|
||||||
|
|
||||||
|
- import_tasks: test_state.yml
|
||||||
|
vars:
|
||||||
|
state: monitored
|
||||||
|
initial_state: down
|
||||||
|
expected_state: up
|
||||||
|
|
||||||
|
- import_tasks: test_errors.yml
|
||||||
6
tests/integration/targets/monit/tasks/test_errors.yml
Normal file
6
tests/integration/targets/monit/tasks/test_errors.yml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
- name: Check an error occurs when wrong process name is used
|
||||||
|
monit:
|
||||||
|
name: missing
|
||||||
|
state: started
|
||||||
|
register: result
|
||||||
|
failed_when: result is not skip and (result is success or result is not failed)
|
||||||
51
tests/integration/targets/monit/tasks/test_state.yml
Normal file
51
tests/integration/targets/monit/tasks/test_state.yml
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
- name: verify initial state (up)
|
||||||
|
command: "curl -sf http://localhost:8082/hello"
|
||||||
|
args:
|
||||||
|
warn: false
|
||||||
|
when: initial_state == 'up'
|
||||||
|
|
||||||
|
- name: verify initial state (down)
|
||||||
|
command: "curl -sf http://localhost:8082/hello"
|
||||||
|
args:
|
||||||
|
warn: false
|
||||||
|
register: curl_result
|
||||||
|
failed_when: curl_result == 0
|
||||||
|
when: initial_state == 'down'
|
||||||
|
|
||||||
|
- name: change httpd_echo process state to {{ state }}
|
||||||
|
monit:
|
||||||
|
name: httpd_echo
|
||||||
|
state: "{{ state }}"
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check that state changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is success
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: check that service is {{ state }} (expected 'up')
|
||||||
|
command: "curl -sf http://localhost:8082/hello"
|
||||||
|
args:
|
||||||
|
warn: false
|
||||||
|
when: expected_state == 'up'
|
||||||
|
|
||||||
|
- name: check that service is {{ state }} (expected 'down')
|
||||||
|
command: "curl -sf http://localhost:8082/hello"
|
||||||
|
args:
|
||||||
|
warn: false
|
||||||
|
register: curl_result
|
||||||
|
failed_when: curl_result == 0
|
||||||
|
when: expected_state == 'down'
|
||||||
|
|
||||||
|
- name: try change state again to {{ state }}
|
||||||
|
monit:
|
||||||
|
name: httpd_echo
|
||||||
|
state: "{{ state }}"
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check that state is not changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is success
|
||||||
|
- result is not changed
|
||||||
4
tests/integration/targets/monit/templates/httpd_echo.j2
Normal file
4
tests/integration/targets/monit/templates/httpd_echo.j2
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
check process httpd_echo with pidfile /tmp/httpd_echo.pid
|
||||||
|
start program = "{{ansible_python.executable}} /opt/httpd_echo.py start"
|
||||||
|
stop program = "{{ansible_python.executable}} /opt/httpd_echo.py stop"
|
||||||
|
if failed host localhost port 8082 then restart
|
||||||
14
tests/integration/targets/monit/templates/monitrc.j2
Normal file
14
tests/integration/targets/monit/templates/monitrc.j2
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
set daemon 2
|
||||||
|
set logfile /var/log/monit.log
|
||||||
|
set idfile /var/lib/monit/id
|
||||||
|
set statefile /var/lib/monit/state
|
||||||
|
|
||||||
|
set eventqueue
|
||||||
|
basedir /var/lib/monit/events
|
||||||
|
slots 100
|
||||||
|
|
||||||
|
set httpd port 2812 and
|
||||||
|
use address localhost
|
||||||
|
allow localhost
|
||||||
|
|
||||||
|
include /etc/monit/conf.d/*
|
||||||
|
|
@ -55,16 +55,21 @@ class MonitTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_reload(self):
|
def test_reload(self):
|
||||||
self.module.run_command.return_value = (0, '', '')
|
self.module.run_command.return_value = (0, '', '')
|
||||||
|
with self.patch_status(monit.Status.OK) as get_status:
|
||||||
|
with self.assertRaises(AnsibleExitJson):
|
||||||
|
self.monit.reload()
|
||||||
|
|
||||||
|
def test_wait_for_status(self):
|
||||||
self.monit._sleep_time = 0
|
self.monit._sleep_time = 0
|
||||||
status = [
|
status = [
|
||||||
monit.Status.MISSING,
|
monit.Status.MISSING,
|
||||||
|
monit.Status.DOES_NOT_EXIST,
|
||||||
monit.Status.INITIALIZING,
|
monit.Status.INITIALIZING,
|
||||||
monit.Status.OK.pending(),
|
monit.Status.OK.pending(),
|
||||||
monit.Status.OK
|
monit.Status.OK
|
||||||
]
|
]
|
||||||
with self.patch_status(status) as get_status:
|
with self.patch_status(status) as get_status:
|
||||||
with self.assertRaises(AnsibleExitJson):
|
self.monit.wait_for_monit_to_stop_pending('ok')
|
||||||
self.monit.reload()
|
|
||||||
self.assertEqual(get_status.call_count, len(status))
|
self.assertEqual(get_status.call_count, len(status))
|
||||||
|
|
||||||
def test_monitor(self):
|
def test_monitor(self):
|
||||||
|
|
@ -105,6 +110,8 @@ BASIC_OUTPUT_CASES = [
|
||||||
(TEST_OUTPUT % ('processX', 'Monitored - stop pending'), monit.Status.NOT_MONITORED),
|
(TEST_OUTPUT % ('processX', 'Monitored - stop pending'), monit.Status.NOT_MONITORED),
|
||||||
(TEST_OUTPUT % ('processX', 'Monitored - restart pending'), monit.Status.OK),
|
(TEST_OUTPUT % ('processX', 'Monitored - restart pending'), monit.Status.OK),
|
||||||
(TEST_OUTPUT % ('processX', 'Not Monitored - monitor pending'), monit.Status.OK),
|
(TEST_OUTPUT % ('processX', 'Not Monitored - monitor pending'), monit.Status.OK),
|
||||||
|
(TEST_OUTPUT % ('processX', 'Does not exist'), monit.Status.DOES_NOT_EXIST),
|
||||||
|
(TEST_OUTPUT % ('processX', 'Not monitored'), monit.Status.NOT_MONITORED),
|
||||||
])
|
])
|
||||||
def test_parse_status(output, expected):
|
def test_parse_status(output, expected):
|
||||||
status = monit.Monit(None, '', 'processX', 0)._parse_status(output)
|
status = monit.Monit(None, '', 'processX', 0)._parse_status(output)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue