From aa3ad3fd8fe1003e092715c3d506861182febb01 Mon Sep 17 00:00:00 2001 From: Erik Bernoth Date: Fri, 10 May 2013 16:24:29 +0200 Subject: [PATCH] WIP: add nosetesting support See Github Issue #34. Signed-off-by: Erik Bernoth --- setup.cfg | 13 ++ setup.py | 35 +++-- test/test_all.py | 41 ------ test/test_bcc.py | 260 ------------------------------------ test/test_connection.py | 216 ------------------------------ test/test_device.py | 26 ---- test/test_devicetestcase.py | 72 ---------- test/test_serial_conn.py | 28 ++-- test/test_ssh_conn.py | 25 ---- 9 files changed, 48 insertions(+), 668 deletions(-) create mode 100644 setup.cfg delete mode 100755 test/test_all.py delete mode 100755 test/test_bcc.py delete mode 100755 test/test_connection.py delete mode 100755 test/test_device.py delete mode 100755 test/test_devicetestcase.py mode change 100755 => 100644 test/test_serial_conn.py delete mode 100755 test/test_ssh_conn.py diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..2698a11 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,13 @@ +[nosetests] +#should not be set to 1 until bug is fixed in nosetests project +verbosity=2 +detailed-errors=1 +#xml output for jenkins and the likes +with-xunit=1 +#coverage with xml as well +with-xcoverage=1 +#only cover the monk package and leave the rest of python alone +cover-package=monk_tf +debug=nose.loader +pdb=1 +pdb-failures=1 diff --git a/setup.py b/setup.py index 3a8e00f..ce7575a 100755 --- a/setup.py +++ b/setup.py @@ -11,25 +11,34 @@ # 2 of the License, or (at your option) any later version. # -from distutils.core import setup +from setuptools import setup -project = 'monk_tf' -src_path = 'src' -version = '0.1.1' +project = "monk_tf" +src_path = "src" +version = "0.1.1" setup( name=project, version=version, - description = 'a test framework for embedded systems', - author = 'DResearch Fahrzeugelektronik GmbH', - author_email = 'project-monk@dresearch-fe.de', - url='https://github.com/DFE/MONK', + description = "a test framework for embedded systems", + author = "DResearch Fahrzeugelektronik GmbH", + author_email = "project-monk@dresearch-fe.de", + url="https://github.com/DFE/MONK", packages=[project], - package_dir = { '' : src_path }, + package_dir = { "" : src_path }, + setup_requires = [ + "nose >= 1.0" + ], install_requires = [ - 'pyserial ==2.5', - 'pylibssh2 ==1.0.1' + "pyserial >=2.5", + "pylibssh2 >=1.0.1" ],provides = [ - '{} ({})'.format(project, version) - ] + "{} ({})".format(project, version) + ], + tests_require = [ + "nose >= 1.0", + "coverage", + "nosexcover" + ], + test_suite = "nose.collector" ) diff --git a/test/test_all.py b/test/test_all.py deleted file mode 100755 index 49523d5..0000000 --- a/test/test_all.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# MONK Automated Testing Framework -# -# Copyright (C) 2012 DResearch Fahrzeugelektronik GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version -# 2 of the License, or (at your option) any later version. -# - -import sys, os, inspect -sys.path.append(os.path.abspath( - os.path.dirname(inspect.getfile(inspect.currentframe()))+"/../src/monk_tf")) - -import unittest - -from test_bcc import TestBcc -from test_connection import TestConnection -from test_device import TestDevice -from test_devicetestcase import TestDevicetestcase -from test_serial_conn import TestSerialConn -from test_ssh_conn import TestSshConn - - -class TestAll(unittest.TestSuite): - - def __init__(self): - self.addTest(TestBcc()) - self.addTest(TestConnection()) - self.addTest(TestDevice()) - self.addTest(TestDeviceTestcase()) - self.addTest(TestSerialConn()) - self.addTest(TestSshConn()) - - - -if __name__ == "__main__": - unittest.main() diff --git a/test/test_bcc.py b/test/test_bcc.py deleted file mode 100755 index 1bccf68..0000000 --- a/test/test_bcc.py +++ /dev/null @@ -1,260 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# MONK Automated Testing Framework -# -# Copyright (C) 2012 DResearch Fahrzeugelektronik GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version -# 2 of the License, or (at your option) any later version. -# - -import subprocess, atexit -import unittest - -import sys, os, inspect -sys.path.append(os.path.abspath( - os.path.dirname(inspect.getfile(inspect.currentframe()))+"/../src/monk_tf")) - -from bcc import Bcc - -# -# MOCKING -# - -# --- mocked functions --- -MOCK_atexit_func = None -def mock_atexit_register(func): - global MOCK_atexit_func - MOCK_atexit_func = func - - -def mock_check_output(cmd, stderr = None): - MOCK_subp_input.append([cmd, stderr]) - if MOCK_subp_raise: - raise MOCK_subp_raise - return MOCK_subp_retval - -# --- mock helper variables and functions --- - -MOCK_bcc_example_output_off = """status_cb: raw data: 01 00 02 00 00 00 17 0b 09 00 09 00 e7 00 09 0a 04 ac 00 f0 00 60 02 05 01 4e 00 9e 00 4f 00 00 00 00 00 00 05 -SPIs/SPOs: Ignition: off, HDD-Sense: closed, OXE_INT1: 0, OXE_INT2: 0, XOSC_ERR: 0, GPI-Power: off, HDD-Power: off -GPInputs 1..6: 0 0 0 0 0 0 GPOutputs 1..4: 0 0 0 0 RTC Temp : 23 deg C Accel X, Y, Z: 35mg, 35mg, 902mg -Voltages: 23.14V 11.96V 2.40V 0.96V 5.17V 3.34V 1.58V 0.79V 0.00V""" - -MOCK_bcc_example_output_on = """status_cb: raw data: 01 00 02 00 00 00 17 0b 09 00 09 00 e7 00 09 0a 04 ac 00 f0 00 60 02 05 01 4e 00 9e 00 4f 00 00 00 00 00 00 05 -SPIs/SPOs: Ignition: on, HDD-Sense: closed, OXE_INT1: 0, OXE_INT2: 0, XOSC_ERR: 0, GPI-Power: off, HDD-Power: on -GPInputs 1..6: 0 0 0 0 0 0 GPOutputs 1..4: 0 0 0 0 RTC Temp : 23 deg C Accel X, Y, Z: 35mg, 35mg, 902mg -Voltages: 23.14V 11.96V 2.40V 0.96V 5.17V 3.34V 1.58V 0.79V 0.00V""" - -MOCK_bcc_example_output_debugget = """debug_get_cb: addr: 0x00000001 len: 4 data: 12 34 23 42""" - -MOCK_subp_retval = "" -MOCK_subp_input = [ ] -MOCK_subp_raise = None - -def mock_reset_values(): - global MOCK_subp_input, MOCK_subp_retval, MOCK_subp_raise - MOCK_subp_input = [ ] - MOCK_subp_retval = "" - MOCK_subp_raise = None - -orig_ate_register = atexit.register -orig_subp_check_output = subprocess.check_output - -def mock_on(): - mock_reset_values() - atexit.register = mock_atexit_register - subprocess.check_output = mock_check_output - -def mock_off(): - atexit.register = orig_ate_register - subprocess.check_output = orig_subp_check_output - -# --- mocking ENDs --- - -# -# The actual tests -# - -class TestBcc(unittest.TestCase): - """ This class implements a number of default test cases - for the board controller class.""" - - def setUp(self): - mock_on() - - def tearDown(self): - mock_off() - - - def test_default_init_cleanup(self): - """ Test the default initialization and cleanup. - This test just checks for the correct defaults after - Bcc class instantiation. - Note that this test also implicitly tests bcc.poweron(), - which in turn tests bcc.hddpower and bcc.heartbeat setters.""" - - b = Bcc() - - # check instance variables - self.assertEquals(b._Bcc__drbcc, "drbcc") - self.assertEquals(b._Bcc__port, "/dev/ttyUSB0") - self.assertEquals(b._Bcc__port_br, 57600) - - # check function registered with atexit - self.assertEquals(b._Bcc__cleanup, MOCK_atexit_func) - - # check board controller commands issued during init - global MOCK_subp_input - self.assertEquals(len(MOCK_subp_input), 3) - self.assertEquals(MOCK_subp_input[0], - [['drbcc', '--dev=/dev/ttyUSB0,57600', '--cmd=debugset 16,0100010001'], subprocess.STDOUT]) - self.assertEquals(MOCK_subp_input[1], - [['drbcc', '--dev=/dev/ttyUSB0,57600', '--cmd=heartbeat 65535'], subprocess.STDOUT]) - self.assertEquals(MOCK_subp_input[2], - [['drbcc', '--dev=/dev/ttyUSB0,57600', '--cmd=hdpower 1'], subprocess.STDOUT]) - - # check atexit command - MOCK_subp_input = [] - MOCK_atexit_func() - self.assertEquals(len(MOCK_subp_input), 1) - self.assertEquals(MOCK_subp_input[0], - [['drbcc', '--dev=/dev/ttyUSB0,57600', '--cmd=debugset 16,00'], subprocess.STDOUT]) - - - def test_cleanup_fails(self): - """ This test checks for pokemon exception handling - in the cleanup atexit handler. """ - b = Bcc() - global MOCK_subp_raise - MOCK_subp_raise = Exception() - try: - MOCK_atexit_func() - except: - self.fail("BCC atexit function raised an exception!") - - - def __simple_setup(self, output, exc=None): - """ Helper for setting up simple tests. Will create a bcc instance and - do some initial cleanup. """ - b = Bcc() - global MOCK_subp_input, MOCK_subp_retval, MOCK_subp_raise - MOCK_subp_input = [] - MOCK_subp_retval = output - if exc: - MOCK_subp_raise = exc - return b - - - def test_cmd(self): - """ Test the execution of an arbitrary command """ - - b = self.__simple_setup("InDiesemStringDaSitztEinGeistUswUsf") - - rc, text = b.cmd("hurz") - - self.assertEquals(len(MOCK_subp_input), 1) - self.assertEquals(MOCK_subp_input[0][0][2],'--cmd=hurz') - - self.assertEquals(text, MOCK_subp_retval) - self.assertEquals(rc, 0) - - - def test_cmd_fails(self): - """ Test the execution of an arbitrary command which fails """ - - b = self.__simple_setup("bla", subprocess.CalledProcessError(9, "", "exception output")) - - rc, text = b.cmd("narf") - - self.assertEquals(len(MOCK_subp_input), 1) - self.assertEquals(MOCK_subp_input[0][0][2],'--cmd=narf') - - self.assertEquals(text, "exception output") - self.assertEquals(rc, 9) - - - def test_reset(self): - """ Test the reset function. """ - - import time - b = Bcc() - - called = [ 0, 0, 0 ] - s = time.sleep - def cb(a, idx): - a[idx] += 1 - - try: - b.poweroff = lambda: cb(called, 0) - time.sleep = lambda ignored: cb(called, 1) - b.poweron = lambda: cb(called, 2) - - b.reset() - - self.assertEquals(called, [1,1,1]) - finally: - time.sleep = s - - - def test_poweroff(self): - """ Poweroff test. Note that bcc.poweron() is already tested - by test_default_init_cleanup(). """ - b = self.__simple_setup(""); - - b.poweroff() - - self.assertEquals(len(MOCK_subp_input), 3) - self.assertEquals(MOCK_subp_input[0], - [['drbcc', '--dev=/dev/ttyUSB0,57600', '--cmd=debugset 16,0100000001'], subprocess.STDOUT]) - self.assertEquals(MOCK_subp_input[1], - [['drbcc', '--dev=/dev/ttyUSB0,57600', '--cmd=heartbeat 0'], subprocess.STDOUT]) - self.assertEquals(MOCK_subp_input[2], - [['drbcc', '--dev=/dev/ttyUSB0,57600', '--cmd=hdpower 0'], subprocess.STDOUT]) - - - def test_status(self): - """ Test the bcc status property. """ - - b = self.__simple_setup(MOCK_bcc_example_output_off) - text = b.status - - self.assertEquals(len(MOCK_subp_input), 1) - self.assertEquals(MOCK_subp_input[0][0][2],'--cmd=gets') - - self.assertEquals(text, MOCK_bcc_example_output_off) - - - def test_ignition(self): - """ Test the ignition prperty. """ - b = self.__simple_setup(MOCK_bcc_example_output_off) - self.assertFalse(b.ignition) - - b = self.__simple_setup(MOCK_bcc_example_output_on) - self.assertTrue(b.ignition) - - - def test_hddpower(self): - """ Test the hdd power prperty. """ - b = self.__simple_setup(MOCK_bcc_example_output_off) - self.assertFalse(b.hddpower) - - b = self.__simple_setup(MOCK_bcc_example_output_on) - self.assertTrue(b.hddpower) - - - def test_heartbeat(self): - """ test the heartbeat property. """ - b = self.__simple_setup(MOCK_bcc_example_output_debugget) - - curr, maxi = b.heartbeat - - self.assertEquals(curr, 4660) - self.assertEquals(maxi, 9026) - - -if __name__ == "__main__": - unittest.main() diff --git a/test/test_connection.py b/test/test_connection.py deleted file mode 100755 index ef01369..0000000 --- a/test/test_connection.py +++ /dev/null @@ -1,216 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# MONK Automated Testing Framework -# -# Copyright (C) 2012 DResearch Fahrzeugelektronik GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version -# 2 of the License, or (at your option) any later version. -# - - -import subprocess, atexit -import unittest - -from copy import deepcopy - -import sys, os, inspect -sys.path.append(os.path.abspath( - os.path.dirname(inspect.getfile(inspect.currentframe()))+"/../src/monk_tf")) - -from connection import Connection -import serial_conn -import ssh_conn - -# -# MOCKING -# - -# --- mocked functions --- - -class MockSerialConn(object): - instance = None - __called = { "__init__" : [], - "open" : [], - "cmd" : [] } - called = {} - - def __init__(self, login, skip_pass, boot_prompt, reset_cb): - MockSerialConn.called["__init__"].append( - (login, skip_pass, boot_prompt, reset_cb) ) - MockSerialConn.instance = self - - def open(self): - MockSerialConn.called["open"].append(True) - - def cmd(self, cmd): - MockSerialConn.called["cmd"].append(cmd) - if MOCK_sercmd_raise: - raise MOCK_sercmd_raise - return 0, MOCK_sercmd_ret - - -class MockSshConn(object): - - instance = None - - __called = { "__init__" : [], - "cmd" : [] } - called = {} - - def __init__(self, host, login): - MockSshConn.called["__init__"].append((host, login)) - MockSshConn.instance = self - - def cmd(self, cmd): - MockSshConn.called["cmd"].append(cmd) - if MOCK_sshcmd_raise: - raise MOCK_sshcmd_raise - return 0, MOCK_sshcmd_ret - -# --- mock helper variables and functions --- - -MOCK_sercmd_ret = "" -MOCK_sercmd_raise = None -MOCK_sshcmd_ret = "" -MOCK_sshcmd_raise = None - -def mock_reset_values(): - global MOCK_sercmd_raise, MOCK_sercmd_ret, MOCK_sshcmd_raise, MOCK_sshcmd_ret - MOCK_sercmd_raise = None - MOCK_sercmd_ret = "" - MOCK_sshcmd_raise = None - MOCK_sshcmd_ret = "" - MockSshConn.called = deepcopy(MockSshConn._MockSshConn__called) - MockSshConn.instance = None - MockSerialConn.called = deepcopy(MockSerialConn._MockSerialConn__called) - MockSerialConn.instance = None - -orig_serial_conn = serial_conn.SerialConn -orig_ssh_conn = ssh_conn.SshConn - -def mock_on(): - mock_reset_values() - serial_conn.SerialConn = MockSerialConn - ssh_conn.SshConn = MockSshConn - -def mock_off(): - serial_conn.SerialConn = orig_serial_conn - ssh_conn.SshConn = orig_ssh_conn - -# --- mocking ENDs --- - -# -# The actual tests -# - -class TestConnection(unittest.TestCase): - """ This class implements a number of default test cases - for the connection class.""" - - def setUp(self): - mock_on() - - def tearDown(self): - mock_off() - - - def test_default_init(self): - """ Test the default initialization. - This will implicitly test _serial_setup() as well. """ - c = Connection(network_setup = ("hurz", "bla-if0")) - - # check instance vars - self.assertEquals(c._login, ("root", "")) - self.assertEquals(c._target_if, "bla-if0") - self.assertEquals(c._serial, MockSerialConn.instance) - self.assertEquals(c.host, "hurz") - - # check initialisation of serial_conn class - self.assertEquals(len(MockSerialConn.called["__init__"]), 1) - self.assertEquals(MockSerialConn.called["__init__"][0], - (c._login, True, "HidaV boot on", None)) - self.assertEquals(len(MockSerialConn.called["open"]), 1) - self.assertEquals(MockSerialConn.called["open"][0], True) - - - def __ssh_test(self, c): - s = c._ssh - self.assertEquals(len(MockSshConn.called["__init__"]), 1) - self.assertEquals(MockSshConn.called["__init__"][0], (c.host, c._login)) - - def test_ssh(self): - """ Test for the ssh property. """ - c = Connection(network_setup = ("horst", "if-fi0")) - self.__ssh_test(c) - - # check for no initialization the second time 'round - MockSshConn.called["__init__"] = [] - s = c._ssh - self.assertEquals(len(MockSshConn.called["__init__"]), 0) - - # check for re-init after the property has been deleted - del c._ssh - self.__ssh_test(c) - - - def test_host(self): - """ Unittest for the host property. """ - c = Connection() - - # first, let the connection figure out the hot IP by itself - global MOCK_sercmd_ret - MOCK_sercmd_ret = "534.117.9.15" - self.assertEquals(c.host, MOCK_sercmd_ret) - - # then, check whether we can set it - c.host = "www.heise.de" - self.assertEquals(c.host, "www.heise.de") - - # finally: check the deleter and the getter's exception handling - del c.host - MOCK_sercmd_ret = "unparseable IP address" - self.assertRaises(Exception, lambda: c.host) - del c.host - - - def test_cmd(self): - """ Test for the command dispatcher. """ - global MOCK_sercmd_ret, MOCK_sshcmd_ret, MOCK_sshcmd_raise - MOCK_sercmd_ret = "Serial command execution" - MOCK_sshcmd_ret = "SSH command execution" - - c = Connection(network_setup = ("hurz", "bla-if0")) - MockSerialConn.called = deepcopy(MockSerialConn._MockSerialConn__called) - - # check for ssh command execution - self.assertEquals(c.cmd("test-command"), (0, MOCK_sshcmd_ret)) - - self.assertEquals(len(MockSshConn.called["cmd"]), 1) - self.assertEquals(MockSshConn.called["cmd"][0], "test-command") - self.assertEquals(len(MockSerialConn.called["cmd"]), 0) - - # generate an exception for ssh to check for serial execution - MOCK_sshcmd_raise = Exception() - self.assertEquals(c.cmd("test-2-command"), (0, MOCK_sercmd_ret)) - self.assertEquals(MockSerialConn.called["cmd"][0], "test-2-command") - self.assertEquals(len(MockSerialConn.called["cmd"]), 1) - - - def test_has_networking(self): - """ Test for the networking availability checker. """ - global MOCK_sercmd_ret - - c = Connection() - self.assertFalse(c.has_networking()) - - MOCK_sercmd_ret = "123.456.789.012" - self.assertTrue(c.has_networking()) - - -if __name__ == "__main__": - unittest.main() - diff --git a/test/test_device.py b/test/test_device.py deleted file mode 100755 index 9e0127a..0000000 --- a/test/test_device.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# MONK Automated Testing Framework -# -# Copyright (C) 2012 DResearch Fahrzeugelektronik GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version -# 2 of the License, or (at your option) any later version. -# - - -import sys, os, inspect -sys.path.append(os.path.abspath( - os.path.dirname(inspect.getfile(inspect.currentframe()))+"/../src/monk_tf")) - -import unittest - -class TestDevice(unittest.TestCase): - pass - - -if __name__ == '__main__': - unittest.main() diff --git a/test/test_devicetestcase.py b/test/test_devicetestcase.py deleted file mode 100755 index 8c91efe..0000000 --- a/test/test_devicetestcase.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# MONK Automated Testing Framework -# -# Copyright (C) 2012 DResearch Fahrzeugelektronik GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version -# 2 of the License, or (at your option) any later version. -# - - -import unittest - -import sys, os, inspect -sys.path.append(os.path.abspath( - os.path.dirname(inspect.getfile(inspect.currentframe()))+"/../src/monk_tf")) - -import device -from devicetestcase import DeviceTestCase - -# -# MOCKING -# - -# --- mocked functions --- - -class MockDevice(object): - def __init__(self, devtype): - pass - def reboot(self, to_nand): - pass - -# --- mock helper variables and functions --- - -orig_device = device.Device - - -def mock_reset_values(): - pass - -def mock_on(): - device.Device = MockDevice - -def mock_off(): - device.Device = orig_device - -# --- mocking ENDs --- - -# -# The actual tests -# - -class TestDevicetestcase(unittest.TestCase): - """ This class implements a number of default test cases - for the devicetestcase class.""" - def setUp(self): - mock_on() - - def tearDown(self): - mock_off() - - - def test_get_device(self): - dev = DeviceTestCase.get_device( "test-dev" ) - - - -if __name__ == '__main__': - unittest.main() diff --git a/test/test_serial_conn.py b/test/test_serial_conn.py old mode 100755 new mode 100644 index 0818b15..e5775aa --- a/test/test_serial_conn.py +++ b/test/test_serial_conn.py @@ -1,26 +1,24 @@ -#!/usr/bin/env python # -*- coding: utf-8 -*- # # MONK Automated Testing Framework # -# Copyright (C) 2012 DResearch Fahrzeugelektronik GmbH +# Copyright (C) 2012-2013 DResearch Fahrzeugelektronik GmbH, project-monk@dresearch-fe.de # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version -# 2 of the License, or (at your option) any later version. +# 3 of the License, or (at you option) any later version. # +from nose import tools as nt +from monk_tf import serial_conn as msc -import sys, os, inspect -sys.path.append(os.path.abspath( - os.path.dirname(inspect.getfile(inspect.currentframe()))+"/../src/monk_tf")) - -import unittest - -class TestSerialConn(unittest.TestCase): - pass - - -if __name__ == '__main__': - unittest.main() +def test_simple(): + """checks if creating a SerialConn object works + """ + #nothing to prepare + # + #execute + sut = msc.SerialConn() + #assert + nt.ok_(sut, "should contain a monk_tf.serial_conn.SerialConn object, but instead contains this: '{}'".format(sut)) diff --git a/test/test_ssh_conn.py b/test/test_ssh_conn.py deleted file mode 100755 index e200777..0000000 --- a/test/test_ssh_conn.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# MONK Automated Testing Framework -# -# Copyright (C) 2012 DResearch Fahrzeugelektronik GmbH -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version -# 2 of the License, or (at your option) any later version. -# - - -import sys, os, inspect -sys.path.append(os.path.abspath( - os.path.dirname(inspect.getfile(inspect.currentframe()))+"/../src/monk_tf")) - -import unittest - -class TestSshConn(unittest.TestCase): - pass - -if __name__ == '__main__': - unittest.main()