nagios-charmers team mailing list archive
-
nagios-charmers team
-
Mailing list archive
-
Message #00212
[Merge] ~aluria/hw-health-charm/+git/hw-health-charm:unittests-engrot6 into hw-health-charm:master
Alvaro Uría has proposed merging ~aluria/hw-health-charm/+git/hw-health-charm:unittests-engrot6 into hw-health-charm:master.
Requested reviews:
Nagios Charm developers (nagios-charmers)
For more details, see:
https://code.launchpad.net/~aluria/hw-health-charm/+git/hw-health-charm/+merge/361504
--
Your team Nagios Charm developers is requested to review the proposed merge of ~aluria/hw-health-charm/+git/hw-health-charm:unittests-engrot6 into hw-health-charm:master.
diff --git a/src/files/check_mdadm.py b/src/files/check_mdadm.py
index 741865e..b2c8b4a 100644
--- a/src/files/check_mdadm.py
+++ b/src/files/check_mdadm.py
@@ -4,6 +4,7 @@
import os
import re
import subprocess
+import sys
def get_devices():
@@ -15,7 +16,8 @@ def get_devices():
stderr=subprocess.PIPE)
devices_re = re.compile('^ARRAY\s+([^ ]+) ')
devices = set()
- for line in devices_raw.stdout.readline().decode():
+ for line in devices_raw.stdout.readlines():
+ line = line.decode().strip()
device_re = devices_re.match(line)
if device_re is not None:
devices.add(device_re.group(1))
@@ -23,14 +25,15 @@ def get_devices():
except Exception as e:
# log error
pass
- return
+ return set()
-def main():
+def parse_output():
devices = get_devices()
if len(devices) == 0:
- print('WARNING: unexpectedly checked no devices')
- return 1
+ msg = 'WARNING: unexpectedly checked no devices'
+ rc = 1
+ return (msg, rc)
mdadm_detail = ['/sbin/mdadm', '--detail']
mdadm_detail.extend(sorted(devices))
@@ -39,12 +42,13 @@ def main():
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
except Exception as error:
- print('WARNING: error executing mdadm: {}'.format(error))
- return 1
+ msg = 'WARNING: error executing mdadm: {}'.format(error)
+ rc = 1
+ return (msg, rc)
- devices_re = '^(/[^ ]+):$'
- state_re = '^\s*State :\s+(\S+)\s*'
- status_re = '^\s*(Active|Working|Failed|Spare) Devices :\s+(\d+)'
+ devices_re = '^(/\S+):$'
+ state_re = '^\s*State\s+:\s+(\S+)$'
+ status_re = '^\s*(Active|Working|Failed|Spare) Devices\s+:\s+(\d+)$'
devices_cre = re.compile(devices_re)
state_cre = re.compile(state_re)
@@ -52,7 +56,8 @@ def main():
device = None
devices_stats = {}
- for line in devices_details_raw.stdout.readline().decode():
+ for line in devices_details_raw.stdout.readlines():
+ line = line.decode().rstrip()
m = devices_cre.match(line)
if m:
device = m.group(1)
@@ -75,8 +80,8 @@ def main():
rc = devices_details_raw.wait()
if rc:
- print('WARNING: mdadm returned exit status {}'.format(int(rc)))
- return 1
+ msg = 'WARNING: mdadm returned exit status {}'.format(int(rc))
+ return (msg, 1)
parts = []
msg = []
@@ -88,22 +93,30 @@ def main():
else:
parts.append('{} ok'.format(device))
- for status in sorted(devices_stats[device]['stats']):
- parts.append('{}[{}]'
- .format(status,
- devices_stats[device]['stats'][status]))
- if status == 'Failed' \
- and devices_stats[device]['stats'][status] > 0:
- critical = True
+ if devices_stats[device]['stats'].get('Failed', 0) > 0:
+ critical = True
+ for status in sorted(devices_stats[device]['stats']):
+ parts.append('{}[{}]'
+ .format(status,
+ devices_stats[device]['stats'][status]))
msg.append(', '.join(parts))
+ parts = []
msg = '; '.join(msg)
if critical:
- print('CRITICAL: {}'.format(msg))
- return 2
+ msg_tmpl = 'CRITICAL: {}'
+ rc = 2
else:
- print('OK: {}'.format(msg))
- return 0
+ msg_tmpl = 'OK: {}'
+ rc = 0
+ return (msg_tmpl.format(msg),
+ rc)
+
+
+def main():
+ msg, rc = parse_output()
+ print(msg)
+ sys.exit(rc)
if __name__ == '__main__':
diff --git a/src/lib/utils/tooling.py b/src/lib/utils/tooling.py
index 387324f..3fe4fc6 100644
--- a/src/lib/utils/tooling.py
+++ b/src/lib/utils/tooling.py
@@ -8,7 +8,8 @@ from charmhelpers.core.hookenv import (
INFO
)
# from charms.layer import snap
-from shutil import copy2
+# from shutil import copy2
+import shutil
import subprocess
TOOLING = {
@@ -41,6 +42,9 @@ def install_tools(tools, method=None):
except Exception as error:
log('Snap install error: {}'.format(error),
ERROR)
+ elif tool == 'mdadm':
+ # XXX(aluria): mdadm is assumed to be installed by default
+ count += 1
return len(tools) >= count > 0
@@ -62,7 +66,7 @@ def configure_tools(tools):
cronjob_scriptname = os.path.basename(TOOLING[tool]['cronjob'])
if filepath:
subprocess.call(filepath)
- copy2(filepath, PLUGINS_DIR)
+ shutil.copy2(filepath, PLUGINS_DIR)
log('Cronjob script [{}]'
' copied to {}'.format(filepath, PLUGINS_DIR),
DEBUG)
@@ -85,7 +89,7 @@ def configure_tools(tools):
if 'filename' in TOOLING[tool]:
filepath = _get_filepath(TOOLING[tool]['filename'])
if filepath:
- copy2(filepath, PLUGINS_DIR)
+ shutil.copy2(filepath, PLUGINS_DIR)
count += 1
log('NRPE script for tool [{}] configured'.format(tool),
INFO)
diff --git a/src/reactive/hw_health.py b/src/reactive/hw_health.py
index 730d405..b136b1e 100644
--- a/src/reactive/hw_health.py
+++ b/src/reactive/hw_health.py
@@ -100,7 +100,8 @@ def configure_nrpe():
# then, parse checks output for Nagios to alert on
# configure_cronjobs(tools)
- if configure_nrpe_checks(tools):
+ configured = configure_nrpe_checks(tools)
+ if configured:
status.active('ready')
set_flag('hw-health.nrpe')
else:
diff --git a/src/tests/hw-health-samples/mdadm.output b/src/tests/hw-health-samples/mdadm.output
new file mode 100644
index 0000000..9356757
--- /dev/null
+++ b/src/tests/hw-health-samples/mdadm.output
@@ -0,0 +1,100 @@
+/dev/md0:
+ Version : 1.2
+ Creation Time : Thu Aug 2 22:50:05 2018
+ Raid Level : raid1
+ Array Size : 523712 (511.52 MiB 536.28 MB)
+ Used Dev Size : 523712 (511.52 MiB 536.28 MB)
+ Raid Devices : 2
+ Total Devices : 2
+ Persistence : Superblock is persistent
+
+ Update Time : Sun Nov 4 00:57:07 2018
+ State : clean
+ Active Devices : 2
+Working Devices : 2
+ Failed Devices : 0
+ Spare Devices : 0
+
+ Name : fnos-nvme05:0 (local to host fnos-nvme05)
+ UUID : dfaf7413:7551b000:56dd7442:5b020adb
+ Events : 51
+
+ Number Major Minor RaidDevice State
+ 0 8 1 0 active sync /dev/sda1
+ 2 8 17 1 active sync /dev/sdb1
+/dev/md1:
+ Version : 1.2
+ Creation Time : Thu Aug 2 22:50:09 2018
+ Raid Level : raid1
+ Array Size : 1948672 (1903.32 MiB 1995.44 MB)
+ Used Dev Size : 1948672 (1903.32 MiB 1995.44 MB)
+ Raid Devices : 2
+ Total Devices : 2
+ Persistence : Superblock is persistent
+
+ Update Time : Tue Nov 20 15:40:27 2018
+ State : clean
+ Active Devices : 2
+Working Devices : 2
+ Failed Devices : 0
+ Spare Devices : 0
+
+ Name : fnos-nvme05:1 (local to host fnos-nvme05)
+ UUID : 8946258c:a6246ca7:8d3dc20a:33bcabcb
+ Events : 51
+
+ Number Major Minor RaidDevice State
+ 0 8 2 0 active sync /dev/sda2
+ 2 8 18 1 active sync /dev/sdb2
+/dev/md3:
+ Version : 1.2
+ Creation Time : Thu Aug 2 22:50:16 2018
+ Raid Level : raid1
+ Array Size : 488148992 (465.54 GiB 499.86 GB)
+ Used Dev Size : 488148992 (465.54 GiB 499.86 GB)
+ Raid Devices : 2
+ Total Devices : 2
+ Persistence : Superblock is persistent
+
+ Intent Bitmap : Internal
+
+ Update Time : Tue Nov 27 16:47:44 2018
+ State : active
+ Active Devices : 2
+Working Devices : 2
+ Failed Devices : 0
+ Spare Devices : 0
+
+ Name : fnos-nvme05:3 (local to host fnos-nvme05)
+ UUID : ae461b25:13219daa:75846e9e:2e5a52f1
+ Events : 1418
+
+ Number Major Minor RaidDevice State
+ 0 8 4 0 active sync /dev/sda4
+ 2 8 20 1 active sync /dev/sdb4
+/dev/md2:
+ Version : 1.2
+ Creation Time : Thu Aug 2 22:50:13 2018
+ Raid Level : raid1
+ Array Size : 439320576 (418.97 GiB 449.86 GB)
+ Used Dev Size : 439320576 (418.97 GiB 449.86 GB)
+ Raid Devices : 2
+ Total Devices : 2
+ Persistence : Superblock is persistent
+
+ Intent Bitmap : Internal
+
+ Update Time : Tue Nov 27 16:47:41 2018
+ State : clean
+ Active Devices : 2
+Working Devices : 2
+ Failed Devices : 0
+ Spare Devices : 0
+
+ Name : fnos-nvme05:2 (local to host fnos-nvme05)
+ UUID : a83fda21:56cf85d4:99c802ed:c07c4f76
+ Events : 5715
+
+ Number Major Minor RaidDevice State
+ 0 8 3 0 active sync /dev/sda3
+ 2 8 19 1 active sync /dev/sdb3
diff --git a/src/tests/hw-health-samples/mdadm.output.critical b/src/tests/hw-health-samples/mdadm.output.critical
new file mode 100644
index 0000000..4bdab35
--- /dev/null
+++ b/src/tests/hw-health-samples/mdadm.output.critical
@@ -0,0 +1,100 @@
+/dev/md0:
+ Version : 1.2
+ Creation Time : Thu Aug 2 22:50:05 2018
+ Raid Level : raid1
+ Array Size : 523712 (511.52 MiB 536.28 MB)
+ Used Dev Size : 523712 (511.52 MiB 536.28 MB)
+ Raid Devices : 2
+ Total Devices : 2
+ Persistence : Superblock is persistent
+
+ Update Time : Sun Nov 4 00:57:07 2018
+ State : clean
+ Active Devices : 2
+Working Devices : 2
+ Failed Devices : 0
+ Spare Devices : 0
+
+ Name : fnos-nvme05:0 (local to host fnos-nvme05)
+ UUID : dfaf7413:7551b000:56dd7442:5b020adb
+ Events : 51
+
+ Number Major Minor RaidDevice State
+ 0 8 1 0 active sync /dev/sda1
+ 2 8 17 1 active sync /dev/sdb1
+/dev/md1:
+ Version : 1.2
+ Creation Time : Thu Aug 2 22:50:09 2018
+ Raid Level : raid1
+ Array Size : 1948672 (1903.32 MiB 1995.44 MB)
+ Used Dev Size : 1948672 (1903.32 MiB 1995.44 MB)
+ Raid Devices : 2
+ Total Devices : 2
+ Persistence : Superblock is persistent
+
+ Update Time : Tue Nov 20 15:40:27 2018
+ State : degraded
+ Active Devices : 1
+Working Devices : 1
+ Failed Devices : 1
+ Spare Devices : 0
+
+ Name : fnos-nvme05:1 (local to host fnos-nvme05)
+ UUID : 8946258c:a6246ca7:8d3dc20a:33bcabcb
+ Events : 51
+
+ Number Major Minor RaidDevice State
+ 0 8 2 0 active sync /dev/sda2
+ 2 8 18 1 active sync /dev/sdb2
+/dev/md3:
+ Version : 1.2
+ Creation Time : Thu Aug 2 22:50:16 2018
+ Raid Level : raid1
+ Array Size : 488148992 (465.54 GiB 499.86 GB)
+ Used Dev Size : 488148992 (465.54 GiB 499.86 GB)
+ Raid Devices : 2
+ Total Devices : 2
+ Persistence : Superblock is persistent
+
+ Intent Bitmap : Internal
+
+ Update Time : Tue Nov 27 16:47:44 2018
+ State : active
+ Active Devices : 2
+Working Devices : 2
+ Failed Devices : 0
+ Spare Devices : 0
+
+ Name : fnos-nvme05:3 (local to host fnos-nvme05)
+ UUID : ae461b25:13219daa:75846e9e:2e5a52f1
+ Events : 1418
+
+ Number Major Minor RaidDevice State
+ 0 8 4 0 active sync /dev/sda4
+ 2 8 20 1 active sync /dev/sdb4
+/dev/md2:
+ Version : 1.2
+ Creation Time : Thu Aug 2 22:50:13 2018
+ Raid Level : raid1
+ Array Size : 439320576 (418.97 GiB 449.86 GB)
+ Used Dev Size : 439320576 (418.97 GiB 449.86 GB)
+ Raid Devices : 2
+ Total Devices : 2
+ Persistence : Superblock is persistent
+
+ Intent Bitmap : Internal
+
+ Update Time : Tue Nov 27 16:47:41 2018
+ State : clean
+ Active Devices : 2
+Working Devices : 2
+ Failed Devices : 0
+ Spare Devices : 0
+
+ Name : fnos-nvme05:2 (local to host fnos-nvme05)
+ UUID : a83fda21:56cf85d4:99c802ed:c07c4f76
+ Events : 5715
+
+ Number Major Minor RaidDevice State
+ 0 8 3 0 active sync /dev/sda3
+ 2 8 19 1 active sync /dev/sdb3
diff --git a/src/tests/hw-health-samples/megacli.output.1 b/src/tests/hw-health-samples/megacli.output.1
new file mode 100644
index 0000000..2fb339f
--- /dev/null
+++ b/src/tests/hw-health-samples/megacli.output.1
@@ -0,0 +1,31 @@
+
+
+Adapter 0 -- Virtual Drive Information:
+Virtual Drive: 0 (Target Id: 0)
+Name :vg01
+RAID Level : Primary-1, Secondary-0, RAID Level Qualifier-0
+Size : 7.276 TB
+Sector Size : 512
+Is VD emulated : No
+Mirror Data : 7.276 TB
+State : Optimal
+Strip Size : 64 KB
+Number Of Drives : 4
+Span Depth : 1
+Default Cache Policy: WriteBack, ReadAhead, Direct, No Write Cache if Bad BBU
+Current Cache Policy: WriteBack, ReadAhead, Direct, No Write Cache if Bad BBU
+Default Access Policy: Read/Write
+Current Access Policy: Read/Write
+Disk Cache Policy : Disk's Default
+Encryption Type : None
+Default Power Savings Policy: Controller Defined
+Current Power Savings Policy: None
+Can spin up in 1 minute: Yes
+LD has drives that support T10 power conditions: Yes
+LD's IO profile supports MAX power savings with cached writes: No
+Bad Blocks Exist: No
+Is VD Cached: No
+
+
+
+Exit Code: 0x00
diff --git a/src/tests/hw-health-samples/sas2ircu.huawei.output.1 b/src/tests/hw-health-samples/sas2ircu.huawei.output.1
new file mode 100644
index 0000000..02ac325
--- /dev/null
+++ b/src/tests/hw-health-samples/sas2ircu.huawei.output.1
@@ -0,0 +1,150 @@
+LSI Corporation SAS2 IR Configuration Utility.
+Version 20.00.00.00 (2014.09.18)
+Copyright (c) 2008-2014 LSI Corporation. All rights reserved.
+
+Read configuration has been initiated for controller 0
+------------------------------------------------------------------------
+Controller information
+------------------------------------------------------------------------
+ Controller type : SAS2308_2
+ BIOS version : 7.39.00.00
+ Firmware version : 18.00.04.00
+ Channel description : 1 Serial Attached SCSI
+ Initiator ID : 0
+ Maximum physical devices : 255
+ Concurrent commands supported : 3072
+ Slot : Unknown
+ Segment : 0
+ Bus : 1
+ Device : 0
+ Function : 0
+ RAID Support : Yes
+------------------------------------------------------------------------
+IR Volume information
+------------------------------------------------------------------------
+------------------------------------------------------------------------
+Physical device information
+------------------------------------------------------------------------
+Initiator at ID #0
+
+Device is a Hard disk
+ Enclosure # : 1
+ Slot # : 0
+ SAS Address : 4433221-1-0000-0000
+ State : Ready (RDY)
+ Size (in MB)/(in sectors) : 3815447/7814037167
+ Manufacturer : ATA
+ Model Number : HGST HUS724040AL
+ Firmware Revision : A8B0
+ Serial No : PN1334PEJ8VRBS
+ GUID : 5000cca250e03649
+ Protocol : SATA
+ Drive Type : SATA_HDD
+
+Device is a Hard disk
+ Enclosure # : 1
+ Slot # : 1
+ SAS Address : 4433221-1-0100-0000
+ State : Ready (RDY)
+ Size (in MB)/(in sectors) : 3815447/7814037167
+ Manufacturer : ATA
+ Model Number : HGST HUS724040AL
+ Firmware Revision : A8B0
+ Serial No : PN1334PEHMEH5S
+ GUID : 5000cca250d6ed31
+ Protocol : SATA
+ Drive Type : SATA_HDD
+
+Device is a Hard disk
+ Enclosure # : 1
+ Slot # : 2
+ SAS Address : 4433221-1-0200-0000
+ State : Ready (RDY)
+ Size (in MB)/(in sectors) : 3815447/7814037167
+ Manufacturer : ATA
+ Model Number : HGST HUS724040AL
+ Firmware Revision : A8B0
+ Serial No : PN1338P4HVWD8B
+ GUID : 5000cca249da4ffe
+ Protocol : SATA
+ Drive Type : SATA_HDD
+
+Device is a Hard disk
+ Enclosure # : 1
+ Slot # : 3
+ SAS Address : 4433221-1-0300-0000
+ State : Ready (RDY)
+ Size (in MB)/(in sectors) : 3815447/7814037167
+ Manufacturer : ATA
+ Model Number : HGST HUS724040AL
+ Firmware Revision : A8B0
+ Serial No : PN1338P4HVVHZB
+ GUID : 5000cca249da4cb0
+ Protocol : SATA
+ Drive Type : SATA_HDD
+
+Device is a Hard disk
+ Enclosure # : 1
+ Slot # : 4
+ SAS Address : 4433221-1-0400-0000
+ State : Ready (RDY)
+ Size (in MB)/(in sectors) : 3815447/7814037167
+ Manufacturer : ATA
+ Model Number : HGST HUS724040AL
+ Firmware Revision : A8B0
+ Serial No : PN1338P4HVPDGB
+ GUID : 5000cca249da397e
+ Protocol : SATA
+ Drive Type : SATA_HDD
+
+Device is a Hard disk
+ Enclosure # : 1
+ Slot # : 5
+ SAS Address : 4433221-1-0500-0000
+ State : Ready (RDY)
+ Size (in MB)/(in sectors) : 3815447/7814037167
+ Manufacturer : ATA
+ Model Number : HGST HUS724040AL
+ Firmware Revision : A8B0
+ Serial No : PN1338P4HVWWKB
+ GUID : 5000cca249da51d8
+ Protocol : SATA
+ Drive Type : SATA_HDD
+
+Device is a Hard disk
+ Enclosure # : 1
+ Slot # : 6
+ SAS Address : 4433221-1-0600-0000
+ State : Ready (RDY)
+ Size (in MB)/(in sectors) : 3815447/7814037167
+ Manufacturer : ATA
+ Model Number : HGST HUS724040AL
+ Firmware Revision : A8B0
+ Serial No : PN1334PEHPU1XX
+ GUID : 5000cca250d80160
+ Protocol : SATA
+ Drive Type : SATA_HDD
+
+Device is a Hard disk
+ Enclosure # : 1
+ Slot # : 7
+ SAS Address : 4433221-1-0700-0000
+ State : Ready (RDY)
+ Size (in MB)/(in sectors) : 3815447/7814037167
+ Manufacturer : ATA
+ Model Number : HGST HUS724040AL
+ Firmware Revision : A8B0
+ Serial No : PN1338P4HVWV7B
+ GUID : 5000cca249da51af
+ Protocol : SATA
+ Drive Type : SATA_HDD
+------------------------------------------------------------------------
+Enclosure information
+------------------------------------------------------------------------
+ Enclosure# : 1
+ Logical ID : 5384c4f8:aa1c9000
+ Numslots : 8
+ StartSlot : 0
+------------------------------------------------------------------------
+SAS2IRCU: Command DISPLAY Completed Successfully.
+SAS2IRCU: Utility Completed Successfully.
diff --git a/src/tests/hw-health-samples/sas3ircu.supermicro.output.1 b/src/tests/hw-health-samples/sas3ircu.supermicro.output.1
new file mode 100644
index 0000000..03ca92e
--- /dev/null
+++ b/src/tests/hw-health-samples/sas3ircu.supermicro.output.1
@@ -0,0 +1,82 @@
+Avago Technologies SAS3 IR Configuration Utility.
+Version 17.00.00.00 (2018.04.02)
+Copyright (c) 2009-2018 Avago Technologies. All rights reserved.
+
+Read configuration has been initiated for controller 0
+------------------------------------------------------------------------
+Controller information
+------------------------------------------------------------------------
+ Controller type : SAS3008
+ PI Supported : Yes
+ PI Mixing : Disabled
+ BIOS version : 8.35.00.00
+ Firmware version : 15.00.00.00
+ Channel description : 1 Serial Attached SCSI
+ Initiator ID : 0
+ Maximum physical devices : 255
+ Concurrent commands supported : 3072
+ Slot : 2
+ Segment : 0
+ Bus : 2
+ Device : 0
+ Function : 0
+ RAID Support : Yes
+------------------------------------------------------------------------
+IR Volume information
+------------------------------------------------------------------------
+IR volume 1
+ Volume ID : 323
+ PI Supported : No
+ Status of volume : Okay (OKY)
+ Volume wwid : 017e97cb06987855
+ RAID level : RAID1
+ Size (in MB) : 3814697
+ Physical hard disks :
+ PHY[0] Enclosure#/Slot# : 1:0
+ PHY[1] Enclosure#/Slot# : 1:1
+------------------------------------------------------------------------
+Physical device information
+------------------------------------------------------------------------
+Initiator at ID #0
+
+Device is a Hard disk
+ Enclosure # : 1
+ Slot # : 0
+ PI Supported : No
+ SAS Address : 4433221-1-0000-0000
+ State : Optimal (OPT)
+ Size (in MB)/(in sectors) : 3815447/7814037167
+ Manufacturer : ATA
+ Model Number : ST4000NM115-1YZ1
+ Firmware Revision : SN02
+ Serial No : ZC11155N
+ Unit Serial No(VPD) : ZC11155N
+ GUID : 5000c500a1d45b35
+ Protocol : SATA
+ Drive Type : SATA_HDD
+
+Device is a Hard disk
+ Enclosure # : 1
+ Slot # : 1
+ PI Supported : No
+ SAS Address : 4433221-1-0100-0000
+ State : Optimal (OPT)
+ Size (in MB)/(in sectors) : 3815447/7814037167
+ Manufacturer : ATA
+ Model Number : ST4000NM115-1YZ1
+ Firmware Revision : SN02
+ Serial No : ZC111FVA
+ Unit Serial No(VPD) : ZC111FVA
+ GUID : 5000c500a1d51834
+ Protocol : SATA
+ Drive Type : SATA_HDD
+------------------------------------------------------------------------
+Enclosure information
+------------------------------------------------------------------------
+ Enclosure# : 1
+ Logical ID : 50030480:22df6300
+ Numslots : 8
+ StartSlot : 0
+------------------------------------------------------------------------
+SAS3IRCU: Command DISPLAY Completed Successfully.
+SAS3IRCU: Utility Completed Successfully.
diff --git a/src/tests/unit/test_check_mdadm.py b/src/tests/unit/test_check_mdadm.py
new file mode 100644
index 0000000..e9d36bf
--- /dev/null
+++ b/src/tests/unit/test_check_mdadm.py
@@ -0,0 +1,119 @@
+import mock
+import unittest
+import io
+import os
+import sys
+
+sys.path.append('files')
+import check_mdadm
+
+
+class TestCheckMegaCLI(unittest.TestCase):
+ @mock.patch('os.path.exists')
+ @mock.patch('subprocess.Popen')
+ def test_get_devices_mdadm_exists(self, mdadm_details, path_exists):
+ class Test_Popen(object):
+ def __init__(cls):
+ data = b'ARRAY /dev/md0 metadata=1.2 name=node00:0'
+ data += b' UUID=dfaf7413:7551b000:56dd7442:5b020adb\n'
+ data += b'ARRAY /dev/md1 metadata=1.2 name=node01:0'
+ data += b' UUID=dfaf7413:7551b000:56dd7442:5b020adc\n'
+ cls.stdout = io.BufferedReader(io.BytesIO(data))
+
+ mdadm_details.return_value = Test_Popen()
+ path_exists.return_value = True
+
+ real = check_mdadm.get_devices()
+ expected = set(['/dev/md0', '/dev/md1'])
+ self.assertEqual(real, expected)
+
+ @mock.patch('os.path.exists')
+ def test_get_devices_mdadm_notfound(self, path_exists):
+ path_exists.return_value = False
+ real = check_mdadm.get_devices()
+ expected = set()
+ self.assertEqual(real, expected)
+
+ @mock.patch('os.path.exists')
+ @mock.patch('subprocess.Popen')
+ def test_get_devices_mdadm_exception(self, mdadm_details, path_exists):
+ path_exists.return_value = True
+ mdadm_details.side_effect = Exception
+ real = check_mdadm.get_devices()
+ expected = set()
+ self.assertEqual(real, expected)
+
+ @mock.patch('check_mdadm.get_devices')
+ @mock.patch('subprocess.Popen')
+ def test_parse_output_ok(self, mdadm_details, devices):
+ class Test_Popen(object):
+ def __init__(cls):
+ test_output = os.path.join(os.getcwd(),
+ 'tests',
+ 'hw-health-samples',
+ 'mdadm.output')
+ cls.stdout = io.FileIO(test_output)
+ cls.wait = lambda: 0
+
+ devices.return_value = set(['/dev/md0', '/dev/md1', '/dev/md2'])
+ mdadm_details.return_value = Test_Popen()
+ real = check_mdadm.parse_output()
+ expected = ('OK: /dev/md0 ok; /dev/md1 ok; /dev/md3 ok; /dev/md2 ok',
+ 0)
+ self.assertEqual(real, expected)
+
+ @mock.patch('check_mdadm.get_devices')
+ @mock.patch('subprocess.Popen')
+ def test_parse_output_wait_warning(self, mdadm_details, devices):
+ class Test_Popen(object):
+ def __init__(cls):
+ test_output = os.path.join(os.getcwd(),
+ 'tests',
+ 'hw-health-samples',
+ 'mdadm.output')
+ cls.stdout = io.FileIO(test_output)
+ cls.wait = lambda: 2
+
+ devices.return_value = set(['/dev/md0', '/dev/md1', '/dev/md2'])
+ mdadm_details.return_value = Test_Popen()
+ real = check_mdadm.parse_output()
+ expected = ('WARNING: mdadm returned exit status 2',
+ 1)
+ self.assertEqual(real, expected)
+
+ @mock.patch('check_mdadm.get_devices')
+ def test_parse_output_nodevices(self, devices):
+ devices.return_value = set()
+ real = check_mdadm.parse_output()
+ expected = ('WARNING: unexpectedly checked no devices', 1)
+ self.assertEqual(real, expected)
+
+ @mock.patch('check_mdadm.get_devices')
+ @mock.patch('subprocess.Popen')
+ def test_parse_output_mdadm_warning(self, mdadm_details, devices):
+ devices.return_value = set(['/dev/md0', '/dev/md1', '/dev/md2'])
+ mdadm_details.side_effect = Exception('ugly error')
+ real = check_mdadm.parse_output()
+ expected = ('WARNING: error executing mdadm: ugly error', 1)
+ self.assertEqual(real, expected)
+
+ @mock.patch('check_mdadm.get_devices')
+ @mock.patch('subprocess.Popen')
+ def test_parse_output_degraded(self, mdadm_details, devices):
+ class Test_Popen(object):
+ def __init__(cls):
+ test_output = os.path.join(os.getcwd(),
+ 'tests',
+ 'hw-health-samples',
+ 'mdadm.output.critical')
+ cls.stdout = io.FileIO(test_output)
+ cls.wait = lambda: 0
+
+ devices.return_value = set(['/dev/md0', '/dev/md1', '/dev/md2'])
+ mdadm_details.return_value = Test_Popen()
+ real = check_mdadm.parse_output()
+ expected = ('CRITICAL: /dev/md0 ok; /dev/md1 degraded, Active[1],'
+ ' Failed[1], Spare[0], Working[1]; /dev/md3 ok;'
+ ' /dev/md2 ok',
+ 2)
+ self.assertEqual(real, expected)
diff --git a/src/tests/unit/test_check_megacli.py b/src/tests/unit/test_check_megacli.py
new file mode 100644
index 0000000..54ed500
--- /dev/null
+++ b/src/tests/unit/test_check_megacli.py
@@ -0,0 +1,19 @@
+# import mock
+import unittest
+import sys
+import os
+
+sys.path.append('files/megaraid')
+import check_megacli
+
+
+class TestCheckMegaCLI(unittest.TestCase):
+ def test_parse_output(self):
+ check_megacli.INPUT_FILE = os.path.join(os.getcwd(),
+ 'tests',
+ 'hw-health-samples',
+ 'megacli.output.1')
+ real = check_megacli.parse_output()
+ expected = {'critical': False,
+ 'OK': 'OK: Optimal, ldrives[1], pdrives[4]'}
+ self.assertEqual(real, expected)
diff --git a/src/tests/unit/test_check_sas2ircu.py b/src/tests/unit/test_check_sas2ircu.py
new file mode 100644
index 0000000..af4a674
--- /dev/null
+++ b/src/tests/unit/test_check_sas2ircu.py
@@ -0,0 +1,18 @@
+# import mock
+import unittest
+import sys
+import os
+
+sys.path.append('files/mpt')
+import check_sas2ircu
+
+
+class TestCheckMegaCLI(unittest.TestCase):
+ def test_parse_output(self):
+ check_sas2ircu.INPUT_FILE = os.path.join(os.getcwd(),
+ 'tests',
+ 'hw-health-samples',
+ 'sas2ircu.huawei.output.1')
+ real = check_sas2ircu.parse_output()
+ expected = ('Ready[1:0,1:1,1:2,1:3,1:4,1:5,1:6,1:7]', False)
+ self.assertEqual(real, expected)
diff --git a/src/tests/unit/test_check_sas3ircu.py b/src/tests/unit/test_check_sas3ircu.py
new file mode 100644
index 0000000..cadaffb
--- /dev/null
+++ b/src/tests/unit/test_check_sas3ircu.py
@@ -0,0 +1,19 @@
+# import mock
+import unittest
+import sys
+import os
+
+sys.path.append('files/mpt')
+import check_sas3ircu
+
+
+class TestCheckMegaCLI(unittest.TestCase):
+ def test_parse_output(self):
+ _filepath = os.path.join(os.getcwd(),
+ 'tests',
+ 'hw-health-samples',
+ 'sas3ircu.supermicro.output.1')
+ check_sas3ircu.INPUT_FILE = _filepath
+ real = check_sas3ircu.parse_output()
+ expected = ('Okay[323:(1:0,1:1)]; Optimal[1:0,1:1]', False)
+ self.assertEqual(real, expected)
diff --git a/src/tests/unit/test_tooling.py b/src/tests/unit/test_tooling.py
index 78a6790..d2fe1e1 100644
--- a/src/tests/unit/test_tooling.py
+++ b/src/tests/unit/test_tooling.py
@@ -1,17 +1,64 @@
-# import mock
+import mock
import unittest
+import shutil
import sys
-# import os
+import os
# import io
# import subprocess
# import charmhelpers.core.host
+# from shutil import copy2
sys.path.append('lib/utils')
import tooling
class TestTooling(unittest.TestCase):
- def test_install_tools(self):
+ def test_install_tools_notools(self):
real = tooling.install_tools([])
expected = False
self.assertEqual(real, expected)
+
+ def test_install_tools_unsupported_tools(self):
+ real = tooling.install_tools(['unittest1', 'unittest2'])
+ expected = False
+ self.assertEqual(real, expected)
+
+ def test_install_tools_supported_tools(self):
+ real = tooling.install_tools(['megacli', 'sas2ircu'])
+ expected = True
+ self.assertEqual(real, expected)
+
+ def test_install_tools_mdadm(self):
+ real = tooling.install_tools(['mdadm'])
+ expected = True
+ self.assertEqual(real, expected)
+
+ @mock.patch('os.environ')
+ @mock.patch('os.path.join')
+ @mock.patch('os.path.exists')
+ def test_get_filepath(self, path_exists, path_join, environ):
+ environ.return_value = {'CHARM_DIR': 'xxx'}
+ path_join.return_value = 'unittest1'
+ path_exists.return_value = True
+ real = tooling._get_filepath('asdfasdf')
+ expected = 'unittest1'
+ self.assertEqual(real, expected)
+
+ def test_configure_tools_notools(self):
+ real = tooling.configure_tools([])
+ expected = False
+ self.assertEqual(real, expected)
+
+ def test_configure_tools_unsupported_tools(self):
+ real = tooling.configure_tools(['unittest1', 'unittest2'])
+ expected = False
+ self.assertEqual(real, expected)
+
+ @mock.patch('shutil.copy2')
+ @mock.patch('tooling._get_filepath')
+ def test_configure_tools_mdadm(self, get_filepath, copy_file):
+ get_filepath.return_value = 'unittest'
+ copy_file.return_value = None
+ real = tooling.configure_tools(['mdadm'])
+ expected = True
+ self.assertEqual(real, expected)
Follow ups