mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-25 14:44:32 +02:00
Merge branch 'feature/unit-tests-5223' into next
This commit is contained in:
commit
eb4afb1eda
@ -16,3 +16,8 @@ file { '/etc/motd':
|
|||||||
owner => root,
|
owner => root,
|
||||||
group => root
|
group => root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user { 'vagrant':
|
||||||
|
groups => 'icingacmd',
|
||||||
|
require => Group['icingacmd']
|
||||||
|
}
|
||||||
|
@ -1 +1,43 @@
|
|||||||
These scripts are used by build.icinga.org to set up a test VM.
|
Set of scripts to set up and test a virtual demo machine
|
||||||
|
========================================================
|
||||||
|
|
||||||
|
This directory contains a few scripts primarily used by build.icinga.org.
|
||||||
|
|
||||||
|
* bootstrap-vm.sh
|
||||||
|
Ensures that all required software is installed and its configuration
|
||||||
|
is applied to the VM. (Usually not of interest for the typical user.)
|
||||||
|
|
||||||
|
* run_tests.sh
|
||||||
|
This is a wrapper script intended to be ran manually by a user. (Note
|
||||||
|
that you need to start this project's vagrant box for this to work!)
|
||||||
|
|
||||||
|
* run_tests.py
|
||||||
|
The actual test-runner. Accepts two options (-C|--config, -O|--output) and
|
||||||
|
expects one or more filenames or -patterns that should be run on the VM.
|
||||||
|
|
||||||
|
* run_tests.conf
|
||||||
|
The default configuration file for the test-runner. (Used when running
|
||||||
|
the wrapper script or when no custom configuration file is passed to the
|
||||||
|
test-runner.)
|
||||||
|
|
||||||
|
Format:
|
||||||
|
- commands: This section is mandatory and contains the commands to use.
|
||||||
|
- settings: This section is mandatory and defines settings that are applied to
|
||||||
|
all tests.
|
||||||
|
- setups: This section is optional and contains setup routines that should
|
||||||
|
be ran before (setup) and after (teardown) any matching test is
|
||||||
|
executed. (Note that only one setup can be effective at a time.)
|
||||||
|
|
||||||
|
Example:
|
||||||
|
"^v[1-9]\.test$": {
|
||||||
|
"setup": {
|
||||||
|
"copy": ["source >> target"], // Files that should be copied.
|
||||||
|
// Note that these files remain
|
||||||
|
// if not removed explicitly
|
||||||
|
"clean": ["target"], // Files to delete from the system
|
||||||
|
"exec": ["cmd1", "cmd2"] // Commands to execute on the system
|
||||||
|
},
|
||||||
|
"teardown": {
|
||||||
|
// The same kind of instructions as above can be added here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
3
test/jenkins/apache_state.test
Executable file
3
test/jenkins/apache_state.test
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
sudo service httpd status
|
@ -1,14 +1,29 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
if [ "$1" != "run-by-jenkins" ]; then
|
if [ "$1" != "--force" ]; then
|
||||||
echo "This script should not be run manually."
|
echo 'This script is NOT intended to be ran by an individual user.' \
|
||||||
exit 1
|
'If you are not human, pass "--force" as the first option to it!'
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "10.10.27.1 packages.icinga.org" >> /etc/hosts
|
if [ $# -lt 3 ]; then
|
||||||
|
echo 'Too few arguments. You need to pass "--force <user> <host>"' \
|
||||||
|
'to run this script.'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
groupadd vagrant
|
|
||||||
|
|
||||||
rmdir /vagrant && ln -s /root/icinga2 /vagrant
|
user=$2
|
||||||
puppet apply --modulepath=/vagrant/.vagrant-puppet/modules /vagrant/.vagrant-puppet/manifests/default.pp
|
host=$3
|
||||||
|
|
||||||
|
SSH_OPTIONS="-o PasswordAuthentication=no"
|
||||||
|
SSH="ssh $SSH_OPTIONS $user@$host"
|
||||||
|
|
||||||
|
$SSH "mkdir /vagrant"
|
||||||
|
scp -qr ../../.vagrant-puppet $user@$host:/vagrant
|
||||||
|
|
||||||
|
$SSH "groupadd vagrant"
|
||||||
|
$SSH "echo '10.10.27.1 packages.icinga.org' >> /etc/hosts"
|
||||||
|
$SSH "puppet apply --modulepath=/vagrant/.vagrant-puppet/modules" \
|
||||||
|
" /vagrant/.vagrant-puppet/manifests/default.pp"
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
87
test/jenkins/checkresult.test
Executable file
87
test/jenkins/checkresult.test
Executable file
@ -0,0 +1,87 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
import utils
|
||||||
|
|
||||||
|
|
||||||
|
STATE_OK = 0
|
||||||
|
TYPE_PASSIVE_CHECK = 1
|
||||||
|
|
||||||
|
CHECK_INTERVAL = 300 # seconds
|
||||||
|
CHECKRESULT_READ_INTERVAL = 5 # seconds
|
||||||
|
CHECKRESULT_LOCATION = '/tmp/icinga2/checkresults'
|
||||||
|
CHECKRESULT_TEMPLATE = """
|
||||||
|
host_name=%(hostname)s
|
||||||
|
service_description=%(servicename)s
|
||||||
|
check_type=%(check_type)s
|
||||||
|
check_options=0
|
||||||
|
scheduled_check=0
|
||||||
|
reschedule_check=0
|
||||||
|
latency=0
|
||||||
|
start_time=%(start_time)s
|
||||||
|
finish_time=%(finish_time)s
|
||||||
|
early_timeout=0
|
||||||
|
exited_ok=%(excited_ok)s
|
||||||
|
return_code=%(return_code)s
|
||||||
|
output=%(output)s
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
run_query = lambda q: utils.run_mysql_query(q, b'/usr/bin/mysql')
|
||||||
|
|
||||||
|
# We need to wait a bit first as Icinga processes a
|
||||||
|
# checkresult only if its newer than the last check
|
||||||
|
query = 'select unix_timestamp(s.last_check) as last_check ' \
|
||||||
|
'from icinga_servicestatus as s ' \
|
||||||
|
'inner join icinga_services as c ' \
|
||||||
|
'on s.service_object_id = c.service_object_id ' \
|
||||||
|
"where c.display_name = 'PassiveService1'"
|
||||||
|
state_time = float(next(iter(run_query(query)), {}).get('last_check', '0'))
|
||||||
|
if state_time == 0:
|
||||||
|
print '"PassiveService1" seems not to have been checked yet'
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if (state_time + CHECK_INTERVAL) - time.time() < 30:
|
||||||
|
time.sleep(45)
|
||||||
|
|
||||||
|
# Now pass the checkresult in
|
||||||
|
with open(os.path.join(CHECKRESULT_LOCATION, 'cfoobar'), 'w') as f:
|
||||||
|
f.write(CHECKRESULT_TEMPLATE % {
|
||||||
|
'hostname': 'nsca-ng',
|
||||||
|
'servicename': 'PassiveService1',
|
||||||
|
'check_type': TYPE_PASSIVE_CHECK,
|
||||||
|
'start_time': time.time(),
|
||||||
|
'finish_time': time.time(),
|
||||||
|
'excited_ok': '1',
|
||||||
|
'return_code': STATE_OK,
|
||||||
|
'output': 'Passing in CheckResult header files works!'
|
||||||
|
})
|
||||||
|
|
||||||
|
# And notfiy Icinga that the file has been completely written...
|
||||||
|
with open(os.path.join(CHECKRESULT_LOCATION, 'cfoobar.ok'), 'w') as f:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Lastly check whether the service changed its state
|
||||||
|
time.sleep(CHECKRESULT_READ_INTERVAL * 2)
|
||||||
|
|
||||||
|
query = 'select s.output ' \
|
||||||
|
'from icinga_servicestatus as s ' \
|
||||||
|
'inner join icinga_services as c ' \
|
||||||
|
'on s.service_object_id = c.service_object_id ' \
|
||||||
|
"where c.display_name = 'PassiveService1'"
|
||||||
|
output = next(iter(run_query(query)), {}).get('output', '')
|
||||||
|
if output != 'Passing in CheckResult header files works!':
|
||||||
|
print 'Checkresult header files seem not to be processed properly'
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print 'Checkresult header files are processed properly'
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
10
test/jenkins/external_commandpipe.test
Executable file
10
test/jenkins/external_commandpipe.test
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ -e "/var/run/icinga2/cmd/icinga2.cmd" ];
|
||||||
|
then
|
||||||
|
echo "Icinga2 commandpipe found"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Icinga2 commandpipe not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
5
test/jenkins/files/configs/checkresult.conf
Normal file
5
test/jenkins/files/configs/checkresult.conf
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
library "compat"
|
||||||
|
|
||||||
|
object CheckResultReader "reader" {
|
||||||
|
spool_dir = "/tmp/icinga2/checkresults"
|
||||||
|
}
|
190
test/jenkins/files/ido_tests.py
Normal file
190
test/jenkins/files/ido_tests.py
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
CHECK_INTERVAL = 10 # minutes; The actual interval are 5 minutes but as other
|
||||||
|
# tests might restart Icinga we need to take any
|
||||||
|
# rescheduling into account
|
||||||
|
|
||||||
|
TABLE_PREFIX = 'icinga_'
|
||||||
|
TABLES = [
|
||||||
|
# Central tables
|
||||||
|
'instances',
|
||||||
|
'objects',
|
||||||
|
# Debugging tables
|
||||||
|
'conninfo',
|
||||||
|
# Historical tables
|
||||||
|
'acknowledgements',
|
||||||
|
'commenthistory',
|
||||||
|
'contactnotifications',
|
||||||
|
'dbversion',
|
||||||
|
'downtimehistory',
|
||||||
|
'eventhandlers',
|
||||||
|
'externalcommands',
|
||||||
|
'flappinghistory',
|
||||||
|
'hostchecks',
|
||||||
|
'logentries',
|
||||||
|
'notifications',
|
||||||
|
'processevents',
|
||||||
|
'servicechecks',
|
||||||
|
'statehistory',
|
||||||
|
'systemcommands',
|
||||||
|
# Current status tables
|
||||||
|
'comments',
|
||||||
|
'customvariablestatus',
|
||||||
|
'hoststatus',
|
||||||
|
'programstatus',
|
||||||
|
'runtimevariables',
|
||||||
|
'scheduleddowntime',
|
||||||
|
'servicestatus',
|
||||||
|
'contactstatus',
|
||||||
|
# Configuration tables
|
||||||
|
'commands',
|
||||||
|
'configfiles',
|
||||||
|
'configfilevariables',
|
||||||
|
'contact_addresses',
|
||||||
|
'contact_notificationcommands',
|
||||||
|
'contactgroup_members',
|
||||||
|
'contactgroups',
|
||||||
|
'contactnotificationmethods',
|
||||||
|
'contacts',
|
||||||
|
'customvariables',
|
||||||
|
'host_contactgroups',
|
||||||
|
'host_contacts',
|
||||||
|
'host_parenthosts',
|
||||||
|
'hostdependencies',
|
||||||
|
'hostescalation_contactgroups',
|
||||||
|
'hostescalation_contacts',
|
||||||
|
'hostescalations',
|
||||||
|
'hostgroup_members',
|
||||||
|
'hostgroups',
|
||||||
|
'hosts',
|
||||||
|
'service_contactgroups',
|
||||||
|
'service_contacts',
|
||||||
|
'servicedependencies',
|
||||||
|
'serviceescalation_contactgroups',
|
||||||
|
'serviceescalation_contacts',
|
||||||
|
'serviceescalations',
|
||||||
|
'servicegroup_members',
|
||||||
|
'servicegroups',
|
||||||
|
'services',
|
||||||
|
'timeperiod_timeranges',
|
||||||
|
'timeperiods'
|
||||||
|
]
|
||||||
|
EXAMPLE_CONFIG = {
|
||||||
|
'localhost': ['disk', 'http', 'icinga', 'load', 'ping4',
|
||||||
|
'ping6', 'processes', 'ssh', 'users'],
|
||||||
|
'nsca-ng': ['PassiveService1', 'PassiveService2']
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def validate_tables(tables):
|
||||||
|
"""
|
||||||
|
Return whether all tables of the IDO database scheme exist in
|
||||||
|
the given table listing
|
||||||
|
|
||||||
|
"""
|
||||||
|
missing = [n for n in TABLES if TABLE_PREFIX + n not in tables]
|
||||||
|
if missing:
|
||||||
|
print 'Some tables are missing in the IDO'
|
||||||
|
print 'Missing tables: ' + ', '.join(missing)
|
||||||
|
return False
|
||||||
|
|
||||||
|
print 'All tables were found in the IDO'
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def verify_host_config(config_data):
|
||||||
|
"""
|
||||||
|
Return whether the example hosts exist in the given "hosts" table
|
||||||
|
|
||||||
|
"""
|
||||||
|
if len([1 for e in config_data if e['alias'] in EXAMPLE_CONFIG]) == 2:
|
||||||
|
print 'All example hosts are stored in the IDO'
|
||||||
|
return True
|
||||||
|
|
||||||
|
print 'Some example hosts are missing in the IDO'
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def verify_service_config(config_data):
|
||||||
|
"""
|
||||||
|
Return whether the example services exist in the given "services" table
|
||||||
|
|
||||||
|
"""
|
||||||
|
for hostname, servicename in ((h, s) for h, ss in EXAMPLE_CONFIG.iteritems()
|
||||||
|
for s in ss):
|
||||||
|
# Not very efficient, but suitable for just two hosts...
|
||||||
|
if not any(1 for c in config_data
|
||||||
|
if c['alias'] == hostname and
|
||||||
|
c['display_name'] == servicename):
|
||||||
|
print 'The config stored in the IDO is missing some services'
|
||||||
|
return False
|
||||||
|
|
||||||
|
print 'The service config stored in the IDO is correct'
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def check_last_host_status_update(check_info):
|
||||||
|
"""
|
||||||
|
Return whether the example hosts are checked as scheduled
|
||||||
|
|
||||||
|
"""
|
||||||
|
for info in check_info:
|
||||||
|
if info['alias'] == 'localhost':
|
||||||
|
last_check = datetime.fromtimestamp(float(info['last_check']))
|
||||||
|
if datetime.now() - last_check > timedelta(minutes=CHECK_INTERVAL,
|
||||||
|
seconds=10):
|
||||||
|
print 'The last status update of host "localhost"' \
|
||||||
|
' was more than {0} minutes ago'.format(CHECK_INTERVAL)
|
||||||
|
return False
|
||||||
|
elif info['alias'] == 'nsca-ng':
|
||||||
|
if float(info['last_check']) > 0:
|
||||||
|
print 'The host "nsca-ng" was checked even though' \
|
||||||
|
' it should not be actively checked'
|
||||||
|
return False
|
||||||
|
|
||||||
|
print 'The updates of both example hosts are processed as configured'
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def check_last_service_status_update(check_info):
|
||||||
|
"""
|
||||||
|
Return whether the example services are checked as scheduled
|
||||||
|
|
||||||
|
"""
|
||||||
|
for info in check_info:
|
||||||
|
if info['display_name'] in EXAMPLE_CONFIG.get(info['alias'], []):
|
||||||
|
last_check = datetime.fromtimestamp(float(info['last_check']))
|
||||||
|
if datetime.now() - last_check > timedelta(minutes=CHECK_INTERVAL,
|
||||||
|
seconds=10):
|
||||||
|
print 'The last status update of service "{0}" of' \
|
||||||
|
' host "{1}" was more than {2} minutes ago' \
|
||||||
|
''.format(info['display_name'], info['alias'],
|
||||||
|
CHECK_INTERVAL)
|
||||||
|
return False
|
||||||
|
|
||||||
|
print 'The updates of all example services are processed as configured'
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def check_logentries(logentry_info):
|
||||||
|
"""
|
||||||
|
Return whether the given logentry originates from host "localhost"
|
||||||
|
and refers to its very last hard status change
|
||||||
|
|
||||||
|
"""
|
||||||
|
if logentry_info and logentry_info[0]['alias'] == 'localhost':
|
||||||
|
entry_time = datetime.fromtimestamp(float(logentry_info[0]['entry_time']))
|
||||||
|
state_time = datetime.fromtimestamp(float(logentry_info[0]['state_time']))
|
||||||
|
if entry_time - state_time > timedelta(seconds=10):
|
||||||
|
print 'The last hard state of host "localhost"' \
|
||||||
|
' seems not to have been logged'
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
print 'No logs found in the IDO for host "localhost"'
|
||||||
|
return False
|
||||||
|
|
||||||
|
print 'The last hard state of host "localhost" was properly logged'
|
||||||
|
return True
|
||||||
|
|
145
test/jenkins/files/utils.py
Normal file
145
test/jenkins/files/utils.py
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import socket
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
__all__ = ['parse_statusdata', 'run_mysql_query', 'run_pgsql_query',
|
||||||
|
'LiveStatusSocket']
|
||||||
|
|
||||||
|
|
||||||
|
MYSQL_PARAMS = b"-t -D icinga -u icinga --password=icinga -e".split()
|
||||||
|
MYSQL_SEPARATOR = '|'
|
||||||
|
|
||||||
|
PGSQL_PARAMS = b"-nq -U icinga -d icinga -c".split()
|
||||||
|
PGSQL_SEPARATOR = '|'
|
||||||
|
PGSQL_ENVIRONMENT = {
|
||||||
|
b'PGPASSWORD': b'icinga'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def parse_statusdata(data, intelligent_cast=True):
|
||||||
|
parsed_data, data_type, type_data = {}, '', {}
|
||||||
|
for line in (l for l in data.split(os.linesep)
|
||||||
|
if l and not l.startswith('#')):
|
||||||
|
if '{' in line:
|
||||||
|
data_type = line.partition('{')[0].strip()
|
||||||
|
elif '}' in line:
|
||||||
|
parsed_data.setdefault(data_type, []).append(type_data)
|
||||||
|
else:
|
||||||
|
key, _, value = line.partition('=')
|
||||||
|
|
||||||
|
if intelligent_cast:
|
||||||
|
value = _cast_status_value(value)
|
||||||
|
|
||||||
|
type_data[key.strip()] = value
|
||||||
|
|
||||||
|
return parsed_data
|
||||||
|
|
||||||
|
|
||||||
|
def _cast_status_value(value):
|
||||||
|
try:
|
||||||
|
return int(value)
|
||||||
|
except ValueError:
|
||||||
|
try:
|
||||||
|
return float(value)
|
||||||
|
except ValueError:
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def run_mysql_query(query, path):
|
||||||
|
p = subprocess.Popen([path] + MYSQL_PARAMS + [query.encode('utf-8')],
|
||||||
|
stdout=subprocess.PIPE)
|
||||||
|
return _parse_mysql_result([l.decode('utf-8') for l in p.stdout.readlines()])
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_mysql_result(resultset):
|
||||||
|
result, header = [], None
|
||||||
|
for line in (l for l in resultset if MYSQL_SEPARATOR in l):
|
||||||
|
columns = [c.strip() for c in line[1:-3].split(MYSQL_SEPARATOR)]
|
||||||
|
if header is None:
|
||||||
|
header = columns
|
||||||
|
else:
|
||||||
|
result.append(dict((header[i], v) for i, v in enumerate(columns)))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def run_pgsql_query(query, path):
|
||||||
|
p = subprocess.Popen([path] + PGSQL_PARAMS + [query.encode('utf-8')],
|
||||||
|
stdout=subprocess.PIPE, env=PGSQL_ENVIRONMENT)
|
||||||
|
return _parse_pgsql_result([l.decode('utf-8') for l in p.stdout.readlines()])
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_pgsql_result(resultset):
|
||||||
|
result, header = [], None
|
||||||
|
for line in (l for l in resultset if PGSQL_SEPARATOR in l):
|
||||||
|
columns = [c.strip() for c in line.split(PGSQL_SEPARATOR)]
|
||||||
|
if header is None:
|
||||||
|
header = columns
|
||||||
|
else:
|
||||||
|
result.append(dict((header[i], v) for i, v in enumerate(columns)))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class LiveStatusError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class LiveStatusSocket(object):
|
||||||
|
options = [
|
||||||
|
'KeepAlive: on',
|
||||||
|
'OutputFormat: json',
|
||||||
|
'ResponseHeader: fixed16'
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self, path):
|
||||||
|
self.path = path
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.connect()
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_value, tb):
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
|
self.sock.connect(self.path)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.sock.shutdown(socket.SHUT_RDWR)
|
||||||
|
self.sock.close()
|
||||||
|
|
||||||
|
def query(self, command):
|
||||||
|
self.send(command)
|
||||||
|
statuscode, response = self.recv()
|
||||||
|
|
||||||
|
if statuscode != 200:
|
||||||
|
raise LiveStatusError(statuscode, response)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
def send(self, query):
|
||||||
|
full_query = '\n'.join([query] + self.options)
|
||||||
|
self.sock.sendall((full_query + '\n\n').encode('utf-8'))
|
||||||
|
|
||||||
|
def recv(self):
|
||||||
|
response = b''
|
||||||
|
response_header = self.sock.recv(16)
|
||||||
|
response_code = int(response_header[:3])
|
||||||
|
response_length = int(response_header[3:].strip())
|
||||||
|
|
||||||
|
if response_length > 0:
|
||||||
|
while len(response) < response_length:
|
||||||
|
response += self.sock.recv(response_length - len(response))
|
||||||
|
|
||||||
|
response = response.decode('utf-8')
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = json.loads(response)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return response_code, response
|
||||||
|
|
38
test/jenkins/files/wait_for_ido.sh
Executable file
38
test/jenkins/files/wait_for_ido.sh
Executable file
@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
TIMEOUT=30
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
mysql)
|
||||||
|
TYPE='MySQL'
|
||||||
|
CMD='/usr/bin/mysql -t -D icinga -u icinga --password=icinga -e'
|
||||||
|
;;
|
||||||
|
pgsql)
|
||||||
|
TYPE='PostgreSQL'
|
||||||
|
CMD='/usr/bin/psql -nq -U icinga -d icinga -c'
|
||||||
|
export PGPASSWORD='icinga'
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "No IDO type specifier given!"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
tries=1
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
out="`$CMD 'select * from icinga_hosts'`"
|
||||||
|
|
||||||
|
if [ $tries -lt $TIMEOUT ] && [ "$out" == "" ];
|
||||||
|
then
|
||||||
|
sleep 1
|
||||||
|
tries=$(($tries + 1))
|
||||||
|
else
|
||||||
|
if [ $tries -eq $TIMEOUT ];
|
||||||
|
then
|
||||||
|
echo "IDO ($TYPE) does not have any hosts or is not responding" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
3
test/jenkins/icinga2_state.test
Executable file
3
test/jenkins/icinga2_state.test
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
sudo service icinga2 status
|
67
test/jenkins/ido_mysql.test
Executable file
67
test/jenkins/ido_mysql.test
Executable file
@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import utils
|
||||||
|
import ido_tests
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
run_query = lambda q: utils.run_mysql_query(q, b'/usr/bin/mysql')
|
||||||
|
|
||||||
|
if not ido_tests.validate_tables([d['Tables_in_icinga']
|
||||||
|
for d in run_query('show tables')]):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
host_info = run_query('select * from icinga_hosts')
|
||||||
|
if not ido_tests.verify_host_config(host_info):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
service_info = run_query(
|
||||||
|
'select c2.alias, c1.* from icinga_services as c1 '
|
||||||
|
'inner join icinga_hosts as c2'
|
||||||
|
' on c1.host_object_id = c2.host_object_id'
|
||||||
|
)
|
||||||
|
if not ido_tests.verify_service_config(service_info):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
hostchecks_data = run_query(
|
||||||
|
'select c.alias, unix_timestamp(s.last_check) as last_check'
|
||||||
|
' from icinga_hoststatus as s '
|
||||||
|
'inner join icinga_hosts as c'
|
||||||
|
' on s.host_object_id = c.host_object_id'
|
||||||
|
)
|
||||||
|
if not ido_tests.check_last_host_status_update(hostchecks_data):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
servicechecks_data = run_query(
|
||||||
|
'select c2.alias, c1.display_name, unix_timestamp(s.last_check) as last_check'
|
||||||
|
' from icinga_servicestatus as s '
|
||||||
|
'inner join icinga_services as c1'
|
||||||
|
' on s.service_object_id = c1.service_object_id '
|
||||||
|
'inner join icinga_hosts as c2'
|
||||||
|
' on c1.host_object_id = c2.host_object_id'
|
||||||
|
)
|
||||||
|
if not ido_tests.check_last_service_status_update(servicechecks_data):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
logentry_info = run_query(
|
||||||
|
'select hosts.alias,'
|
||||||
|
' max(unix_timestamp(logs.entry_time)) as entry_time,'
|
||||||
|
' max(unix_timestamp(hist.state_time)) as state_time'
|
||||||
|
' from icinga_logentries as logs '
|
||||||
|
'inner join icinga_hosts as hosts'
|
||||||
|
' on logs.object_id = hosts.host_object_id and hosts.alias = "localhost" '
|
||||||
|
'inner join icinga_statehistory as hist'
|
||||||
|
' on hist.object_id = hosts.host_object_id and hist.state_type = 1'
|
||||||
|
)
|
||||||
|
if not ido_tests.check_logentries(logentry_info):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
||||||
|
|
69
test/jenkins/ido_pgsql.test
Executable file
69
test/jenkins/ido_pgsql.test
Executable file
@ -0,0 +1,69 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import utils
|
||||||
|
import ido_tests
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
run_query = lambda q: utils.run_pgsql_query(q, b'/usr/bin/psql')
|
||||||
|
|
||||||
|
if not ido_tests.validate_tables([d['Name'] for d in run_query('\\dt')
|
||||||
|
if d['Type'] == 'table']):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
host_info = run_query('select * from icinga_hosts')
|
||||||
|
if not ido_tests.verify_host_config(host_info):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
service_info = run_query(
|
||||||
|
'select c2.alias, c1.* from icinga_services as c1 '
|
||||||
|
'inner join icinga_hosts as c2'
|
||||||
|
' on c1.host_object_id = c2.host_object_id'
|
||||||
|
)
|
||||||
|
if not ido_tests.verify_service_config(service_info):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
hostchecks_data = run_query(
|
||||||
|
'select c.alias, unix_timestamp(s.last_check) as last_check'
|
||||||
|
' from icinga_hoststatus as s '
|
||||||
|
'inner join icinga_hosts as c'
|
||||||
|
' on s.host_object_id = c.host_object_id'
|
||||||
|
)
|
||||||
|
if not ido_tests.check_last_host_status_update(hostchecks_data):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
servicechecks_data = run_query(
|
||||||
|
'select c2.alias, c1.display_name, unix_timestamp(s.last_check) as last_check'
|
||||||
|
' from icinga_servicestatus as s '
|
||||||
|
'inner join icinga_services as c1'
|
||||||
|
' on s.service_object_id = c1.service_object_id '
|
||||||
|
'inner join icinga_hosts as c2'
|
||||||
|
' on c1.host_object_id = c2.host_object_id'
|
||||||
|
)
|
||||||
|
if not ido_tests.check_last_service_status_update(servicechecks_data):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
logentry_info = run_query(
|
||||||
|
'select hosts.alias,'
|
||||||
|
' max(unix_timestamp(logs.entry_time)) as entry_time,'
|
||||||
|
' max(unix_timestamp(hist.state_time)) as state_time'
|
||||||
|
' from icinga_logentries as logs '
|
||||||
|
'inner join icinga_hosts as hosts'
|
||||||
|
' on logs.object_id = hosts.host_object_id '
|
||||||
|
'inner join icinga_statehistory as hist'
|
||||||
|
' on hist.object_id = hosts.host_object_id '
|
||||||
|
"where hosts.alias = 'localhost' and hist.state_type = 1 "
|
||||||
|
'group by hosts.alias'
|
||||||
|
)
|
||||||
|
if not ido_tests.check_logentries(logentry_info):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
||||||
|
|
17
test/jenkins/livestatus_socket.test
Executable file
17
test/jenkins/livestatus_socket.test
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ ! -e /var/run/icinga2/cmd/livestatus ];
|
||||||
|
then
|
||||||
|
sudo icinga2-enable-feature livestatus 1> /dev/null
|
||||||
|
sudo service icinga2 restart 1> /dev/null
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
if [ ! -e /var/run/icinga2/cmd/livestatus ];
|
||||||
|
then
|
||||||
|
echo "Icinga2 Livestatus socket not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Icinga2 Livestatus socket found"
|
||||||
|
exit 0
|
10
test/jenkins/logfile.test
Executable file
10
test/jenkins/logfile.test
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if sudo test -f /var/log/icinga2/icinga2.log;
|
||||||
|
then
|
||||||
|
echo "Icinga2 log file found"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Icinga2 log file not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
3
test/jenkins/mysql_state.test
Executable file
3
test/jenkins/mysql_state.test
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
sudo service mysqld status
|
3
test/jenkins/pgsql_state.test
Executable file
3
test/jenkins/pgsql_state.test
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
sudo service postgresql status
|
10
test/jenkins/pidfile.test
Executable file
10
test/jenkins/pidfile.test
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ -f /var/run/icinga2/icinga2.pid ];
|
||||||
|
then
|
||||||
|
echo "Icinga2 pidfile found"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Icinga2 pidfile not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
@ -1,34 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
import sys
|
|
||||||
from xml.dom.minidom import getDOMImplementation
|
|
||||||
from subprocess import Popen, PIPE
|
|
||||||
|
|
||||||
impl = getDOMImplementation()
|
|
||||||
result = impl.createDocument(None, "testsuite", None)
|
|
||||||
testsuite = result.documentElement
|
|
||||||
|
|
||||||
for fn in sys.argv[1:]:
|
|
||||||
process = Popen(["./" + fn], stdout=PIPE, stderr=PIPE)
|
|
||||||
(stdoutdata, stderrdata) = process.communicate()
|
|
||||||
|
|
||||||
testcase = result.createElement("testcase")
|
|
||||||
testcase.setAttribute("classname", "vm")
|
|
||||||
testcase.setAttribute("name", fn)
|
|
||||||
|
|
||||||
systemout = result.createElement("system-out")
|
|
||||||
systemout.appendChild(result.createTextNode(stdoutdata))
|
|
||||||
testcase.appendChild(systemout)
|
|
||||||
|
|
||||||
systemerr = result.createElement("system-err")
|
|
||||||
systemerr.appendChild(result.createTextNode(stderrdata))
|
|
||||||
testcase.appendChild(systemerr)
|
|
||||||
|
|
||||||
if process.returncode != 0:
|
|
||||||
failure = result.createElement("failure")
|
|
||||||
failure.setAttribute("type", "returncode")
|
|
||||||
failure.appendChild(result.createTextNode("code: " + str(process.returncode)))
|
|
||||||
testcase.appendChild(failure)
|
|
||||||
|
|
||||||
testsuite.appendChild(testcase)
|
|
||||||
|
|
||||||
print result.toxml()
|
|
60
test/jenkins/run_tests.conf
Normal file
60
test/jenkins/run_tests.conf
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
{
|
||||||
|
"commands": {
|
||||||
|
"copy": "scp -qF ssh_config {0} default:{1}",
|
||||||
|
"exec": "ssh -F ssh_config default '{0}'",
|
||||||
|
"clean": "ssh -F ssh_config default 'rm -f {0}'"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"test_root": "/tmp"
|
||||||
|
},
|
||||||
|
"setups": {
|
||||||
|
"^ido_[a-z]{2}sql.test$": {
|
||||||
|
"setup": {
|
||||||
|
"copy": [
|
||||||
|
"files/ido_tests.py >> /tmp/ido_tests.py",
|
||||||
|
"files/utils.py >> /tmp/utils.py"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"teardown": {
|
||||||
|
"clean": [
|
||||||
|
"/tmp/ido_tests.py*",
|
||||||
|
"/tmp/utils.py*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"checkresult.test": {
|
||||||
|
"setup": {
|
||||||
|
"copy": [
|
||||||
|
"files/configs/checkresult.conf >> /tmp/checkresult.conf",
|
||||||
|
"files/wait_for_ido.sh >> /tmp/wait_for_ido.sh",
|
||||||
|
"files/utils.py >> /tmp/utils.py"
|
||||||
|
],
|
||||||
|
"exec": [
|
||||||
|
"sudo mv /tmp/checkresult.conf /etc/icinga2/conf.d/",
|
||||||
|
"mkdir -p -m 0777 /tmp/icinga2/checkresults",
|
||||||
|
"sudo service icinga2 restart",
|
||||||
|
"/tmp/wait_for_ido.sh mysql"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"teardown": {
|
||||||
|
"clean": ["/tmp/utils.py*"],
|
||||||
|
"exec": [
|
||||||
|
"sudo rm /etc/icinga2/conf.d/checkresult.conf",
|
||||||
|
"sudo service icinga2 restart",
|
||||||
|
"rmdir /tmp/icinga2/checkresults",
|
||||||
|
"/tmp/wait_for_ido.sh mysql",
|
||||||
|
"/tmp/wait_for_ido.sh pgsql && rm /tmp/wait_for_ido.sh"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"external_commands.test": {
|
||||||
|
"setup": {
|
||||||
|
"copy": ["files/utils.py >> /tmp/utils.py"]
|
||||||
|
},
|
||||||
|
"teardown": {
|
||||||
|
"clean": ["/tmp/utils.py*"],
|
||||||
|
"exec": ["sudo service icinga2 restart"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
147
test/jenkins/run_tests.py
Executable file
147
test/jenkins/run_tests.py
Executable file
@ -0,0 +1,147 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import glob
|
||||||
|
import subprocess
|
||||||
|
from optparse import OptionParser
|
||||||
|
from xml.dom.minidom import getDOMImplementation
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
from subprocess import DEVNULL
|
||||||
|
except ImportError:
|
||||||
|
DEVNULL = open(os.devnull, 'w')
|
||||||
|
|
||||||
|
|
||||||
|
class TestSuite(object):
|
||||||
|
def __init__(self, configpath):
|
||||||
|
self._tests = []
|
||||||
|
self._results = {}
|
||||||
|
|
||||||
|
self.load_config(configpath)
|
||||||
|
|
||||||
|
def add_test(self, filepath):
|
||||||
|
self._tests.append(filepath)
|
||||||
|
|
||||||
|
def load_config(self, filepath):
|
||||||
|
with open(filepath) as f:
|
||||||
|
self._config = json.load(f)
|
||||||
|
|
||||||
|
def get_report(self):
|
||||||
|
dom = getDOMImplementation()
|
||||||
|
document = dom.createDocument(None, 'testsuite', None)
|
||||||
|
xml_root = document.documentElement
|
||||||
|
|
||||||
|
for name, info in self._results.iteritems():
|
||||||
|
testresult = document.createElement('testcase')
|
||||||
|
testresult.setAttribute('classname', 'vm')
|
||||||
|
testresult.setAttribute('name', name)
|
||||||
|
|
||||||
|
systemout = document.createElement('system-out')
|
||||||
|
systemout.appendChild(document.createTextNode(info['stdout']))
|
||||||
|
testresult.appendChild(systemout)
|
||||||
|
|
||||||
|
systemerr = document.createElement('system-err')
|
||||||
|
systemerr.appendChild(document.createTextNode(info['stderr']))
|
||||||
|
testresult.appendChild(systemerr)
|
||||||
|
|
||||||
|
if info['returncode'] != 0:
|
||||||
|
failure = document.createElement('failure')
|
||||||
|
failure.setAttribute('type', 'returncode')
|
||||||
|
failure.appendChild(document.createTextNode(
|
||||||
|
'code: {0}'.format(info['returncode'])))
|
||||||
|
testresult.appendChild(failure)
|
||||||
|
|
||||||
|
xml_root.appendChild(testresult)
|
||||||
|
|
||||||
|
return document.toxml()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
for path in self._tests:
|
||||||
|
test_name = os.path.basename(path)
|
||||||
|
self._apply_setup_routines(test_name, 'setup')
|
||||||
|
self._copy_test(path)
|
||||||
|
self._results[test_name] = self._run_test(path)
|
||||||
|
self._apply_setup_routines(test_name, 'teardown')
|
||||||
|
|
||||||
|
def _apply_setup_routines(self, test_name, context):
|
||||||
|
instructions = next((t[1].get(context)
|
||||||
|
for t in self._config.get('setups', {}).iteritems()
|
||||||
|
if re.match(t[0], test_name)), None)
|
||||||
|
if instructions is not None:
|
||||||
|
for instruction in instructions.get('copy', []):
|
||||||
|
source, _, destination = instruction.partition('>>')
|
||||||
|
self._copy_file(source.strip(), destination.strip())
|
||||||
|
for filepath in instructions.get('clean', []):
|
||||||
|
self._remove_file(filepath)
|
||||||
|
for command in instructions.get('exec', []):
|
||||||
|
self._exec_command(command)
|
||||||
|
|
||||||
|
def _remove_file(self, path):
|
||||||
|
command = self._config['commands']['clean'].format(path)
|
||||||
|
subprocess.call(command, stdout=DEVNULL, shell=True)
|
||||||
|
|
||||||
|
def _exec_command(self, command):
|
||||||
|
command = self._config['commands']['exec'].format(command)
|
||||||
|
subprocess.call(command, stdout=DEVNULL, shell=True)
|
||||||
|
|
||||||
|
def _copy_file(self, source, destination):
|
||||||
|
command = self._config['commands']['copy'].format(source, destination)
|
||||||
|
subprocess.call(command, stdout=DEVNULL, shell=True)
|
||||||
|
|
||||||
|
def _copy_test(self, path):
|
||||||
|
self._copy_file(path, os.path.join(self._config['settings']['test_root'],
|
||||||
|
os.path.basename(path)))
|
||||||
|
|
||||||
|
def _run_test(self, path):
|
||||||
|
command = self._config['commands']['exec']
|
||||||
|
target = os.path.join(self._config['settings']['test_root'],
|
||||||
|
os.path.basename(path))
|
||||||
|
p = subprocess.Popen(command.format(target), stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE, shell=True)
|
||||||
|
out, err = p.communicate()
|
||||||
|
|
||||||
|
return {
|
||||||
|
'stdout': out.decode('utf-8'),
|
||||||
|
'stderr': err.decode('utf-8'),
|
||||||
|
'returncode': p.returncode
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def parse_commandline():
|
||||||
|
parser = OptionParser(version='0.1')
|
||||||
|
parser.add_option('-C', '--config', default="run_tests.conf",
|
||||||
|
help='The path to the config file to use [%default]')
|
||||||
|
parser.add_option('-O', '--output',
|
||||||
|
help='The file which to save the test results. '
|
||||||
|
'(By default this goes to stdout)')
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
options, arguments = parse_commandline()
|
||||||
|
suite = TestSuite(options.config)
|
||||||
|
|
||||||
|
for path in (p for a in arguments for p in glob.glob(a)):
|
||||||
|
suite.add_test(path)
|
||||||
|
|
||||||
|
suite.run()
|
||||||
|
|
||||||
|
report = suite.get_report()
|
||||||
|
if options.output is None:
|
||||||
|
print report.encode('utf-8')
|
||||||
|
else:
|
||||||
|
with open(options.output, 'w') as f:
|
||||||
|
f.write(report.encode('utf-8'))
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
||||||
|
|
5
test/jenkins/run_tests.sh
Executable file
5
test/jenkins/run_tests.sh
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
vagrant ssh-config > ssh_config
|
||||||
|
./run_tests.py *.test
|
||||||
|
rm -f ssh_config
|
51
test/jenkins/statusdata.test
Executable file
51
test/jenkins/statusdata.test
Executable file
@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ ! -f /var/cache/icinga2/status.dat ];
|
||||||
|
then
|
||||||
|
sudo icinga2-enable-feature statusdata 1> /dev/null
|
||||||
|
sudo service icinga2 restart 1> /dev/null
|
||||||
|
|
||||||
|
n=0
|
||||||
|
while [ $n -lt 3 ]
|
||||||
|
do
|
||||||
|
sleep 15
|
||||||
|
|
||||||
|
if [ -f /var/cache/icinga2/status.dat ];
|
||||||
|
then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
n=$(( $n + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $n -eq 3 ];
|
||||||
|
then
|
||||||
|
echo "Icinga2 status.dat not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Icinga2 status.dat found"
|
||||||
|
|
||||||
|
if [ -f /var/cache/icinga2/objects.cache ];
|
||||||
|
then
|
||||||
|
echo "Icinga2 objects.cache found"
|
||||||
|
else
|
||||||
|
echo "Icinga2 objects.cache not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
status_time=$(stat --format="%Y" /var/cache/icinga2/status.dat)
|
||||||
|
|
||||||
|
now=$(date +"%s")
|
||||||
|
sleep $(((15 + 5) - ($now - $status_time)))
|
||||||
|
|
||||||
|
new_status_time=$(stat --format="%Y" /var/cache/icinga2/status.dat)
|
||||||
|
|
||||||
|
if [ $new_status_time -eq $status_time ];
|
||||||
|
then
|
||||||
|
echo "Icinga2 status.dat is not being updated"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "Icinga2 status.dat is being updated"
|
||||||
|
fi
|
@ -1,3 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
echo "Hello World!"
|
|
||||||
exit 1
|
|
Loading…
x
Reference in New Issue
Block a user