コード例 #1
0
    def test_update_template_variables(self):
        """
		It checks that we are able to update the following variables
		of a template:
		- {#FOLDER_LOCATION#}
		- {#APP_FOLDER#}
		- {#BUILD_COMMAND#}
		"""

        l = LogCapture()

        template.upload_folder = "."

        # We prepare the file that we are going to use for the tests
        with open("test_update_template_variables.txt", "w") as text_file:
            print("Test test test file...", file=text_file)
            print("some text{#FOLDER_LOCATION#}...", file=text_file)
            print("Test test test file...", file=text_file)
            print("Test {#APP_FOLDER#}test {#FOLDER_LOCATION#}...",
                  file=text_file)
            print("Test test test file...", file=text_file)
            print("{#APP_FOLDER#} test {#BUILD_COMMAND#} file...",
                  file=text_file)
            print("end of file", file=text_file)

        destination_template = template.update_template(
            "test_update_template_variables.txt", "gcc -x1", "/home/pepito",
            "application")

        # We read all the lines
        lines = [line.rstrip('\n') for line in open(destination_template)]

        self.assertEquals("Test test test file...", lines[0])
        self.assertEquals("some text/home/pepito...", lines[1])
        self.assertEquals("Test test test file...", lines[2])
        self.assertEquals("Test applicationtest /home/pepito...", lines[3])
        self.assertEquals("Test test test file...", lines[4])
        self.assertEquals("application test gcc -x1 file...", lines[5])
        self.assertEquals("end of file", lines[6])

        # We clean after the test
        os.remove("test_update_template_variables.txt")
        os.remove(destination_template)

        # We verify the name follows the righ nomenclature
        filename = os.path.basename(destination_template)
        log_string = 'Template generated on: ./' + filename
        filename = filename[:-4]

        try:
            val = UUID(filename, version=4)
        except ValueError:
            self.fail("Filname is not uuid4 complaint: " + filename)

        # Checking that we are logging the correct messages
        l.check((
            'root', 'INFO',
            'Creating singulartiy template using file: test_update_template_variables.txt'
        ), ('root', 'INFO', log_string))
        l.uninstall()
コード例 #2
0
ファイル: shell_tests.py プロジェクト: TANGO-Project/alde
    def test_raise_exception(self, mock_subprocess):
        """
        It verifies that an exception is raised when an error occours when
        exectuting a command, the exception will be handled latar own
        by the script that uses this function
        """

        l = LogCapture() # we cature the logger

        error = subprocess.CalledProcessError(returncode=255, cmd="ls", output="failed")
        mock_subprocess.side_effect = error

        self.assertRaises(subprocess.CalledProcessError,
                          shell.execute_command,
                          command="ls",
                          params=["-la", "."])

        # Checking that we are logging the correct messages
        l.check(
            ('root', 'INFO', 'Executing: ls -la .'),
            ('root', 'ERROR', "Trying to execute command:  ls -la ."),
            ('root', 'ERROR', "Error: Command 'ls' returned non-zero exit status 255."),
            ('root', 'ERROR', "failed"),
            ('root', 'ERROR', 'Trying to execute command at server ')
            )
        l.uninstall() # We uninstall the capture of the logger
コード例 #3
0
 def test_move(self):
     l = LogCapture(names="drivar.DrivarNoop",
                    install=False,
                    level=logging.DEBUG)
     drivar = DrivarNoop()
     drivar.initialize()
     adapter = PahoMqttAdapter(drivar)
     # Test that messages get interpreted correctly
     adapter.start()
     l.install()
     params = {'speed': Drivar.SPEED_FAST}
     self.client.publish("scene/robot/drivar/command/motor/move",
                         json.dumps(params), 0, True)
     time.sleep(1)
     l.check(
         ('drivar.DrivarNoop', 'INFO',
          'Drivar : Moving all wheels with power ' +
          str(DrivarNoop._getMotorPowerLevel(params['speed'])) + '.'),
         ('drivar.DrivarNoop', 'INFO', 'Drivar : Stopping the vehicle.'))
     l.clear()
     self.client.publish("scene/robot/drivar/command/motor/turn", "", 0,
                         True)
     time.sleep(1)
     l.check(('drivar.DrivarNoop', 'INFO',
              'Drivar : Turning the vehicle left by 90 degrees.'))
     l.uninstall()
コード例 #4
0
class Test(unittest.TestCase):

    def setUp(self):
        from testfixtures import LogCapture
        self.log_capture = LogCapture()
        self.log_group  = "phidgeter.ir_temperature"
        self.lvl = "DEBUG"

    def tearDown(self):
        self.log_capture.uninstall()

    def test_log_captures(self):
        # verification of log matching functionality
        from logging import getLogger
        getLogger().info("a message")
        self.log_capture.check(("root", "INFO", "a message"))

    def test_sensor_is_available(self):
        ir_temp = IRSensor()
        assert ir_temp.open_phidget() == True
        assert ir_temp.get_temperature() >= 0.0
        assert ir_temp.close_phidget() == True

    def test_sensor_is_room_temperature(self):
        ir_temp = IRSensor()
        assert ir_temp.open_phidget() == True
        print ir_temp.get_temperature()
        assert ir_temp.get_temperature() >= 20.0
        assert ir_temp.close_phidget() == True
コード例 #5
0
def connectTo():
    gearkey = "qnlgzsPUUxYeyQP"
    gearsecret = "1euJPvxybllEPQZzq2u9wpRJXDbjM7"
    appid = "testNo3"    
    client.create(gearkey, gearsecret, appid, {'debugmode': "True"})
    
    def on_connected():
        print("connect")
    def on_closed():
        print("close")  
    def on_rejected():
        print("reject")     
    def on_error():
        print("error")  
    def on_message():
        print("message")  
    def on_present():
        print("present")
    def on_absent():
        print("absent") 
    client.on_connect = on_connected
    client.on_error = on_error
    client.on_present = on_present
    client.on_absent = on_absent
    client.on_rejected = on_rejected
    client.on_closed = on_closed
    client.on_message = on_message
    logs = LogCapture()
    client.connect()
    print(logs)
    logs.check(('root', 'DEBUG', 'Check stored token.'))
コード例 #6
0
ファイル: ranking_tests.py プロジェクト: TANGO-Project/alde
    def test_read_csv_first_line(self):
        """
        It checks that it is possible to read the line with an specific exeuction id of a csv file
        """

        l = LogCapture()  # we cature the logger

        file = 'Time_Ranking.csv'

        line = ranking._read_ranking_info(file, 7332)

        self.assertEqual('Matmul', line[0])
        self.assertEqual('5851', line[1])
        self.assertEqual('20', line[2])
        self.assertEqual('7332', line[3])
        self.assertEqual('20', line[4])

        # inexistent file test
        file = 'no_file.csv'

        line = ranking._read_ranking_info(file, 7332)
        self.assertEqual([], line)

        # Execution id does not exists
        file = 'Time_Ranking.csv'

        line = ranking._read_ranking_info(file, 11)
        self.assertEqual([], line)

        l.check(('root', 'ERROR', "Could not read file: no_file.csv"))
        l.uninstall()  # We uninstall the capture of the logger
コード例 #7
0
class TestPickleSerializer(unittest.TestCase):

    layer = ZAMQP_FUNCTIONAL_TESTING

    def setUp(self):
        from testfixtures import LogCapture
        self.l = LogCapture("c.zamqp.tests")

    def tearDown(self):
        self.l.uninstall()

    def _testDeclareQueue(self):
        rabbitctl = self.layer['rabbitctl']
        self.assertIn("my.picklequeue\t0",
                      rabbitctl('list_queues')[0].split("\n"))

    def testDeclareQueue(self):
        runAsyncTest(self._testDeclareQueue)

    def _testDeclareQueueAgain(self):
        rabbitctl = self.layer['rabbitctl']
        self.assertIn("my.picklequeue\t0",
                      rabbitctl('list_queues')[0].split("\n"))

    def testDeclareQueueAgain(self):
        runAsyncTest(self._testDeclareQueueAgain)

    def _testPublishToQueue(self):
        rabbitctl = self.layer['rabbitctl']
        self.assertIn("my.picklequeue\t1",
                      rabbitctl('list_queues')[0].split("\n"))

    def _testPublishToQueueAndConsumeIt(self):
        rabbitctl = self.layer['rabbitctl']
        self.assertIn("my.picklequeue\t0",
                      rabbitctl('list_queues')[0].split("\n"))

    def testPublishToQueueAndConsumeIt(self):
        runAsyncTest(self._testDeclareQueue)

        from zope.component import getUtility
        from collective.zamqp.interfaces import IProducer
        producer = getUtility(IProducer, name="my.picklequeue")
        producer.publish({"key": "value"})

        runAsyncTest(self._testPublishToQueue)
        runAsyncTest(self._testPublishToQueueAndConsumeIt)
        self.l.check(
            ('c.zamqp.tests', 'INFO',
             "<BasicProperties(['delivery_mode=2', "
             "'content_type=application/x-python-serialize'])>"),
            ('c.zamqp.tests', 'INFO', "{'key': 'value'}"),
            ('c.zamqp.tests', 'INFO', "<type 'dict'>")
        )
コード例 #8
0
class TestComponentResolving(unittest.TestCase):
    def setUp(self):
        self.l = LogCapture()
        
    def tearDown(self):
        self.l.uninstall()
        
    def test_that_resolve_does_not_warn_if_component_list_empty(self):
        root = ET.Element('component')
        op = ComponentParser()
        
        op.parse(root)
        op.resolve([])
        
        assert_that(self.l.__str__(), is_("No logging captured"))
        
    def test_that_resolve_does_not_warn_if_all_categories_found(self):
        category_name = 'something'
        category = MockCategory(category_name)
        name = 'sample component'
        root = _component_tree_with_category(category_name, name)
        op = ComponentParser()
        
        op.parse(root)
        op.resolve([category])
        
        assert_that(self.l.__str__(), is_("No logging captured"))
        
    def test_that_resolve_links_to_category(self):
        category_name = 'something'
        category = MockCategory(category_name)
        name = 'sample component'
        root = _component_tree_with_category(category_name, name)
        op = ComponentParser()
        
        op.parse(root)
        op.resolve([category])
        result = op.components[name]
        
        assert_that(result.category(category_name), is_(same_instance(category)))
        assert_that(category.set_component_was_called, is_(True))
        assert_that(category.component, is_(same_instance(result)))
        
    def test_that_resolve_warns_if_category_referenced_which_does_not_exist(self):
        category = 'something'
        name = 'sample component'
        root = _component_tree_with_category(category, name)
        op = ComponentParser()
        
        op.parse(root)
        op.resolve([])
        
        self.l.check(('root', 'WARNING', "Component '{0}' references undefined category '{1}'".format(name, category)))
コード例 #9
0
class TestPickleSerializer(unittest.TestCase):

    layer = ZAMQP_FUNCTIONAL_TESTING

    def setUp(self):
        from testfixtures import LogCapture
        self.l = LogCapture("c.zamqp.tests")

    def tearDown(self):
        self.l.uninstall()

    def _testDeclareQueue(self):
        rabbitctl = self.layer['rabbitctl']
        self.assertIn("my.picklequeue\t0",
                      rabbitctl('list_queues')[0].split("\n"))

    def testDeclareQueue(self):
        runAsyncTest(self._testDeclareQueue)

    def _testDeclareQueueAgain(self):
        rabbitctl = self.layer['rabbitctl']
        self.assertIn("my.picklequeue\t0",
                      rabbitctl('list_queues')[0].split("\n"))

    def testDeclareQueueAgain(self):
        runAsyncTest(self._testDeclareQueueAgain)

    def _testPublishToQueue(self):
        rabbitctl = self.layer['rabbitctl']
        self.assertIn("my.picklequeue\t1",
                      rabbitctl('list_queues')[0].split("\n"))

    def _testPublishToQueueAndConsumeIt(self):
        rabbitctl = self.layer['rabbitctl']
        self.assertIn("my.picklequeue\t0",
                      rabbitctl('list_queues')[0].split("\n"))

    def testPublishToQueueAndConsumeIt(self):
        runAsyncTest(self._testDeclareQueue)

        from zope.component import getUtility
        from collective.zamqp.interfaces import IProducer
        producer = getUtility(IProducer, name="my.picklequeue")
        producer.publish({"key": "value"})

        runAsyncTest(self._testPublishToQueue)
        runAsyncTest(self._testPublishToQueueAndConsumeIt)
        self.l.check(
            ('c.zamqp.tests', 'INFO', "<BasicProperties(['delivery_mode=2', "
             "'content_type=application/x-python-serialize'])>"),
            ('c.zamqp.tests', 'INFO', "{'key': 'value'}"),
            ('c.zamqp.tests', 'INFO', "<type 'dict'>"))
コード例 #10
0
    def test_move(self):
        l = LogCapture()

        drivar = DrivarNoop()
        drivar.initialize()
        drivar.motor_move()
        l.check(
            ('drivar.DrivarNoop', 'DEBUG', 'Drivar : initialized'),
            ('drivar.DrivarNoop', 'INFO',
             'Drivar : Moving all wheels with power 70.'),
            ('drivar.DrivarNoop', 'INFO', 'Drivar : Stopping the vehicle.'))
        drivar.motor_turn()

        l.uninstall_all()
コード例 #11
0
class TestConstrain(TestCase):

    def setUp(self):
        self._versions = {}
        self.i=FakeInstaller(self._versions)
        self.logging = LogCapture('zc.buildout.easy_install')

    def tearDown(self):
        self.logging.uninstall()

    def _check(self,requirement,expected):
        result = _constrain(
            self.i,
            tuple(parse_requirements(requirement))[0]
            )
        self.failUnless(isinstance(result,Requirement))
        compare(expected,str(result))
        
    def test_normal(self):
        self._versions['a-package']='1.0'
        self._check('a_package','a-package==1.0')
        self.logging.check()
    
    def test_extras(self):
        self._versions['a-package']='1.0'
        self._check('a_package[some,thing]',
                    'a-package[some,thing]==1.0')
        self.logging.check()
    
    def test_capitalisation(self):
        self._versions['a-package']='1.0'
        self._check('A-Package','A-Package==1.0')
        self.logging.check()

    def test_no_version(self):
        self._check('a_package','a-package')
        self.logging.check()
    
    def test_incompatible_version(self):
        self._versions['a-package']='1.0'
        with ShouldRaise(IncompatibleVersionError(
                'Bad version','1.0'
                )):
            self._check('a-package==2.0','xxx')
        self.logging.check(
            ('zc.buildout.easy_install',
             'ERROR',
             "The version, 1.0, is not consistent with"
             " the requirement, 'a-package==2.0'.")
            )
コード例 #12
0
    def test_process_needs_sigkill(self):
        """Test cases where send_signal must be called multiple times."""
        log = LogCapture('gateway_code', level=logging.WARNING)
        self.addCleanup(log.uninstall)

        only_sigkill = f'python {os.path.join(CURRENT_DIR, "only_sigkill.py")}'

        with mock.patch.object(_DummyProcess, 'PROC', only_sigkill):
            m_process = _DummyProcess()
            m_process.start()
            time.sleep(5)
            m_process.stop()

        log.check(('gateway_code', 'WARNING',
                   'External process signal: escalading to SIGKILL'))
コード例 #13
0
    def test_socat_needs_sigkill(self):
        """Test cases where send_signal must be called multiple times."""
        log = LogCapture('gateway_code', level=logging.WARNING)
        self.addCleanup(log.uninstall)

        only_sigkill = os.path.join(CURRENT_DIR, 'only_sigkill.py')
        only_sigkill = 'python %s' % only_sigkill

        with mock.patch.object(SerialRedirection, 'SOCAT', only_sigkill):
            self.redirect = SerialRedirection(self.tty, self.baud)
            self.redirect.start()
            time.sleep(5)
            self.redirect.stop()

        log.check(('gateway_code', 'WARNING',
                   'SerialRedirection signal: escalading to SIGKILL'))
コード例 #14
0
    def test_socat_needs_sigkill(self):
        """Test cases where send_signal must be called multiple times."""
        log = LogCapture('gateway_code', level=logging.WARNING)
        self.addCleanup(log.uninstall)

        only_sigkill = os.path.join(CURRENT_DIR, 'only_sigkill.py')
        only_sigkill = 'python %s' % only_sigkill

        with mock.patch.object(SerialRedirection, 'SOCAT', only_sigkill):
            self.redirect = SerialRedirection(self.tty, self.baud)
            self.redirect.start()
            time.sleep(1)
            self.redirect.stop()

        log.check(('gateway_code', 'WARNING',
                   'SerialRedirection signal: escalading to SIGKILL'))
コード例 #15
0
ファイル: test_request.py プロジェクト: ryansanford/core
class TestRequest(unittest.TestCase):
    def setUp(self):
        self.log_capture = LogCapture()
        self.request = api.web.request.SciTranRequest({})

    def tearDown(self):
        LogCapture.uninstall_all()

    def test_request_id(self):
        self.assertEqual(len(self.request.id), 19)

    def test_request_logger_adapter(self):
        test_log_message = "test log message"
        self.request.logger.error(test_log_message)
        expected_log_output = "{0} request_id={1}".format(
            test_log_message, self.request.id)
        self.log_capture.check(('scitran.api', 'ERROR', expected_log_output))
コード例 #16
0
    def testLoadConfig(self):
        """
        check that the config loading works properly
        :return:
        """
        # check if it is complaining about not having a json
        l = LogCapture('sync-cass-elastic')
        _ = PyCassElastic()
        l.check(('sync-cass-elastic', 'WARNING',
                 'No config file passed for the sync class'), )
        l.clear()

        # check if it has setup correctly
        sync = PyCassElastic(self.config)

        # assert the last time log file is created properly
        os.remove(sync.lastRunFileName) if os.path.exists(
            sync.lastRunFileName) else None
        self.assertRaises(IOError, sync.setup)
        with open(sync.lastRunFileName, 'w') as f:
            f.write(' ')
        self.assertRaises(ValueError, sync.setup)

        # check connection
        l.clear()
        minutes_ago = self._createLastRunFile()
        sync.setup()
        l.check(
            ('sync-cass-elastic', 'DEBUG',
             u"Connected to Cassandra: [u'localhost'] / test"),
            ('sync-cass-elastic', 'DEBUG',
             u"Connected to Elasticsearch: [u'localhost']"),
        )
        self.assertEqual(minutes_ago.strftime('%Y%m%d %H:%M'),
                         sync.time_last_run.strftime('%Y%m%d %H:%M'),
                         'The time should be the same')
        self.assertNotEqual(sync.time_this_run, None,
                            'Time of this run should be filled')
        self.assertNotEqual(sync.time_delta, None,
                            'Time of this run should be filled')

        # get rid of the logger checker
        l.uninstall()
        os.remove(sync.lastRunFileName) if os.path.exists(
            sync.lastRunFileName) else None
コード例 #17
0
ファイル: test_request.py プロジェクト: scitran/core
class TestRequest(unittest.TestCase):
    def setUp(self):
        self.log_capture = LogCapture()
        self.request = api.web.request.SciTranRequest({})

    def tearDown(self):
        LogCapture.uninstall_all()

    def test_request_id(self):
        self.assertEqual(len(self.request.id), 19)

    def test_request_logger_adapter(self):
        test_log_message = "test log message"
        self.request.logger.error(test_log_message)
        expected_log_output = "{0} request_id={1}".format(
            test_log_message, self.request.id
        )
        self.log_capture.check(('scitran.api', 'ERROR', expected_log_output))
コード例 #18
0
ファイル: slurm_tests.py プロジェクト: TANGO-Project/alde
    def test_check_nodes_in_db_for_on_line_testbeds(self, mock_get_nodes):
        """
        Test the correct work of this function
        """
        l = LogCapture()  # we cature the logger

        # We store some data in the db for the test.
        testbed, node_1, node_2 = self._create_initial_db_data()

        #We create the expectation to retrieve a list of nodes from slurm.
        node_3 = {'node_name': 'node_3'}
        node_1_slurm = {'node_name': 'node_1'}
        mock_get_nodes.return_value = [node_1_slurm, node_3]

        # We exectue the command
        slurm.check_nodes_in_db_for_on_line_testbeds()

        # We check we get the desired result
        node = db.session.query(Node).filter_by(name='node_3').all()
        self.assertEquals(1, len(node))
        node = node[0]
        self.assertEquals('node_3', node.name)
        self.assertTrue(node.information_retrieved)
        self.assertEquals(3, len(testbed.nodes))

        node = db.session.query(Node).filter_by(name='node_1').all()
        self.assertEquals(1, len(node))
        node = node[0]
        self.assertFalse(node.disabled)

        node = db.session.query(Node).filter_by(name='node_2').all()
        self.assertEquals(1, len(node))
        node = node[0]
        self.assertTrue(node.disabled)

        # Checking that we are logging the correct messages
        l.check(
            ('root', 'INFO', 'Checking node info for testbed: name1'),
            ('root', 'INFO', 'Adding a new node: node_3 to testbed: name1'),
            ('root', 'INFO', 'Enabling node: node_1'),
            ('root', 'INFO', 'Disabling node: node_2'))
        l.uninstall()  # We uninstall the capture of the logger
コード例 #19
0
class TestElfTargetIsCompatibleWithNode(unittest.TestCase):
    """Test elftarget.is_compatible_with_node."""

    def setUp(self):
        self.m3_class = mock.Mock()
        self.m3_class.ELF_TARGET = ('ELFCLASS32', 'EM_ARM')
        self.log = LogCapture('gateway_code', level=logging.DEBUG)

    def tearDown(self):
        self.log.uninstall()

    def test_m3_like_elf_check(self):
        """Test elftarget for an m3 like node."""
        ret = elftarget.is_compatible_with_node(firmware('idle_m3.elf'),
                                                self.m3_class)
        self.assertTrue(ret)
        self.log.check()

        # invalid target
        ret = elftarget.is_compatible_with_node(firmware('node.z1'),
                                                self.m3_class)
        self.assertFalse(ret)
        self.log.check()

        # invalid, not elf file
        ret = elftarget.is_compatible_with_node(
            firmware('wsn430_print_uids.hex'), self.m3_class)
        self.assertFalse(ret)
        self.log.check(('gateway_code', 'WARNING',
                        'Invalid firmware: Not a valid elf file'))
コード例 #20
0
class TestElfTargetIsCompatibleWithNode(unittest.TestCase):
    """Test elftarget.is_compatible_with_node."""
    def setUp(self):
        self.m3_class = mock.Mock()
        self.m3_class.ELF_TARGET = ('ELFCLASS32', 'EM_ARM')
        self.log = LogCapture('gateway_code', level=logging.DEBUG)

    def tearDown(self):
        self.log.uninstall()

    def test_m3_like_elf_check(self):
        """Test elftarget for an m3 like node."""
        ret = elftarget.is_compatible_with_node(firmware('m3_idle.elf'),
                                                self.m3_class)
        self.assertTrue(ret)
        self.log.check()

        # invalid target
        ret = elftarget.is_compatible_with_node(firmware('node.z1'),
                                                self.m3_class)
        self.assertFalse(ret)
        self.log.check()

        # invalid, not elf file
        ret = elftarget.is_compatible_with_node(
            firmware('wsn430_print_uids.hex'), self.m3_class)
        self.assertFalse(ret)
        self.log.check(('gateway_code', 'WARNING',
                        'Invalid firmware: Not a valid elf file'))
コード例 #21
0
class DatabaseHandlerTests(TestCase):

    def setUp(self):
        self.dir = TempDirectory()
        self.db_path = self.dir.getpath('test.db')
        self.conn = sqlite3.connect(self.db_path)
        self.conn.execute('create table notes '
                          '(filename varchar, text varchar)')
        self.conn.commit()
        self.log = LogCapture()
        
    def tearDown(self):
        self.log.uninstall()
        self.dir.cleanup()
        
    def test_normal(self):
        with DatabaseHandler(self.db_path) as handler:
            handler.conn.execute('insert into notes values (?, ?)',
                                 ('test.txt', 'a note'))
            handler.conn.commit()
        # check the row was inserted and committed
        curs = self.conn.cursor()
        curs.execute('select * from notes')
        self.assertEqual(curs.fetchall(), [('test.txt', 'a note')])
        # check there was no logging
        self.log.check()

    def test_exception(self):
        with ShouldRaise(Exception('foo')):
            with DatabaseHandler(self.db_path) as handler:
                handler.conn.execute('insert into notes values (?, ?)',
                                     ('test.txt', 'a note'))
                raise Exception('foo')
        # check the row not inserted and the transaction was rolled back
        curs = handler.conn.cursor()
        curs.execute('select * from notes')
        self.assertEqual(curs.fetchall(), [])
        # check the error was logged
        self.log.check(('root', 'ERROR', 'Something went wrong'))
コード例 #22
0
class TestHandleAnswer(unittest.TestCase):

    def setUp(self):
        self.cn = cn_interface.ControlNodeSerial('tty')
        self.log = LogCapture('gateway_code', level=logging.DEBUG)

    def tearDown(self):
        self.log.uninstall()

    def test_config_ack(self):
        self.cn._handle_answer('config_ack set_time 0.123456')
        self.log.check(
            ('gateway_code', 'DEBUG', 'config_ack set_time'),
            ('gateway_code', 'INFO', 'Control Node set time delay: 123456 us')
        )

        self.log.clear()
        self.cn._handle_answer('config_ack anything')
        self.log.check(
            ('gateway_code', 'DEBUG', 'config_ack anything'),
        )

    def test_error(self):
        self.cn._handle_answer('error 42')
        self.log.check(
            ('gateway_code', 'ERROR', 'Control node error: %r' % '42'))

    def test_cn_serial_error(self):
        self.cn._handle_answer('cn_serial_error: any error msg')
        self.log.check(
            ('gateway_code', 'ERROR', 'cn_serial_error: any error msg'))

    def test_measures_debug(self):
        msg = ('measures_debug: consumption_measure 1377268768.841070:'
               '1.78250 0.000000 3.230000 0.080003')

        m_debug = mock.Mock()

        self.cn.measures_debug = m_debug
        self.cn._handle_answer(msg)
        m_debug.assert_called_with(msg)

        m_debug.reset_mock()
        self.cn.measures_debug = None
        self.cn._handle_answer(msg)
        self.assertFalse(m_debug.called)
コード例 #23
0
class TestHandleAnswer(unittest.TestCase):

    def setUp(self):
        self.cn = cn_interface.ControlNodeSerial('tty')
        self.log = LogCapture('gateway_code', level=logging.DEBUG)

    def tearDown(self):
        self.log.uninstall()

    def test_config_ack(self):
        self.cn._handle_answer('config_ack set_time 0.123456')
        self.log.check(
            ('gateway_code', 'DEBUG', 'config_ack set_time'),
            ('gateway_code', 'INFO', 'Control Node set time delay: 123456 us')
        )

        self.log.clear()
        self.cn._handle_answer('config_ack anything')
        self.log.check(
            ('gateway_code', 'DEBUG', 'config_ack anything'),
        )

    def test_error(self):
        self.cn._handle_answer('error 42')
        self.log.check(
            ('gateway_code', 'ERROR', 'Control node error: %r' % '42'))

    def test_cn_serial_error(self):
        self.cn._handle_answer('cn_serial_error: any error msg')
        self.log.check(
            ('gateway_code', 'ERROR', 'cn_serial_error: any error msg'))

    def test_measures_debug(self):
        msg = ('measures_debug: consumption_measure 1377268768.841070:'
               '1.78250 0.000000 3.230000 0.080003')

        m_debug = mock.Mock()

        self.cn.measures_debug = m_debug
        self.cn._handle_answer(msg)
        m_debug.assert_called_with(msg)

        m_debug.reset_mock()
        self.cn.measures_debug = None
        self.cn._handle_answer(msg)
        self.assertFalse(m_debug.called)
コード例 #24
0
class DatabaseHandlerTests(TestCase):
    def setUp(self):
        self.dir = TempDirectory()
        self.addCleanup(self.dir.cleanup)
        self.db_path = self.dir.getpath('test.db')
        self.conn = sqlite3.connect(self.db_path)
        self.conn.execute('create table notes '
                          '(filename varchar, text varchar)')
        self.conn.commit()
        self.log = LogCapture()
        self.addCleanup(self.log.uninstall)

    def test_normal(self):
        with DatabaseHandler(self.db_path) as handler:
            handler.conn.execute('insert into notes values (?, ?)',
                                 ('test.txt', 'a note'))
            handler.conn.commit()
        # check the row was inserted and committed
        curs = self.conn.cursor()
        curs.execute('select * from notes')
        self.assertEqual(curs.fetchall(), [('test.txt', 'a note')])
        # check there was no logging
        self.log.check()

    def test_exception(self):
        with ShouldRaise(Exception('foo')):
            with DatabaseHandler(self.db_path) as handler:
                handler.conn.execute('insert into notes values (?, ?)',
                                     ('test.txt', 'a note'))
                raise Exception('foo')
        # check the row not inserted and the transaction was rolled back
        curs = handler.conn.cursor()
        curs.execute('select * from notes')
        self.assertEqual(curs.fetchall(), [])
        # check the error was logged
        self.log.check(('root', 'ERROR', 'Something went wrong'))
コード例 #25
0
ファイル: test_directory.py プロジェクト: dornheimer/gogtool
class TestLogging(unittest.TestCase):
    def setUp(self):
        self.capture = LogCapture()

    def tearDown(self):
        self.capture.uninstall()

    def test_init_invalid(self):
        with self.assertRaises(SystemExit) as cm:
            directory = Directory(INVALID_PATH)
            self.assertEqual(directory.path, None)

        self.assertTrue(cm.exception.code, 2)
        self.capture.check((
            'gogtool.helper.log', 'ERROR',
            f"Directory could not be initialized: '{INVALID_PATH}' does not exist."
        ))

    def test_init_valid(self):
        directory = Directory(VALID_PATH)
        self.assertEqual(directory.path, VALID_PATH)

        self.capture.check(('gogtool.helper.log', 'DEBUG',
                            f"Directory initialized with {VALID_PATH}"))
コード例 #26
0
class TestCheck(TestCase):

    def setUp(self):
        self.r = Replacer()
        self.l = LogCapture()

    def tearDown(self):
        self.l.uninstall()
        self.r.restore()

    def checker_returns(self,output):
        resolve = Mock()
        self.r.replace('checker.resolve',resolve)
        def the_checker(config_folder,param):
            return output
        resolve.return_value = the_checker
        return resolve
        
    def test_bad_checker(self):
        from checker import check
        check = should_raise(check,ImportError('No module named unknown'))
        check('/config','unknown',None)

    def test_normal(self):
        m = self.checker_returns('some output')
        check('/config','achecker',None)
        compare(m.call_args_list,[
                (('checker.checkers.achecker.check',), {})
                ])

    def test_log_newline(self):
        self.checker_returns('some output\n')
        check('/config','achecker','aparam')
        self.l.check(
            ('root', 'INFO', 'some output'),
            )

    def test_log_no_newline(self):
        self.checker_returns('some output')
        check('/config','achecker','aparam')
        self.l.check(
            ('root', 'INFO', 'some output'),
            )
        
    def test_no_log_empty(self):
        self.checker_returns('')
        check('/config','achecker','aparam')
        self.l.check()
コード例 #27
0
ファイル: test_main.py プロジェクト: pombredanne/checker
class TestCheck(TestCase):
    def setUp(self):
        self.r = Replacer()
        self.l = LogCapture()

    def tearDown(self):
        self.l.uninstall()
        self.r.restore()

    def checker_returns(self, output):
        resolve = Mock()
        self.r.replace('checker.check.resolve', resolve)

        def the_checker(config_folder, param):
            return output

        resolve.return_value = the_checker
        return resolve

    def test_bad_checker(self):
        with ShouldRaise(ImportError('No module named unknown')):
            check('/config', 'unknown', None)

    def test_normal(self):
        m = self.checker_returns('some output')
        check('/config', 'achecker', None)
        compare(m.call_args_list,
                [(('checker.checkers.achecker.check', ), {})])

    def test_log_newline(self):
        self.checker_returns('some output\n')
        check('/config', 'achecker', 'aparam')
        self.l.check(('root', 'INFO', 'some output'), )

    def test_log_no_newline(self):
        self.checker_returns('some output')
        check('/config', 'achecker', 'aparam')
        self.l.check(('root', 'INFO', 'some output'), )

    def test_no_log_empty(self):
        self.checker_returns('')
        check('/config', 'achecker', 'aparam')
        self.l.check()
コード例 #28
0
ファイル: test_main.py プロジェクト: Simplistix/checker
class TestCheck(TestCase):
    def setUp(self):
        self.r = Replacer()
        self.l = LogCapture()

    def tearDown(self):
        self.l.uninstall()
        self.r.restore()

    def checker_returns(self, output):
        resolve = Mock()
        self.r.replace("checker.check.resolve", resolve)

        def the_checker(config_folder, param):
            return output

        resolve.return_value = the_checker
        return resolve

    def test_bad_checker(self):
        with ShouldRaise(ImportError("No module named unknown")):
            check("/config", "unknown", None)

    def test_normal(self):
        m = self.checker_returns("some output")
        check("/config", "achecker", None)
        compare(m.call_args_list, [(("checker.checkers.achecker.check",), {})])

    def test_log_newline(self):
        self.checker_returns("some output\n")
        check("/config", "achecker", "aparam")
        self.l.check(("root", "INFO", "some output"))

    def test_log_no_newline(self):
        self.checker_returns("some output")
        check("/config", "achecker", "aparam")
        self.l.check(("root", "INFO", "some output"))

    def test_no_log_empty(self):
        self.checker_returns("")
        check("/config", "achecker", "aparam")
        self.l.check()
コード例 #29
0
ファイル: test_scripts.py プロジェクト: cjw296/mortar_rdb
class TestCreate(ScriptsMixin, PackageTest):
    def setUp(self):
        super(TestCreate, self).setUp()
        self.db_url = 'sqlite:///' + self.dir.getpath('sqlite.db')
        self.log = LogCapture()
        self.addCleanup(self.log.uninstall)

    def _setup_config(self):
        # setup
        metadata = MetaData()
        self.mytable = Table(
            'user',
            metadata,
            Column('id', Integer, primary_key=True),
        )
        self.config = Config(Source(self.mytable))

    def _check_db(self, expected_metadata):
        actual_metadata = MetaData(bind=create_engine(self.db_url))
        actual_metadata.reflect()
        # hmm, not much of a test right now, could do with more depth
        compare(expected_metadata.tables.keys(), actual_metadata.tables.keys())

    def test_url_from_command_line(self):
        self._setup_config()
        # make sure we're actually using the url from the command line:
        db_url = self.db_url
        self.db_url = 'junk://'
        self._check(
            '--url=%s create' % db_url, '''
For database at %s:
Creating the following tables:
user
''' % (db_url, ))

    def test_pass_in_argv(self):
        self._setup_config()
        # check we can pass in argv if we're being called as a sub-script
        self._check('not for us',
                    '''
For database at %s:
Creating the following tables:
user
''' % (self.db_url, ),
                    kw=dict(argv=['create']))
        expected_metadata = MetaData()
        self.mytable.tometadata(expected_metadata)
        self._check_db(expected_metadata)

    def test_help(self):
        self._setup_config()
        output = self._check('--help', expected=SystemExit)
        self.assertTrue('acted on is at:\n' + self.db_url in output, output)
        self.assertTrue('in the current configuration:\nuser\n' in output,
                        output)
        self.assertTrue('Create all the tables' in output, output)
        self.assertTrue('Drop all tables' in output, output)
        # db should be empty!
        self._check_db(MetaData())

    def test_password_in_help(self):
        self.db_url = "postgres://*****:*****@localhost/db"
        self._setup_config()
        output = self._check('--help', expected=SystemExit)
        self.assertFalse('pw' in output, output)

    def test_help_with_our_parser(self):
        self._setup_config()
        parser = ArgumentParser()
        self.db_url = None
        obj = self._callable()
        obj.setup_parser(parser)
        with OutputCapture() as capture:
            try:
                parser.parse_args(['--help'])
            except SystemExit as ex:
                pass
        output = capture.captured
        self.assertFalse('acted on is at:\n' in output, output)
        self.assertTrue('in the current configuration:\nuser\n' in output,
                        output)
        self.assertTrue('Create all the tables' in output, output)
        self.assertTrue('Drop all tables' in output, output)

    def test_create_without_using_call(self):
        self._setup_config()
        db_url = self.db_url
        self.db_url = None

        parser = ArgumentParser()
        obj = self._callable()
        obj.setup_parser(parser)

        args = parser.parse_args(['create'])
        obj.run(db_url, args)

        self.log.check(
            (logger_name, 'INFO', 'For database at ' + db_url + ':'),
            (logger_name, 'INFO', 'Creating the following tables:'),
            (logger_name, 'INFO', 'user'),
        )

        expected_metadata = MetaData()
        self.mytable.tometadata(expected_metadata)
        self.db_url = db_url
        self._check_db(expected_metadata)

    def test_create_without_using_call_url_option_preferred(self):
        self._setup_config()
        db_url = self.db_url
        self.db_url = None

        parser = ArgumentParser()
        obj = self._callable()
        obj.setup_parser(parser)

        args = parser.parse_args(['--url', db_url, 'create'])
        obj.run('absolute rubbish', args)

        self.log.check(
            (logger_name, 'INFO', 'For database at ' + db_url + ':'),
            (logger_name, 'INFO', 'Creating the following tables:'),
            (logger_name, 'INFO', 'user'),
        )

        expected_metadata = MetaData()
        self.mytable.tometadata(expected_metadata)
        self.db_url = db_url
        self._check_db(expected_metadata)

    def test_create_logging_not_printing(self):
        self._setup_config()
        parser = ArgumentParser()
        obj = self._callable()
        obj.setup_parser(parser)

        with OutputCapture() as output:
            args = parser.parse_args(['create'])
            obj.run('absolute rubbish', args)

        self.log.check(
            (logger_name, 'INFO', 'For database at ' + self.db_url + ':'),
            (logger_name, 'INFO', 'Creating the following tables:'),
            (logger_name, 'INFO', 'user'),
        )

        output.compare('')

    def test_single_source(self):
        self._setup_config()
        # check
        self._check(
            'create', '''
For database at %s:
Creating the following tables:
user
''' % (self.db_url, ))
        expected_metadata = MetaData()
        self.mytable.tometadata(expected_metadata)
        self._check_db(expected_metadata)

    def test_multi_source(self):

        # setup

        m1 = MetaData()
        t1 = Table(
            't1',
            m1,
            Column('id', Integer, primary_key=True),
        )
        m1 = MetaData()
        t2 = Table(
            't2',
            m1,
            Column('jd', Integer, primary_key=True),
        )
        self.config = Config(Source(t1), Source(t2))

        # check

        self._check(
            'create', '''
For database at %s:
Creating the following tables:
t1
t2
''' % (self.db_url, ))

        expected_metadata = MetaData()
        t1.tometadata(expected_metadata)
        t2.tometadata(expected_metadata)
        self._check_db(expected_metadata)

    def test_table_present(self):
        self._setup_config()
        self.mytable.create(create_engine(self.db_url))
        # check
        self._check(
            'create', '''
For database at %s:
Refusing to create as the following tables exist:
user
''' % self.db_url)
        expected_metadata = MetaData()
        self.mytable.tometadata(expected_metadata)
コード例 #30
0
ファイル: test_runner.py プロジェクト: sshyran/panoptes
class TestPanoptesPluginRunner(unittest.TestCase):
    @staticmethod
    def extract(record):
        message = record.getMessage()
        match_obj = re.match(r'(?P<name>.*):\w+(?P<body>.*)', message)
        if match_obj:
            message = match_obj.group('name') + match_obj.group('body')

        match_obj = re.match(
            r'(?P<start>.*[R|r]an in\s)\d+\.?\d*.*(?P<end>seconds.*)', message)
        if match_obj:
            return record.name, record.levelname, match_obj.group(
                'start') + match_obj.group('end')

        match_obj = re.match(
            r'(?P<start>.*took\s*)\d+\.?\d*.*(?P<seconds>seconds.*)\d+\s(?P<end>garbage objects.*)',
            message)
        if match_obj:
            return record.name, record.levelname, match_obj.group('start') + match_obj.group('seconds') + \
                   match_obj.group('end')

        match_obj = re.match(
            r'(?P<start>Attempting to get lock for plugin .*with lock path) \".*\".*(?P<id> and identifier).*'
            r'(?P<in> in) \d\.?\d*(?P<seconds> seconds)', message)
        if match_obj:
            return record.name, record.levelname, match_obj.group('start') + match_obj.group('id') + \
                   match_obj.group('in') + match_obj.group('seconds')

        return record.name, record.levelname, message

    @patch('redis.StrictRedis', panoptes_mock_redis_strict_client)
    @patch('kazoo.client.KazooClient', panoptes_mock_kazoo_client)
    def setUp(self):
        self.my_dir, self.panoptes_test_conf_file = get_test_conf_file()
        self._panoptes_context = PanoptesContext(
            self.panoptes_test_conf_file,
            key_value_store_class_list=[PanoptesTestKeyValueStore],
            create_message_producer=False,
            async_message_producer=False,
            create_zookeeper_client=True)

        self._runner_class = PanoptesPluginRunner
        self._log_capture = LogCapture(attributes=self.extract)

    def tearDown(self):
        self._log_capture.uninstall()

    def test_logging_methods(self):
        runner = self._runner_class("Test Polling Plugin", "polling",
                                    PanoptesPollingPlugin, PanoptesPluginInfo,
                                    None, self._panoptes_context,
                                    PanoptesTestKeyValueStore,
                                    PanoptesTestKeyValueStore,
                                    PanoptesTestKeyValueStore, "plugin_logger",
                                    PanoptesMetricsGroupSet, _callback)

        #  Ensure logging methods run:
        runner.info(PanoptesTestPluginNoLock(), "Test Info log message")
        runner.warn(PanoptesTestPluginNoLock(), "Test Warning log message")
        runner.error(PanoptesTestPluginNoLock(), "Test Error log message",
                     Exception)
        runner.exception(PanoptesTestPluginNoLock(),
                         "Test Exception log message")

        self._log_capture.check(
            ('panoptes.tests.test_runner', 'INFO',
             '[None] [{}] Test Info log message'),
            ('panoptes.tests.test_runner', 'WARNING',
             '[None] [{}] Test Warning log message'),
            ('panoptes.tests.test_runner', 'ERROR',
             "[None] [{}] Test Error log message: <type 'exceptions.Exception'>"
             ), ('panoptes.tests.test_runner', 'ERROR',
                 '[None] [{}] Test Exception log message'))

    def test_basic_operations(self):
        runner = self._runner_class("Test Polling Plugin", "polling",
                                    PanoptesPollingPlugin, PanoptesPluginInfo,
                                    None, self._panoptes_context,
                                    PanoptesTestKeyValueStore,
                                    PanoptesTestKeyValueStore,
                                    PanoptesTestKeyValueStore, "plugin_logger",
                                    PanoptesMetricsGroupSet, _callback)

        runner.execute_plugin()

        self._log_capture.check_present(
            ('panoptes.tests.test_runner', 'INFO',
             'Attempting to execute plugin "Test Polling Plugin"'),
            ('panoptes.tests.test_runner', 'DEBUG',
             '''Starting Plugin Manager for "polling" plugins with the following '''
             '''configuration: {'polling': <class'''
             """ 'yahoo_panoptes.polling.polling_plugin.PanoptesPollingPlugin'>}, """
             """['tests/plugins/polling'], panoptes-plugin"""),
            ('panoptes.tests.test_runner', 'DEBUG', 'Found 3 plugins'),
            ('panoptes.tests.test_runner', 'DEBUG', 'Loaded plugin '
             '"Test Polling Plugin", version "0.1" of type "polling"'
             ', category "polling"'),
            ('panoptes.tests.test_runner', 'DEBUG',
             'Loaded plugin "Test Polling Plugin 2", '
             'version "0.1" of type "polling", category "polling"'),
            ('panoptes.tests.test_runner', 'DEBUG',
             'Loaded plugin "Test Polling Plugin Second Instance", '
             'version "0.1" of type "polling", category "polling"'),
            ('panoptes.tests.test_runner', 'INFO',
             '''[Test Polling Plugin] [None] '''
             '''Attempting to get lock for plugin "Test Polling Plugin"'''),
            ('panoptes.tests.test_runner', 'DEBUG',
             'Attempting to get lock for plugin "Test Polling Plugin", with lock path and '
             'identifier in seconds'),
            ('panoptes.tests.test_runner', 'INFO',
             '[Test Polling Plugin] [None] Acquired lock'),
            ('panoptes.tests.test_runner', 'INFO',
             '[Test Polling Plugin] [None]'
             ' Ran in seconds'),
            ('panoptes.tests.test_runner', 'INFO',
             '[Test Polling Plugin] [None] Released lock'),
            ('panoptes.tests.test_runner', 'INFO',
             '[Test Polling Plugin] [None] Plugin returned'
             ' a result set with 1 members'),
            ('panoptes.tests.test_runner', 'INFO',
             '[Test Polling Plugin] [None]'
             ' Callback function ran in seconds'),
            ('panoptes.tests.test_runner', 'INFO',
             '[Test Polling Plugin] [None] GC took seconds. There are garbage objects.'
             ), ('panoptes.tests.test_runner', 'DEBUG',
                 'Deleting module: yapsy_loaded_plugin_Test_Polling_Plugin_0'),
            ('panoptes.tests.test_runner', 'DEBUG',
             'Deleting module: yapsy_loaded_plugin_Test_Polling_Plugin_Second_Instance_0'
             ),
            order_matters=False)

    def test_nonexistent_plugin(self):
        runner = self._runner_class("Non-existent Plugin", "polling",
                                    PanoptesPollingPlugin, PanoptesPluginInfo,
                                    None, self._panoptes_context,
                                    PanoptesTestKeyValueStore,
                                    PanoptesTestKeyValueStore,
                                    PanoptesTestKeyValueStore, "plugin_logger",
                                    PanoptesMetricsGroupSet, _callback)
        runner.execute_plugin()
        self._log_capture.check_present((
            'panoptes.tests.test_runner', 'INFO',
            'Attempting to execute plugin "Non-existent Plugin"'
        ), (
            'panoptes.tests.test_runner', 'DEBUG',
            'Starting Plugin Manager for "polling" plugins with the following '
            "configuration: {'polling': <class 'yahoo_panoptes.polling.polling_plugin."
            "PanoptesPollingPlugin'>}, "
            "['tests/plugins/polling'], panoptes-plugin"
        ), ('panoptes.tests.test_runner', 'DEBUG', 'Found 3 plugins'), (
            'panoptes.tests.test_runner', 'DEBUG',
            'Loaded plugin "Test Polling Plugin", version "0.1" of type "polling", '
            'category "polling"'
        ), ('panoptes.tests.test_runner', 'DEBUG',
            'Loaded plugin "Test Polling Plugin Second Instance", version "0.1" of type '
            '"polling", category "polling"'), (
                'panoptes.tests.test_runner', 'WARNING',
                'No plugin named "Non-existent Plugin" found in "'
                '''['tests/plugins/polling']"'''))

    def test_bad_plugin_type(self):
        runner = self._runner_class("Test Polling Plugin", "bad",
                                    PanoptesPollingPlugin, PanoptesPluginInfo,
                                    None, self._panoptes_context,
                                    PanoptesTestKeyValueStore,
                                    PanoptesTestKeyValueStore,
                                    PanoptesTestKeyValueStore, "plugin_logger",
                                    PanoptesMetricsGroupSet, _callback)
        runner.execute_plugin()

        self._log_capture.check_present((
            'panoptes.tests.test_runner', 'ERROR',
            '''Error trying to load plugin "Test Polling Plugin": KeyError('bad',)'''
        ))

    def test_execute_now_false(self):
        mock_get_plugin_by_name = MagicMock(
            return_value=MockPluginExecuteNow())
        with patch(
                'yahoo_panoptes.framework.plugins.runner.PanoptesPluginManager.getPluginByName',
                mock_get_plugin_by_name):
            runner = self._runner_class(
                "Test Polling Plugin", "polling", PanoptesPollingPlugin,
                PanoptesPluginInfo, None, self._panoptes_context,
                PanoptesTestKeyValueStore, PanoptesTestKeyValueStore,
                PanoptesTestKeyValueStore, "plugin_logger",
                PanoptesMetricsGroupSet, _callback)
            runner.execute_plugin()

            self._log_capture.check_present(
                ('panoptes.tests.test_runner', 'INFO',
                 'Attempting to execute plugin "Test Polling Plugin"'),
                ('panoptes.tests.test_runner', 'DEBUG',
                 '''Starting Plugin Manager for '''
                 '''"polling" plugins with the '''
                 '''following configuration: {'polling': '''
                 """<class 'yahoo_panoptes.polling.polling_plugin.PanoptesPollingPlugin'"""
                 """>}, ['tests/plugins/polling'], panoptes-plugin"""),
                ('panoptes.tests.test_runner', 'DEBUG', 'Found 3 plugins'),
                ('panoptes.tests.test_runner', 'DEBUG', 'Loaded plugin '
                 '"Test Polling Plugin", version "0.1" of type "polling"'
                 ', category "polling"'),
                ('panoptes.tests.test_runner', 'DEBUG',
                 'Loaded plugin "Test Polling Plugin Second Instance", '
                 'version "0.1" of type "polling", category "polling"'))

    def test_callback_failure(self):
        runner = self._runner_class(
            "Test Polling Plugin", "polling", PanoptesPollingPlugin,
            PanoptesPluginInfo, None, self._panoptes_context,
            PanoptesTestKeyValueStore, PanoptesTestKeyValueStore,
            PanoptesTestKeyValueStore, "plugin_logger",
            PanoptesMetricsGroupSet, _callback_with_exception)
        runner.execute_plugin()

        self._log_capture.check_present(
            ('panoptes.tests.test_runner', 'ERROR', '[Test Polling Plugin] '
             '[None] Results callback function failed'))

    def test_lock_no_lock_object(self):
        mock_plugin = MagicMock(return_value=PanoptesTestPluginNoLock)
        mock_get_context = MagicMock(return_value=self._panoptes_context)
        with patch(
                'yahoo_panoptes.framework.plugins.runner.PanoptesPluginManager.getPluginByName',
                mock_plugin):
            with patch(
                    'yahoo_panoptes.framework.plugins.runner.PanoptesPluginRunner._get_context',
                    mock_get_context):
                runner = self._runner_class(
                    "Test Polling Plugin", "polling", PanoptesPollingPlugin,
                    PanoptesPluginInfo, None, self._panoptes_context,
                    PanoptesTestKeyValueStore, PanoptesTestKeyValueStore,
                    PanoptesTestKeyValueStore, "plugin_logger",
                    PanoptesMetricsGroupSet, _callback)
                runner.execute_plugin()

                self._log_capture.check_present(
                    ('panoptes.tests.test_runner', 'ERROR',
                     '[None] [{}] Error in acquiring lock'))

    def test_lock_is_none(self):
        mock_get_plugin_by_name = MagicMock(return_value=MockPluginLockNone())
        mock_get_context = MagicMock(return_value=self._panoptes_context)
        with patch(
                'yahoo_panoptes.framework.plugins.runner.PanoptesPluginManager.getPluginByName',
                mock_get_plugin_by_name):
            with patch(
                    'yahoo_panoptes.framework.plugins.runner.PanoptesPluginRunner._get_context',
                    mock_get_context):
                runner = self._runner_class(
                    "Test Polling Plugin", "polling", PanoptesPollingPlugin,
                    PanoptesPluginInfo, None, self._panoptes_context,
                    PanoptesTestKeyValueStore, PanoptesTestKeyValueStore,
                    PanoptesTestKeyValueStore, "plugin_logger",
                    PanoptesMetricsGroupSet, _callback)
                runner.execute_plugin()

                self._log_capture.check_present(
                    ('panoptes.tests.test_runner', 'INFO',
                     '[None] [{}] Attempting to get lock for plugin'
                     ' "Test Polling Plugin"'))

    def test_lock_is_not_locked(self):
        mock_get_plugin_by_name = MagicMock(
            return_value=MockPluginLockIsNotLocked())
        mock_get_context = MagicMock(return_value=self._panoptes_context)
        with patch(
                'yahoo_panoptes.framework.plugins.runner.PanoptesPluginManager.getPluginByName',
                mock_get_plugin_by_name):
            with patch(
                    'yahoo_panoptes.framework.plugins.runner.PanoptesPluginRunner._get_context',
                    mock_get_context):
                runner = self._runner_class(
                    "Test Polling Plugin", "polling", PanoptesPollingPlugin,
                    PanoptesPluginInfo, None, self._panoptes_context,
                    PanoptesTestKeyValueStore, PanoptesTestKeyValueStore,
                    PanoptesTestKeyValueStore, "plugin_logger",
                    PanoptesMetricsGroupSet, _callback)
                runner.execute_plugin()

                self._log_capture.check_present(
                    ('panoptes.tests.test_runner', 'INFO',
                     '[None] [{}] Attempting to get lock for plugin'
                     ' "Test Polling Plugin"'))

    def test_plugin_failure(self):
        mock_plugin = MagicMock(
            return_value=PanoptesTestPluginRaisePluginReleaseException)
        mock_get_context = MagicMock(return_value=self._panoptes_context)
        with patch(
                'yahoo_panoptes.framework.plugins.runner.PanoptesPluginManager.getPluginByName',
                mock_plugin):
            with patch(
                    'yahoo_panoptes.framework.plugins.runner.PanoptesPluginRunner._get_context',
                    mock_get_context):
                runner = self._runner_class(
                    "Test Polling Plugin", "polling", PanoptesPollingPlugin,
                    PanoptesPluginInfo, None, self._panoptes_context,
                    PanoptesTestKeyValueStore, PanoptesTestKeyValueStore,
                    PanoptesTestKeyValueStore, "plugin_logger",
                    PanoptesMetricsGroupSet, _callback)
                runner.execute_plugin()

                self._log_capture.check_present(
                    ('panoptes.tests.test_runner', 'ERROR',
                     '[None] [{}] Failed to execute plugin'),
                    ('panoptes.tests.test_runner', 'INFO',
                     '[None] [{}] Ran in seconds'),
                    ('panoptes.tests.test_runner', 'ERROR',
                     '[None] [{}] Failed to release lock for plugin'),
                    ('panoptes.tests.test_runner', 'WARNING',
                     '[None] [{}] Plugin did not return any results'))

    def test_plugin_wrong_result_type(self):
        runner = self._runner_class("Test Polling Plugin 2", "polling",
                                    PanoptesPollingPlugin, PanoptesPluginInfo,
                                    None, self._panoptes_context,
                                    PanoptesTestKeyValueStore,
                                    PanoptesTestKeyValueStore,
                                    PanoptesTestKeyValueStore, "plugin_logger",
                                    PanoptesMetricsGroupSet, _callback)
        runner.execute_plugin()

        self._log_capture.check_present((
            'panoptes.tests.test_runner', 'WARNING',
            '[Test Polling Plugin 2] [None] Plugin returned an unexpected result type: '
            '"PanoptesMetricsGroup"'))
コード例 #31
0
class TestUsesResolving(unittest.TestCase):
    
    def setUp(self):
        self.l = LogCapture()
        
    def tearDown(self):
        self.l.uninstall()
        
    def test_that_resolving_warns_about_missing_category_backend_if_no_includes_found(self):
        op = UsesParser()
        category = MockCategory()
        
        op.resolve([category], [])
        
        self.l.check(('root', 'WARNING', "Category '{0}' has no backend specified".format(category.catid)))
        
    def test_that_resolving_does_not_warn_if_category_missing_backend_but_include_all_specified(self):
        root = ET.Element('config')
        uses = ET.SubElement(root, 'uses')
        backend = 'db'
        use = ET.SubElement(uses, 'use', {'backend':backend})
        ET.SubElement(use, 'includeall')  
        op = UsesParser()
        category = MockCategory()
        op.parse(root)

        op.resolve([category], [], {backend:MockBackend()})
        
        assert_that(self.l.__str__(), is_("No logging captured"))        
    
    def test_that_resolving_does_not_warn_if_category_missing_backend_but_component_includes_it(self):
        backend = 'db'
        category = MockCategory()
        example_component = Component(categories = [category.catid]) 
        component_name = 'example'
        root = _build_tree_with_valid_component_include(backend, component_name)
        op = UsesParser()
        op.parse(root)        
        
        op.resolve([category], {component_name:example_component}, {backend:MockBackend()})
        
        assert_that(self.l.__str__(), is_("No logging captured"))
        
    def test_that_component_level_exclude_overrides_include_all(self):
        category = MockCategory()      
        example_component = Component(categories = [category.catid]) 
        component_name = 'example'
        root = ET.Element('config')
        uses = ET.SubElement(root, 'uses')
        backend = 'db'
        use = ET.SubElement(uses, 'use', {'backend':backend})
        ET.SubElement(use, 'includeall')
        exclude = ET.SubElement(use, 'exclude')
        ET.SubElement(exclude, 'component', {'name':component_name})
        op = UsesParser()  
        op.parse(root)      
        
        op.resolve([category], {component_name:example_component})
        
        self.l.check(('root', 'WARNING', "Category '{0}' has no backend specified".format(category.catid)))
        
    def test_that_resolve_warns_if_category_linked_to_nonexistant_backend(self):
        backend = 'db'
        category = MockCategory()
        root = _build_tree_with_valid_category_include(backend, category)
        op = UsesParser()
        op.parse(root)
        
        op.resolve([category], {})
        
        self.l.check(('root', 'WARNING', "Category '{0}' has link to nonexistant backend {1}".format(category.catid, backend)))
        
    def test_that_resolve_links_categories_to_backend(self):
        backend = 'db'
        category = MockCategory()
        root = _build_tree_with_valid_category_include(backend, category)
        op = UsesParser()
        op.parse(root)
        example_backend = MockBackend()
        
        op.resolve([category], {}, {backend:example_backend})
        
        assert_that(category.set_backend_called, is_(True))
        assert_that(category.backend, is_(same_instance(example_backend)))
        
    def test_that_resolve_links_backends_to_categories(self):
        backend_name = 'db'
        category = MockCategory()
        root = _build_tree_with_valid_category_include(backend_name, category)
        op = UsesParser()
        op.parse(root)
        backend = MockBackend()
        
        op.resolve([category], {}, {backend_name:backend})
        
        assert_that(backend.add_category_called, is_(True))
        assert_that(backend.categories, has_item(same_instance(category)))
        
    def test_that_resolve_warns_if_component_include_is_not_in_components_list(self): 
        component_name = 'nonexistant'
        root = ET.Element('config')
        uses = ET.SubElement(root, 'uses')
        backend = 'db'
        use = ET.SubElement(uses, 'use', {'backend':backend})
        include = ET.SubElement(use, 'include')
        ET.SubElement(include, 'component', {'name':component_name})
        op = UsesParser()  
        op.parse(root)      
        category_name = "don't care"
        op.resolve([MockCategory(category_name)], {})
        
        # TODO We don't care about the second method here.  Create a better matcher than l.check to allow checking for only a subset of the messages 
        self.l.check(('root', 'WARNING', "Component '{0}' is included/excluded for backend {1}, but does not exist".format(component_name, backend)),
                      ('root', 'WARNING', "Category '{0}' has no backend specified".format(category_name)))
コード例 #32
0
ファイル: test_process.py プロジェクト: peteches/servercheck
class TestProcess:

    def __init__(self, **kwargs):
        self.log_name = 'servercheck.TestProcessTester.{}'

        self.pass_str = '\033[1;32mPASS: Process "{}" {}\033[0m'
        self.fail_str = '\033[1;31mFAIL: Process "{}" {}\033[0m'

        self.processes = [
            ['sleep', '200'],
            ['yes', 'TESTING'],
        ]

        self.fake_processes = [
            'NotAProcess',
            'ThinksItMayBeAProcess',
            'InNoWayIsThisAProcess',
        ]

    def setup(self):

        self.log_capture = LogCapture()

        self.running_procs = []

        with open('/dev/null', 'w') as DEVNULL:
            for p in self.processes:
                self.running_procs.append(sp.Popen(p,
                                                   stderr=DEVNULL,
                                                   stdout=DEVNULL))

    def teardown(self):
        self.log_capture.uninstall()

        for p in self.running_procs:
            p.kill()

    def check_pname_set_correctly(self, pname):

        pt = TestProcessTester(pname)

        assert_equal(pname, pt.pname)

    def test_pname_set_correctly(self):
        for p in [x[0] for x in self.processes]:
            yield self.check_pname_set_correctly, p

        for p in self.fake_processes:
            yield self.check_pname_set_correctly, p

    def check_process_is_running(self, pname):
        pt = TestProcessTester(pname)

        pt.is_running()

        if pname in [x[0] for x in self.processes]:
            lvl = 'INFO'
            msg = self.pass_str.format(pname,
                                       'is running.')
        else:
            lvl = 'WARNING'
            msg = self.fail_str.format(pname,
                                       'is not running.')

        self.log_capture.check(
            (
                self.log_name.format(pname),
                lvl,
                msg,
            ),
        )

    def test_process_running(self):
        for p in [x[0] for x in self.processes]:
            yield self.check_process_is_running, p

        for p in self.fake_processes:
            yield self.check_process_is_running, p

    def check_running_as(self, pname, test_user, exp_user):

        pt = TestProcessTester(pname)

        if test_user == exp_user:
            lvl = 'INFO'
            msg = self.pass_str.format(pname,
                                       'is running as {}.'.format(test_user))
        else:
            lvl = 'WARNING'
            msg = self.fail_str.format(pname,
                                       'is not running as {}.'.format(test_user))  # nopep8

        pt.is_running_as(test_user)

        self.log_capture.check(
            (
                self.log_name.format(pname),
                lvl,
                msg,
            ),
        )

    def test_running_as(self):
        current_user = pwd.getpwuid(os.getuid()).pw_name
        for p in [x[0] for x in self.processes]:
            for u in ['root', current_user]:
                yield self.check_running_as, p, u, current_user
        rp = sp.Popen(['ps', '-U', 'root', '-o', 'comm'], stderr=sp.PIPE,
                      stdout=sp.PIPE).stdout.read()
        root_procs = random.sample([x for x in str(rp).split('\n')
                                    if not x.count('/') and not x.count('[') and  not x.count('CMD')],
                                   2)
        for p in root_procs:
            for u in ['root', current_user]:
                yield self.check_running_as, p, u, 'root'
コード例 #33
0
class Tests(TestCase):
    def setUp(self):
        self.dir = TempDirectory()
        self.log = LogCapture()
        self.r = Replacer()
        self.r.replace("datetime.datetime", test_datetime())

    def tearDown(self):
        self.r.restore()
        self.log.uninstall()
        self.dir.cleanup()

    def test_parse(self):
        path = self.dir.write(
            "test.csv",
            b"""\
Name,Money Owed
Adam Alpha,100
""",
        )
        self.assertEqual(most_owed(path), "Adam Alpha")
        self.log.check(("root", "INFO", "Processing took 0:00:10"))

    def test_max(self):
        path = self.dir.write(
            "test.csv",
            b"""\
Name,Money Owed
Adam Alpha,100
Brian Beta, 300
""",
        )
        self.assertEqual(most_owed(path), "Brian Beta")

    def test_unicode(self):
        path = self.dir.write(
            "test.csv",
            """\
Name,Money Owed
C\xe9dric Cee,200
""",
            "utf8",
        )
        self.assertEqual(most_owed(path), "C\xe9dric Cee")

    def test_whitespace(self):
        path = self.dir.write(
            "test.csv",
            b"""\
Name,Money Owed
 Adam Alpha,\t100
""",
        )
        self.assertEqual(most_owed(path), "Adam Alpha")

    def test_invalid_numbers(self):
        path = self.dir.write(
            "test.csv",
            b"""\
Name,Money Owed
Adam Alpha,X
Brian Beta, 300
""",
        )
        self.assertEqual(most_owed(path), "Brian Beta")
        self.log.check(("root", "WARNING", "ignoring 'X' as not valid"), ("root", "INFO", "Processing took 0:00:10"))

    def test_malformed(self):
        path = self.dir.write(
            "test.csv",
            b"""\
Name,
Adam Alpha
""",
        )
        with ShouldRaise(KeyError("Money Owed")):
            most_owed(path)
コード例 #34
0
class TestComponentParsing(unittest.TestCase):
    def setUp(self):
        self.l = LogCapture()
        
    def tearDown(self):
        self.l.uninstall()
    
    def test_that_empty_dictionary_is_returned_if_no_components_found(self):
        op = ComponentParser()
        
        result = op.components
        
        assert_that(result, is_({}))
    
    def test_that_parse_requires_an_outer_components_element(self):
        root = ET.Element('component')  #Note the lack of a final 's'
        op = ComponentParser()
        
        op.parse(root)
        result = op.components
        
        assert_that(result, is_({}))
        
    
    def test_that_parse_generates_a_component_if_xml_contains_component_element(self):
        root = ET.Element('components')
        ET.SubElement(root, 'component', {'name':"don't care"})
        op = ComponentParser()
        
        op.parse(root)
        result = op.components
        
        assert_that(result, is_not([]))
        assert_that(type(result), is_(type(Component)))
    
    def test_that_parse_generates_two_component_if_xml_contains_two_component_elements(self):
        root = ET.Element('components')
        name1 = "first"
        name2 = "second"
        ET.SubElement(root, 'component', {'name':name1})
        ET.SubElement(root, 'component', {'name':name2})
        op = ComponentParser()
        
        op.parse(root)
        result = op.components
        
        assert_that(len(result), is_(2))
        assert_that(type(result[name1]), is_(type(Component)))
        assert_that(type(result[name2]), is_(type(Component)))
                
    def test_that_parse_generates_empty_dictionary_if_xml_does_not_contain_components_element(self):
        root = ET.Element('model')
        op = ComponentParser()
        
        op.parse(root)
        result = op.components
        
        assert_that(result, is_({}))
        
    
    def test_that_parse_generates_a_component_with_attributes_if_specified(self):
        root = ET.Element('components')
        component_name = 'example'
        ET.SubElement(root, 'component', { 'name':component_name, 'random':'abc', 'random2':'123'})
        op = ComponentParser()
        
        op.parse(root)
        result = op.components[component_name]
        
        assert_that(result.attributes, is_not(None))
        assert_that(result.attributes, has_entry('name', 'example'))
        assert_that(result.attributes, has_entry('random', 'abc'))
        assert_that(result.attributes, has_entry('random2', '123'))
        
    def test_that_parse_sets_component_names_as_specified(self):
        name = 'sample component'
        root = ET.Element('components')
        ET.SubElement(root, 'component', {'name':name})
        op = ComponentParser()
        
        op.parse(root)
        result = op.components[name]
        
        assert_that(result.name, is_(name))

    def test_that_parse_generates_a_component_including_category_if_specified_with_name(self):
        category = 'publication'
        name = 'sample component'
        root = _component_tree_with_category(category, name)
        op = ComponentParser()
        
        op.parse(root)
        result = op.components[name]
        
        assert_that(result.category_names, is_not(None))
        assert_that(result.category_names, has_item(category))
        
    def test_that_parse_generates_a_component_including_two_categories_if_two_specified(self):
        root = ET.Element('components')
        component_name = "example"
        sample_component = ET.SubElement(root, 'component', {'name':component_name})
        name1 = "publication"
        name2 = "enquiry"
        ET.SubElement(sample_component, 'category', {'name':name1})
        ET.SubElement(sample_component, 'category', {'name':name2})
        op = ComponentParser()
        
        op.parse(root)
        result = op.components[component_name]
        
        assert_that(result.category_names, is_not(None))
        assert_that(result.category_names, has_item(name1))
        assert_that(result.category_names, has_item(name2))
        
    @unittest.expectedFailure
    def test_that_parse_raises_if_category_has_no_name(self):
        '''Allow categories with no name in xml file, just means the element will be skipped'''        
        root = ET.Element('components')
        sample_component = ET.SubElement(root, 'component')
        ET.SubElement(sample_component, 'category')
        op = ComponentParser()
        
        self.assertRaises(AttributeError, op.parse)
        
    def test_that_parse_skip_element_and_generates_warning_if_component_has_no_name(self):
        root = ET.Element('components')
        sample_component = ET.SubElement(root, 'component')
        ET.SubElement(sample_component, 'category')
        op = ComponentParser()
        
        op.parse(root)
        result = op.components
        
        assert_that(result, is_({}))
        self.l.check(('root', 'WARNING', "Ignoring component definition with no name"))
        
コード例 #35
0
class TestImportPayments(TestCase):
    """Test import_payments command."""
    def setUp(self):
        account = BankAccount(account_number='123456/7890', currency='CZK')
        account.save()
        self.account = account
        self.log_handler = LogCapture(
            'django_pain.management.commands.import_payments', propagate=False)

    def tearDown(self):
        self.log_handler.uninstall()

    def test_import_payments(self):
        """Test import_payments command."""
        out = StringIO()
        call_command(
            'import_payments',
            '--parser=django_pain.tests.commands.test_import_payments.DummyPaymentsParser',
            '--no-color',
            '--verbosity=3',
            stdout=out)

        self.assertEqual(out.getvalue().strip().split('\n'), [
            'Payment ID PAYMENT_1 has been imported.',
            'Payment ID PAYMENT_2 has been imported.',
        ])

        self.assertQuerysetEqual(BankPayment.objects.values_list(
            'identifier',
            'account',
            'counter_account_number',
            'transaction_date',
            'amount',
            'amount_currency',
            'variable_symbol',
        ), [
            ('PAYMENT_1', self.account.pk, '098765/4321', date(
                2018, 5, 9), Decimal('42.00'), 'CZK', '1234'),
            ('PAYMENT_2', self.account.pk, '098765/4321', date(
                2018, 5, 9), Decimal('370.00'), 'CZK', ''),
        ],
                                 transform=tuple,
                                 ordered=False)

        self.log_handler.check(
            ('django_pain.management.commands.import_payments', 'INFO',
             'Command import_payments started.'),
            ('django_pain.management.commands.import_payments', 'DEBUG',
             'Importing payments from -.'),
            ('django_pain.management.commands.import_payments', 'DEBUG',
             'Parsing payments from -.'),
            ('django_pain.management.commands.import_payments', 'DEBUG',
             'Saving 2 payments from - to database.'),
            ('django_pain.management.commands.import_payments', 'INFO',
             'Command import_payments finished.'),
        )

    def test_account_not_exist(self):
        """Test command while account does not exist."""
        with self.assertRaises(CommandError) as cm:
            call_command(
                'import_payments',
                '--parser=django_pain.tests.commands.test_import_payments.DummyExceptionParser',
                '--no-color')

        self.assertEqual(str(cm.exception),
                         'Bank account ACCOUNT does not exist.')
        self.log_handler.check(
            ('django_pain.management.commands.import_payments', 'INFO',
             'Command import_payments started.'),
            ('django_pain.management.commands.import_payments', 'DEBUG',
             'Importing payments from -.'),
            ('django_pain.management.commands.import_payments', 'DEBUG',
             'Parsing payments from -.'),
            ('django_pain.management.commands.import_payments', 'ERROR',
             'Bank account ACCOUNT does not exist.'),
        )

    def test_payment_already_exist(self):
        """Test command for payments that already exist in database."""
        out = StringIO()
        err = StringIO()
        call_command(
            'import_payments',
            '--parser=django_pain.tests.commands.test_import_payments.DummyPaymentsParser',
            '--no-color',
            stdout=out)
        call_command(
            'import_payments',
            '--parser=django_pain.tests.commands.test_import_payments.DummyPaymentsParser',
            '--no-color',
            stderr=err)

        self.assertEqual(err.getvalue().strip().split('\n'), [
            'Payment ID PAYMENT_1 has not been saved due to the following errors:',
            'Bank payment with this Payment ID and Destination account already exists.',
            'Payment ID PAYMENT_2 has not been saved due to the following errors:',
            'Bank payment with this Payment ID and Destination account already exists.',
        ])
        self.log_handler.check(
            ('django_pain.management.commands.import_payments', 'INFO',
             'Command import_payments started.'),
            ('django_pain.management.commands.import_payments', 'DEBUG',
             'Importing payments from -.'),
            ('django_pain.management.commands.import_payments', 'DEBUG',
             'Parsing payments from -.'),
            ('django_pain.management.commands.import_payments', 'DEBUG',
             'Saving 2 payments from - to database.'),
            ('django_pain.management.commands.import_payments', 'INFO',
             'Command import_payments finished.'),
            ('django_pain.management.commands.import_payments', 'INFO',
             'Command import_payments started.'),
            ('django_pain.management.commands.import_payments', 'DEBUG',
             'Importing payments from -.'),
            ('django_pain.management.commands.import_payments', 'DEBUG',
             'Parsing payments from -.'),
            ('django_pain.management.commands.import_payments', 'DEBUG',
             'Saving 2 payments from - to database.'),
            ('django_pain.management.commands.import_payments', 'WARNING',
             'Payment ID PAYMENT_1 has not been saved due to the following errors:'
             ),
            ('django_pain.management.commands.import_payments', 'WARNING',
             'Bank payment with this Payment ID and Destination account already exists.'
             ),
            ('django_pain.management.commands.import_payments', 'WARNING',
             'Payment ID PAYMENT_2 has not been saved due to the following errors:'
             ),
            ('django_pain.management.commands.import_payments', 'WARNING',
             'Bank payment with this Payment ID and Destination account already exists.'
             ),
            ('django_pain.management.commands.import_payments', 'INFO',
             'Command import_payments finished.'),
        )

    def test_quiet_command(self):
        """Test command call with verbosity set to 0."""
        out = StringIO()
        err = StringIO()
        call_command(
            'import_payments',
            '--parser=django_pain.tests.commands.test_import_payments.DummyPaymentsParser',
            '--no-color',
            '--verbosity=0',
            stdout=out,
            stderr=err)
        call_command(
            'import_payments',
            '--parser=django_pain.tests.commands.test_import_payments.DummyPaymentsParser',
            '--no-color',
            '--verbosity=0',
            stdout=out,
            stderr=err)

        self.assertEqual(out.getvalue(), '')
        self.assertEqual(err.getvalue(), '')

    def test_input_from_files(self):
        """Test command call with input files."""
        out = StringIO()
        err = StringIO()
        with TempDirectory() as d:
            d.write('input_file.xml', b'<whatever></whatever>')
            call_command(
                'import_payments',
                '--parser=django_pain.tests.commands.test_import_payments.DummyPaymentsParser',
                '--no-color',
                '--verbosity=0',
                '-',
                '/'.join([d.path, 'input_file.xml']),
                stdout=out,
                stderr=err)

        self.assertEqual(out.getvalue(), '')
        self.assertEqual(err.getvalue(), '')

    def test_invalid_parser(self):
        """Test command call with invalid parser."""
        with self.assertRaises(CommandError) as cm:
            call_command('import_payments', '--parser=decimal.Decimal',
                         '--no-color')

        self.assertEqual(
            str(cm.exception),
            'Parser argument has to be subclass of AbstractBankStatementParser.'
        )

    @override_settings(PAIN_IMPORT_CALLBACKS=[
        'django_pain.import_callbacks.skip_credit_card_transaction_summary'
    ])
    def test_import_callback_exception(self):
        """Test import callback raising exception."""
        out = StringIO()
        err = StringIO()
        call_command(
            'import_payments',
            '--parser=django_pain.tests.commands.test_import_payments.DummyCreditCardSummaryParser',
            '--no-color',
            '--verbosity=3',
            stdout=out,
            stderr=err)

        self.assertEqual(out.getvalue().strip(), '')
        self.assertEqual(err.getvalue().strip().split('\n'), [
            'Payment ID PAYMENT_3 has not been saved due to the following errors:',
            'Payment is credit card transaction summary.',
        ])
        self.assertEqual(BankPayment.objects.count(), 0)
        self.log_handler.check(
            ('django_pain.management.commands.import_payments', 'INFO',
             'Command import_payments started.'),
            ('django_pain.management.commands.import_payments', 'DEBUG',
             'Importing payments from -.'),
            ('django_pain.management.commands.import_payments', 'DEBUG',
             'Parsing payments from -.'),
            ('django_pain.management.commands.import_payments', 'DEBUG',
             'Saving 1 payments from - to database.'),
            ('django_pain.management.commands.import_payments', 'WARNING',
             'Payment ID PAYMENT_3 has not been saved due to the following errors:'
             ),
            ('django_pain.management.commands.import_payments', 'WARNING',
             'Payment is credit card transaction summary.'),
            ('django_pain.management.commands.import_payments', 'INFO',
             'Command import_payments finished.'),
        )
コード例 #36
0
class TestHTMLFilter(TestCase):

    def setUp(self):
        self.log = LogCapture()
        self.logger = getLogger()
        self.log.addFilter(HTMLFilter())

    def tearDown(self):
        self.log.uninstall()

    def test_plain_string(self):
        self.logger.info('foo')
        self.log.check(('root', 'INFO', 'foo'),)

    def test_html_string(self):
        self.logger.info('<foo &bar>')
        self.log.check(('root', 'INFO', '&lt;foo &amp;bar&gt;'),)

    def test_with_params_string(self):
        self.logger.info('%s', 'foo')
        self.log.check(('root', 'INFO', 'foo'),)

    def test_plain_unicode(self):
        self.logger.info(u"accentu\u00E9")
        self.log.check(('root', 'INFO', u'accentu\xe9'),)

    def test_html_unicode(self):
        self.logger.info(u"<u\u00E9 &bar>")
        self.log.check(('root', 'INFO', u'&lt;u\xe9 &amp;bar&gt;'),)

    def test_with_params_unicode(self):
        self.logger.info(u"\u00E9%s", u"accentu\u00E9")
        self.log.check(('root', 'INFO', u'\xe9accentu\xe9'),)

    def test_some_object(self):
        class AnObject(object):

            def __repr__(self):
                return 'obj'
            __str__ = __repr__
        self.logger.info(AnObject())
        self.log.check(('root', 'INFO', 'obj'),)
コード例 #37
0
class TestClassWriter(TestCase):

    def setUp(self):
        self.output = StringIO()
        self.writer = ClassWriter('FooBar', 'FOOB', self.output)
        self.log = LogCapture()
        self.addCleanup(self.log.uninstall)

    def check_output(self, expected):
        compare(expected=dedent(expected), actual=self.output.getvalue(),
                trailing_whitespace=False)

    def test_write_header(self):
        self.writer.write_header()
        self.check_output("""

        class FooBar(Object):
            code = 'FOOB'
        """)

    def test_write_members(self):
        self.output.write('class TestClass(Object):\n')
        self.writer.write_simple_members(
            'Field', {'fields': {'fooBar': {}, 'BazBob': {}}}, 'fields'
        )
        self.check_output("""\
        class TestClass(Object):
            baz_bob = Field('BazBob')
            foo_bar = Field('fooBar')
        """)

    def test_write_duplicate_members(self):
        self.output.write('class TestClass(Object):\n')
        self.writer.write_simple_members(
            'Field', {'fields': {'fooBar': {}, 'FooBAR': {}}},'fields'
        )
        self.check_output("""\
        class TestClass(Object):
            foo_bar = Field('FooBAR')
            foo_bar = Field('fooBar')
        """)
        self.log.check(
            ('workfront.generate', 'ERROR',
             "FooBar (FOOB) has duplicate member name: "
             "'foo_bar', first from 'FooBAR', current from 'fooBar'")
        )

    def test_member_name_override(self):
        self.output.write('class Approval(Object):\n')
        writer = ClassWriter('Approval', 'TEST', self.output)
        writer.write_simple_members(
            'Field', {'fields': {'URL': {}, 'url': {}}}, 'fields'
        )
        self.check_output("""\
        class Approval(Object):
            url = Field('URL')
            url_ = Field('url')
        """)
        # no error log:
        self.log.check()

    def test_write_footer(self):
        self.output.write('class FooBar(Object):\n    foo = "bar"\n')
        self.writer.write_footer()
        self.check_output("""\
        class FooBar(Object):
            foo = "bar"

        api.register(FooBar)
        """)

    def test_action_no_arguments(self):
        self.output.write('class FooBar(Object):\n    foo = "bar"\n')
        self.writer.write_members(self.writer.format_action, {
            'actions': {"doSomething": {
                    "resultType": "string",
                }
            }}, 'actions')
        self.check_output('''\
        class FooBar(Object):
            foo = "bar"
            def do_something(self):
                """
                The ``doSomething`` action.

                :return: ``string``
                """
                params = {}
                data = self.session.put(self.api_url()+'/doSomething', params)
                return data['result']
        ''')

    def test_action_no_returns(self):
        self.output.write('class FooBar(Object):\n    foo = "bar"\n')
        self.writer.write_members(self.writer.format_action, {
            'actions': {"doSomething": {
                    "arguments": [
                        {
                            "name": "anOption",
                            "type": "Task"
                        },
                    ],
                }
            }}, 'actions')
        self.check_output('''\
        class FooBar(Object):
            foo = "bar"

            def do_something(self, an_option=None):
                """
                The ``doSomething`` action.

                :param an_option: anOption (type: ``Task``)
                """
                params = {}
                if an_option is not None: params['anOption'] = an_option
                data = self.session.put(self.api_url()+'/doSomething', params)
        ''')

    def test_method_override(self):
        writer = ClassWriter('Update', '???', self.output)
        writer.write_header()
        writer.write_members(self.writer.format_action,
                             {'actions': {"update_obj": {}}}, 'actions')
        writer.write_footer()
        self.check_output('''
        class Update(Object):
            code = '???'

            @property
            def update_obj(self):
                """
                The object referenced by this update.
                """
                return self.session.api.from_data(
                    self.session, dict(
                        ID=self.update_obj_id,
                        objCode=self.update_obj_code
                    ))
        api.register(Update)
        ''')
コード例 #38
0
class TestControlNodeSerial(unittest.TestCase):

    def setUp(self):
        self.popen_patcher = mock.patch(
            'gateway_code.utils.subprocess_timeout.Popen')
        popen_class = self.popen_patcher.start()
        self.popen = popen_class.return_value

        self.popen.terminate.side_effect = self._terminate
        self.popen.poll.return_value = None

        self.readline_ret_vals = Queue.Queue(0)
        self.popen.stderr.readline.side_effect = self.readline_ret_vals.get
        self.readline_ret_vals.put('cn_serial_ready\n')

        self.cn = cn_interface.ControlNodeSerial('tty')
        self.log_error = LogCapture('gateway_code', level=logging.WARNING)

    def tearDown(self):
        self.cn.stop()
        mock.patch.stopall()
        self.log_error.uninstall()

    def _terminate(self):
        self.readline_ret_vals.put('')

    def test_normal_start_stop(self):
        ret_start = self.cn.start()
        self.assertEquals(0, ret_start)
        self.assertTrue(self.popen.stderr.readline.called)

        self.cn.stop()
        self.assertTrue(self.popen.terminate.called)
        self.assertTrue(self.readline_ret_vals.empty())

    def test_start_error_in_cn_serial(self):

        # poll should return an error
        self.popen.poll.return_value = 2

        ret_start = self.cn.start()
        self.assertNotEquals(0, ret_start)
        self.log_error.check(
            ('gateway_code', 'ERROR',
             'Control node serial reader thread ended prematurely'))
        self.cn.stop()

    def test_stop_before_start(self):
        self.cn.stop()

    def test_stop_with_cn_interface_allready_stopped(self):

        # Simulate cn_interface stopped
        self.readline_ret_vals.put('')
        self.popen.stdin.write.side_effect = IOError()
        self.popen.terminate.side_effect = OSError()

        self.cn.start()

        # try sending command
        ret = self.cn.send_command(['test', 'cmd'])
        self.assertEquals(None, ret)
        self.log_error.check(
            ('gateway_code', 'ERROR',
             'control_node_serial process is terminated'))

        self.log_error.clear()
        self.cn.stop()
        self.log_error.check(
            ('gateway_code', 'ERROR',
             'Control node process already terminated'))

    def test_stop_terminate_failed(self):
        """Stop cn_interface but terminate does not stop it."""
        # terminate does not stop process
        self.popen.terminate.side_effect = None
        timeout_expired = cn_interface.subprocess_timeout.TimeoutExpired
        self.popen.wait.side_effect = timeout_expired('cn_serial_interface', 3)
        # kill does it
        self.popen.kill.side_effect = self._terminate

        self.cn.start()
        self.cn.stop()

        self.assertTrue(self.popen.kill.called)
        self.log_error.check(('gateway_code', 'WARNING',
                              'Control node serial not terminated, kill it'))


# Test command sending
    def test_send_command(self):
        self.popen.stdin.write.side_effect = \
            (lambda *x: self.readline_ret_vals.put('start ACK\n'))

        self.cn.start()
        ret = self.cn.send_command(['start', 'DC'])
        self.assertEquals(['start', 'ACK'], ret)
        self.cn.stop()

    def test_send_command_no_answer(self):
        self.cn.start()
        ret = self.cn.send_command(['start', 'DC'])
        self.assertIsNone(ret)
        self.cn.stop()

    def test_send_command_cn_interface_stoped(self):
        ret = self.cn.send_command(['lala'])
        self.assertIsNone(ret)

    def test_answer_and_answer_with_queue_full(self):
        # get two answers without sending command
        self.readline_ret_vals.put('set ACK\n')
        self.readline_ret_vals.put('start ACK\n')

        self.cn.start()
        self.cn.stop()

        self.log_error.check(
            ('gateway_code', 'ERROR',
             'Control node answer queue full: %r' % ['start', 'ACK']))

# _cn_interface_args

    def test__cn_interface_args(self):
        args = self.cn._cn_interface_args()
        self.assertIn(self.cn.tty, args)
        self.assertNotIn('-c', args)
        self.assertNotIn('-d', args)

        # OML config
        args = self.cn._cn_interface_args('<omlc></omlc>')
        self.assertIn('-c', args)
        self.assertNotIn('-d', args)
        self.cn._oml_cfg_file.close()

        # Debug mode
        self.cn.measures_debug = (lambda x: None)
        args = self.cn._cn_interface_args()
        self.assertNotIn('-c', args)
        self.assertIn('-d', args)

# _config_oml coverage tests

    def test_empty_config_oml(self):
        # No experiment description
        ret = self.cn._oml_config_file(None)
        self.assertIsNone(ret)

    @mock.patch(utils.READ_CONFIG, utils.read_config_mock('m3'))
    def test_config_oml(self):
        oml_xml_cfg = '''<omlc id='{node_id}' exp_id='{exp_id}'>\n</omlc>'''
        self.cn.start(oml_xml_cfg)
        self.assertIsNotNone(self.cn._oml_cfg_file)

        self.cn.stop()

    def test_oml_xml_config(self):
        exp_files = {
            'consumption': '/tmp/consumption',
            'radio': '/tmp/radio',
            'event': '/tmp/event',
            'sniffer': '/tmp/sniffer',
            'log': '/tmp/log',
        }

        oml_xml_cfg = self.cn.oml_xml_config('m3-1', '1234', exp_files)
        self.assertIsNotNone(oml_xml_cfg)
        self.assertTrue(oml_xml_cfg.startswith('<omlc'))

        # No output if none or empty
        oml_xml_cfg = self.cn.oml_xml_config('m3-1', '1234', None)
        self.assertIsNone(oml_xml_cfg)
        oml_xml_cfg = self.cn.oml_xml_config('m3-1', '1234', {})
        self.assertIsNone(oml_xml_cfg)
コード例 #39
0
class ShowBearsTest(unittest.TestCase):

    def setUp(self):
        self.console_printer = ConsolePrinter(print_colored=False)
        self.logs = LogCapture()
        self.logs.__enter__()

    deprecation_messages = [('root',
                             'WARNING',
                             'show_description parameter is deprecated'),
                            ('root',
                             'WARNING',
                             'show_params parameter is deprecated')]

    def tearDown(self):
        self.logs.__exit__(None, None, None)

    def test_show_bear_minimal(self):
        with retrieve_stdout() as stdout:
            show_bear(
                SomelocalBear, False, False, self.console_printer)
            self.assertEqual(stdout.getvalue(), 'SomelocalBear\n')

        self.logs.check(*self.deprecation_messages)

    def test_show_bear_desc_only(self):
        with retrieve_stdout() as stdout:
            show_bear(
                SomelocalBear, True, False, self.console_printer)
            self.assertEqual(
                stdout.getvalue(),
                'SomelocalBear\n  Some local-bear Description.\n\n')

        self.logs.check(*self.deprecation_messages)

    def test_show_bear_details_only(self):
        with retrieve_stdout() as stdout:
            show_bear(
                SomelocalBear, False, True, self.console_printer)
            self.assertEqual(stdout.getvalue(),
                             'SomelocalBear\n'
                             '  The bear does not provide information about '
                             'which languages it can analyze.\n\n'
                             '  No needed settings.\n\n'
                             '  No optional settings.\n\n'
                             '  This bear does not provide information about '
                             'what categories it can detect.\n\n'
                             '  This bear cannot fix issues or does not '
                             'provide information about what categories it '
                             'can fix.\n\n  Path:\n   ' +
                             repr(SomelocalBear.source_location) + '\n\n')

        self.logs.check(*self.deprecation_messages)

    def test_show_bear_long_without_content(self):
        with retrieve_stdout() as stdout:
            show_bear(
                SomelocalBear, True, True, self.console_printer)
            self.assertEqual(stdout.getvalue(),
                             'SomelocalBear\n'
                             '  Some local-bear Description.\n\n'
                             '  The bear does not provide information about '
                             'which languages it can analyze.\n\n'
                             '  No needed settings.\n\n'
                             '  No optional settings.\n\n'
                             '  This bear does not provide information about '
                             'what categories it can detect.\n\n'
                             '  This bear cannot fix issues or does not '
                             'provide information about what categories it '
                             'can fix.\n\n  Path:\n   ' +
                             repr(SomelocalBear.source_location) + '\n\n')

        self.logs.check(*self.deprecation_messages)

    def test_show_bear_with_content(self):
        with retrieve_stdout() as stdout:
            show_bear(TestBear, True, True, self.console_printer)
            self.assertEqual(stdout.getvalue(),
                             'TestBear\n'
                             '  Test bear Description.\n\n'
                             '  Supported languages:\n'
                             '   * F#\n'
                             '   * Shakespearean Programming Language\n\n'
                             '  Needed Settings:\n'
                             '   * setting1: Required Setting.\n\n'
                             '  Optional Settings:\n'
                             '   * setting2: Optional Setting. ('
                             "Optional, defaults to 'None'."
                             ')\n\n'
                             '  Can detect:\n   * Formatting\n\n'
                             '  Can fix:\n   * Formatting\n\n  Path:\n   ' +
                             repr(TestBear.source_location) + '\n\n')

        self.logs.check(*self.deprecation_messages)

    def test_show_bear_settings_only(self):
        with retrieve_stdout() as stdout:
            args = default_arg_parser().parse_args(['--show-settings'])
            show_bear(TestBear, False, False, self.console_printer, args)
            self.assertEqual(stdout.getvalue(),
                             'TestBear\n'
                             '  Needed Settings:\n'
                             '   * setting1: Required Setting.\n\n'
                             '  Optional Settings:\n'
                             '   * setting2: Optional Setting. ('
                             "Optional, defaults to 'None'.)\n\n")

        self.logs.check(*self.deprecation_messages)

    def test_show_bears_empty(self):
        with retrieve_stdout() as stdout:
            show_bears({}, {}, True, True, self.console_printer)
            self.assertIn('No bears to show.', stdout.getvalue())

        self.logs.check(*self.deprecation_messages)

    def test_show_bears_with_json(self):
        args = default_arg_parser().parse_args(['--json'])
        with retrieve_stdout() as stdout:
            show_bears({}, {}, True, True, self.console_printer, args)
            self.assertEqual('{\n  "bears": []\n}\n', stdout.getvalue())

        self.logs.check(*self.deprecation_messages)

    @patch('coalib.output.ConsoleInteraction.show_bear')
    def test_show_bears(self, show_bear):
        local_bears = OrderedDict([('default', [SomelocalBear]),
                                   ('test', [SomelocalBear])])
        show_bears(local_bears, {}, True, True, self.console_printer)
        show_bear.assert_called_once_with(SomelocalBear,
                                          True,
                                          True,
                                          self.console_printer,
                                          None)

        self.logs.check(*self.deprecation_messages)

    def test_show_bears_sorted(self):
        local_bears = OrderedDict([('default', [SomelocalBear]),
                                   ('test', [aSomelocalBear])])
        global_bears = OrderedDict([('default', [SomeglobalBear]),
                                    ('test', [BSomeglobalBear])])

        with retrieve_stdout() as stdout:
            show_bears(local_bears, global_bears, False,
                       False, self.console_printer)
            self.assertEqual(stdout.getvalue(),
                             'aSomelocalBear\n'
                             'BSomeglobalBear\n'
                             'SomeglobalBear\n'
                             'SomelocalBear\n')

        self.logs.check(*(self.deprecation_messages*5))

    def test_show_bears_capabilities(self):
        with retrieve_stdout() as stdout:
            show_language_bears_capabilities(
                {'some_language': (
                    {'Formatting', 'Security'}, {'Formatting'})},
                self.console_printer)
            self.assertIn('coala can do the following for SOME_LANGUAGE\n'
                          '    Can detect only: Formatting, Security\n'
                          '    Can fix        : Formatting\n',
                          stdout.getvalue())
            show_language_bears_capabilities(
                {'some_language': (set(), set())}, self.console_printer)
            self.assertIn('coala does not support some_language',
                          stdout.getvalue())
            show_language_bears_capabilities(
                {}, self.console_printer)
            self.assertIn(
                'There is no bear available for this language',
                stdout.getvalue())
            show_language_bears_capabilities(
                {'some_language': ({'Formatting', 'Security'}, set())},
                self.console_printer)
            self.assertIn('coala can do the following for SOME_LANGUAGE\n'
                          '    Can detect only: Formatting, Security\n',
                          stdout.getvalue())
コード例 #40
0
class Test(unittest.TestCase):

    def setUp(self):
        from testfixtures import LogCapture
        self.log_capture = LogCapture() 
        self.log_group  = 'phidgeter.relay'
        self.lvl = 'DEBUG'

    def tearDown(self):
        self.log_capture.uninstall()

    def test_log_captures(self):
        # verification of log matching functionality
        from logging import getLogger
        getLogger().info('a message')
        self.log_capture.check(('root', 'INFO', 'a message'))

    def test_zero_on_off_toggle(self):
        phd_relay = Relay()
        result = phd_relay.zero_off()
        self.assertTrue(result, "Successfully turned off")

        result = phd_relay.zero_on()
        self.assertTrue(result, "Successfully turned off")

        result = phd_relay.zero_toggle()
        self.assertTrue(result, "Successfully toggled")

    def test_one_on_off_toggle(self):
        phd_relay = Relay()
        result = phd_relay.one_off()
        self.assertTrue(result, "Successfully turned off")

        result = phd_relay.one_on()
        self.assertTrue(result, "Successfully turned off")

        result = phd_relay.one_toggle()
        self.assertTrue(result, "Successfully toggled")

    def test_two_on_off_toggle(self):
        phd_relay = Relay()
        result = phd_relay.two_off()
        self.assertTrue(result, "Successfully turned off")

        result = phd_relay.two_on()
        self.assertTrue(result, "Successfully turned off")

        result = phd_relay.two_toggle()
        self.assertTrue(result, "Successfully toggled")

    def test_three_on_off_toggle(self):
        phd_relay = Relay()
        result = phd_relay.three_off()
        self.assertTrue(result, "Successfully turned off")

        result = phd_relay.three_on()
        self.assertTrue(result, "Successfully turned off")

        result = phd_relay.three_toggle()
        self.assertTrue(result, "Successfully toggled")


    def test_open_phidget(self):
        """ Apparently, LogCapture is setup to compare the entire log
         entries at once. So go through all of the operations, then
         check the total log output at the end.
        """
        phd = Relay()
        self.assertTrue(phd.zero_on())

        gr = self.log_group
        self.log_capture.check(
            (gr, "DEBUG", "Start of phidgeter with serial: None"),
            (gr, "DEBUG", "Attempting to open phidget"),
            (gr, "DEBUG", "Attempt to open first found"),
            (gr, "DEBUG", "Wait for attach 10300ms"),
            (gr, "INFO", "Opened phidget"),
            (gr, "DEBUG", "Attempting to close phidget"),
            (gr, "INFO", "Closed phidget")
            )

    def test_phidget_by_serial(self):
        # Get the serial number of the phidget from the usb descriptor
        serial = self.find_serial()

        # connect to that phidget precisely
        phd = Relay(serial)
        self.assertTrue(phd.zero_on())

    def find_serial(self):
        """ On linux only, use pyusb to enumerate all devices connected
        to the bus, return the string from the usb descriptor, which is
        the device serial number.
        """
        import platform
        if platform.system() != "Linux":
            return self.find_windows_serial()

        print "Finding serial number using pyusb"
        import usb
        for bus in usb.busses():
            devices = bus.devices
            for dev in devices:
                if dev.idVendor == 0x06c2:
                    print "  idVendor:",hex(dev.idVendor)
                    print "  idProduct:",hex(dev.idProduct)
                    ld = dev.open()
                    local_serial = ld.getString(dev.iSerialNumber, 256)
                    return local_serial

        raise ValueError("Can't find phidget (linux)")

    def find_windows_serial(self):
        """ On windows, the phidget appears as an HID, and will not be
        enumerated by pyusb. Use the windows management information command to
        find ther deviceid, which has the serial number at the end.
        """

        from subprocess import Popen, PIPE
        
        print "Finding serial number using wmic"

        # Be careful how quotres are used in windows .bat files. 
        wmic_cmd = "wmic path CIM_LogicalDevice where " + \
                   "\'DeviceID like \"%%VID_06C2%%\"\' get /value"

        # Can call popen directly, if you can figure out the escaping
        bat_out = open("wmic_cmd.bat", "w")
        bat_out.write(wmic_cmd)
        bat_out.close()

        sp = Popen("wmic_cmd.bat", stdin=PIPE, stdout=PIPE, stderr=PIPE)
        stdout, stderr = sp.communicate()

        # on the command line stdout is the return code, stderr is the
        # response of the wmic command. In popen land it is reversed.
        # Mogrify the string to be the end of the deviceid line, and
        # nothing after
        for line in stdout.split("\r"):
            if "DeviceID=USB" in line:
                local_serial = line.split("\\")[-1]
                local_serial = local_serial.split("\r")[0]
                return local_serial

        return "serial not found"
コード例 #41
0
ファイル: test_base.py プロジェクト: peteches/servercheck
class TestBase(object):

    """Tests Servercheck base class"""

    def __init__(self):
        """TODO: to be defined1. """
        self.logger = logging.getLogger('TestBase')

        self.passing_msg = 'Test has Passed'
        self.failing_msg = 'Test has Failed'

        self.report_logname = 'servercheck'

    def setup(self):
        self.log_capture = LogCapture()
        self.verbose_tester = BaseTester(verbose=True,
                                         item='verbose_test')

        self.default_tester = BaseTester(item='default_test')

        self.verbose_logname = '{}.{}.verbose_test'.format('servercheck',
                                                           self.verbose_tester.__class__.__name__)  # nopep8
        self.default_logname = '{}.{}.default_test'.format('servercheck',
                                                        self.default_tester.__class__.__name__)  # nopep8

    def teardown(self):
        self.log_capture.uninstall_all()

    def test_verbose_output_from_passing_test(self):
        self.verbose_tester.passed(self.passing_msg)

        self.log_capture.check(
            (self.verbose_logname,
             'INFO',
             '\033[1;32mPASS: {}\033[0m'.format(self.passing_msg)
             )
        )

    def test_default_output_from_passing_test(self):
        self.default_tester.passed(self.passing_msg)

        self.log_capture.check()

    def test_verbose_output_from_failing_test(self):
        self.verbose_tester.failed(self.failing_msg)

        self.log_capture.check(
            (self.verbose_logname,
             'WARNING',
             '\033[1;31mFAIL: {}\033[0m'.format(self.failing_msg)
             )
        )

    def test_default_output_from_failing_test(self):
        self.default_tester.failed(self.failing_msg)

        self.log_capture.check(
            (self.default_logname,
             'WARNING',
             '\033[1;31mFAIL: {}\033[0m'.format(self.failing_msg)
             )
        )

    def test_report_with_no_failing_tests(self):
        self.default_tester.passed(self.passing_msg)

        self.default_tester.report()

        self.log_capture.check(
            (self.report_logname,
             'INFO',
             '----- Report: -----\n\n'
             '\033[1;32mAll tests passed, YAY!\033[0m\n\n'
             '-------------------',
             )
        )

    def test_report_with_one_failing_test(self):
        self.default_tester.failed(self.failing_msg)

        self.default_tester.report()

        self.log_capture.check(
            (self.default_logname,
             'WARNING',
             '\033[1;31mFAIL: {}\033[0m'.format(self.failing_msg)
             ),
            (self.report_logname,
             'WARNING',
             '----- Report: -----\n\n'
             '\033[1;31mFAIL: {}\033[0m\n\n'
             '-------------------'.format(self.failing_msg),
             ),
        )

    def test_report_with_multiple_failing_tests(self):
        self.default_tester.failed(self.failing_msg)
        self.default_tester.failed(self.failing_msg)

        self.default_tester.report()

        self.log_capture.check(
            (self.default_logname,
             'WARNING',
             '\033[1;31mFAIL: {}\033[0m'.format(self.failing_msg)
             ),
            (self.default_logname,
             'WARNING',
             '\033[1;31mFAIL: {}\033[0m'.format(self.failing_msg)
             ),
            (self.report_logname,
             'WARNING',
             '----- Report: -----\n\n'
             '\033[1;31mFAIL: {}\033[0m\n'
             '\033[1;31mFAIL: {}\033[0m\n\n'
             '-------------------'.format(self.failing_msg,
                                          self.failing_msg)
             )
        )
コード例 #42
0
class LoggerTests(unittest.TestCase):
    '''Test if MgProxy correctly logs messages to console'''
    @classmethod
    def setUpClass(cls):
        '''Sets up the logger once before the test_functions are called'''
        logging.config.dictConfig(MG_LOGGER)

    def setUp(self):
        # The logger itself
        self.logger = logging.getLogger(MG_LOGGER_CONST['base_name'])

        # For each test a new LogCapture instance is called
        self.log_capt = LogCapture(MG_LOGGER_CONST['base_name'])

        # Empties the list (do not want to assign a new empty list)
        del ADDRESS_ERROR[:]

    def tearDown(self):
        # Simply uninstalls the log capture instance (warning otherwise)
        self.log_capt.uninstall()

        # Remove the created jpeg files from the files folder
        base_path = 'test/files'

        filelist = [f for f in os.listdir(base_path) if f.endswith(".jpg")]
        for f in filelist:
            if f.startswith('delete'):
                os.remove(os.path.join(base_path, f))

    def testEmptyFile(self):
        '''Tests the log output for an empty file'''
        file_path = self.helperFilePath('empty_input.txt')

        # sys.argv always returns a list, so I need to supply a list
        main([file_path])
        log_list = self.helperLogTemplate(file_path, 0, 0, 0)
        self.log_capt.check(*log_list)

    def testCorrectFile(self):
        '''Tests syntatically correct files where all cards exist'''
        file_path = self.helperFilePath('good_input.txt')

        # sys.argv always returns a list, so I need to supply a list
        # The saved jpgs will be called delete.jpg (deleted by tearDown)
        main([file_path, '-f', 'delete'])
        log_list = self.helperLogTemplate(
            file_path, 4, 1, 0, self.logCardPaste((None, 2, None, 'Swamp')),
            self.logCardPaste((None, 2, 'M10', 'Forest')))

        self.log_capt.check(*log_list)

    def testBadParse(self):
        '''Test various versions of bad parse'''
        file_path = self.helperFilePath('bad_parse_input.txt')
        with open(file_path, 'r') as f:
            parseFile(f)

        self.log_capt.check(
            self.logBadParse('Forest'),
            self.logBadParse('[M10] Forest'),
            self.logBadParse('SB: Forest'),
            self.logBadParse('A Forest'),
            self.logBadParse('2'),
            self.logBadParse('SB: 2'),
            self.logBadParse('2Forest'),
            self.logBadParse('SB: 1[M10] Forest'),
        )

    def testBadFile(self):
        '''Test logging when input file cannot be accessed'''
        file_path = '/file/does/not/exist'

        main([file_path])
        self.log_capt.check(self.logStart(), self.logBadFile(file_path))

    def testNetworkError(self):
        '''Test that a timeout is correctly logged'''

        # Set timeout flag (will be reset in setUp)
        ADDRESS_ERROR.append('timeout')

        creator = self.helperInitGetImage()
        creator.getMgImageFromWeb(MgQueueCar((None, 10, None, 'Swamp')))
        creator.getMgImageFromWeb(MgQueueCar(('SB:', '1', 'M10', 'Forest')))

        self.log_capt.check(
            self.logNetworkError((None, 10, None, 'Swamp'),
                                 createAddress('Swamp', None)),
            self.logNetworkError(('SB:', 1, 'M10', 'Forest'),
                                 createAddress('Forest', 'M10')))

    def testCard404(self):
        '''Test for non-existant cards'''
        creator = self.helperInitGetImage()
        creator.getMgImageFromWeb(MgQueueCar((None, 10, None, 'ForestXXX')))
        creator.getMgImageFromWeb(MgQueueCar(('SB:', 1, 'XXX', 'Swamp')))

        self.log_capt.check(self.logCard404((None, 10, None, 'ForestXXX')),
                            self.logCard404(('SB:', 1, 'XXX', 'Swamp')))

    def testBadContentType(self):
        '''Tests logging for bad content type'''
        # Causes the content type error by returning html address
        ADDRESS_ERROR.append('content_type')

        creator = self.helperInitGetImage()
        creator.getMgImageFromWeb(MgQueueCar((None, 10, None, 'Swamp')))
        creator.getMgImageFromWeb(MgQueueCar(('SB:', '1', 'M10', 'Forest')))

        self.log_capt.check(
            self.logBadTypeContent((None, 10, None, 'Swamp'), 'image/jpeg',
                                   'text/html; charset=utf-8'),
            self.logBadTypeContent(('SB:', 1, 'M10', 'Forest'), 'image/jpeg',
                                   'text/html; charset=utf-8'))

    def testBadSave(self):
        '''Test logging of save location that does not exist'''
        reporter = MgReport()
        bad_path = '/does/not/exist'
        file_name = 'page'
        saved_file_name = 'page0.jpg'
        saver = MgSaveThread(None, bad_path, file_name, reporter, self.logger)

        # Fake canvas has to be supplied for the function to manipulate
        qc = MgQueueCar()
        qc.image = createCanvas(1, (1, 1), (1, 1))

        saver.saveFunc(qc)
        self.log_capt.check(self.logBadSave(bad_path, saved_file_name))

    def helperInitMgCreator(self):
        '''Creates an instance of the MgImageCreator class'''
        return MgImageCreator(CON.DPI, (CON.WIDTH, CON.HIGHT),
                              (CON.PAGE_X, CON.PAGE_Y), self.logger)

    def helperInitGetImage(self):
        '''Creates an instance of the MgGetImageThread class.

        As the thread will never be run and only used to call
        getMgImageFromWeb, none of the init variables except the logger
        need to be supplied.
        '''
        return MgGetImageThread(None, None, None, None, self.logger)

    def helperFilePath(self, file_name):
        '''Return the relative file path from the module root'''
        base_path = 'test/files'
        return os.path.join(base_path, file_name)

    def helperLogTemplate(self, file_path, cards, pages, errors, *args):
        '''Creates the boiler blate logging calls'''
        log_list = [self.logStart()]

        if file_path:
            log_list.append(self.logSave(file_path))

        if args:
            log_list = log_list + list(args)

        log_list.append(self.logTotal(cards, pages, errors))

        return log_list

    def logStart(self):
        '''Returns program start log message tuple for testing purposes'''
        return (MG_LOGGER_CONST['base_name'], 'INFO',
                MG_LOGGER_CONST['start_prog'])

    def logCardPaste(self, card_input):
        '''Returns log message when a card is succesfully pasted'''
        card_name = logCardName(card_input)
        return (MG_LOGGER_CONST['base_name'], 'INFO',
                MG_LOGGER_CONST['good_paste'] % (card_input[1], card_name))

    def logSave(self, file_path):
        '''Returns log message stating the save directory'''
        directory, file_name = getFileNamePath(file_path)
        return (MG_LOGGER_CONST['base_name'], 'INFO',
                MG_LOGGER_CONST['save_loc'] % directory)

    def logBadSave(self, invalid_path, file_name):
        full_path = os.path.join(invalid_path, file_name)
        return (MG_LOGGER_CONST['base_name'], 'ERROR',
                MG_LOGGER_CONST['save_fail'] %
                (full_path, 'No such file or directory'))

    def logTotal(self, card_numb, page_numb, errors):
        '''Returns log message stating card number pasted across numb pages'''
        return (MG_LOGGER_CONST['base_name'], 'INFO',
                MG_LOGGER_CONST['final_msg'] % (card_numb, page_numb, errors))

    def logBadParse(self, line):
        '''Error message when input line cannot be parsed'''
        return (MG_LOGGER_CONST['base_name'], 'ERROR',
                MG_LOGGER_CONST['bad_parse'] % line)

    def logBadFile(self, file_path):
        '''Error log when input file does not exist or could not be accessed'''
        return (MG_LOGGER_CONST['base_name'], 'CRITICAL',
                MG_LOGGER_CONST['bad_input'] % file_path)

    def logNetworkError(self, card_input, address):
        '''Error log when website access times out'''
        card_name = logCardName(card_input)
        return (MG_LOGGER_CONST['base_name'], 'ERROR',
                MG_LOGGER_CONST['card_error'] %
                (card_name, MG_LOGGER_CONST['network_error'] %
                 (address, '[Errno 111] Connection refused')))

    def logCard404(self, card_input):
        '''Error logged when card cannot be downloaded'''
        card_name = logCardName(card_input)
        return (MG_LOGGER_CONST['base_name'], 'ERROR',
                MG_LOGGER_CONST['card_error'] %
                (card_name, MG_LOGGER_CONST['html_error'] %
                 (404, createAddress(card_input[3], card_input[2]))))

    def logBadTypeContent(self, card_input, expected, received):
        '''Error logged when file content type is unexpected'''
        card_name = logCardName(card_input)
        return (
            MG_LOGGER_CONST['base_name'], 'ERROR',
            MG_LOGGER_CONST['card_error'] %
            (card_name, MG_LOGGER_CONST['ct_error'] %
             (expected, received, createAddress(card_input[3], card_input[2])))
        )
コード例 #43
0
class DjangoHookboxTest(TestCase):
    def _cb_all(self, op, user, channel='-', payload=None):
        if channel in self.all_calls:
            self.all_calls[channel] += 1
        else:
            self.all_calls[channel] = 1
        return None

    def _cb_create(self, op, user, channel=None):
        if channel in self.create_calls:
            self.create_calls[channel] += 1
        else:
            self.create_calls[channel] = 1

        if channel == '/a/':
            return {
                'history_size': 2,
                'reflective': False,
                'presenceful': False,
                'moderated': True,
            }
        elif channel == '/b/':
            return 'denied'
        elif channel == '/c/':
            return [False, {'msg': 'also denied'}]
        else:
            return None

    def setUp(self):
        self.all_calls = {}
        self.create_calls = {}

        # HACK: don't allow other apps to mess with us or vice versa...
        self.old_cbs = djhookbox.views._callbacks
        djhookbox.views._callbacks = []
        djhookbox.whcallback(self._cb_all)
        djhookbox.whcallback('create')(self._cb_create)

        User.objects.create_user('a', '*****@*****.**', 'a').save()

        self.logcap = LogCapture()

    def tearDown(self):
        djhookbox.views._callbacks = self.old_cbs
        self.logcap.uninstall()

    @server
    def test_create(self):
        self.assertRaises(djhookbox.HookboxError, djhookbox.publish, '/a/',
                          json.dumps({'foo': 'bar'}))

        djhookbox.create('/a/')
        djhookbox.publish('/a/', json.dumps({'foo': 'bar'}))

        # TODO: Test send_hook works
        # TODO: Confirm it actually did something

    @server
    def test_web_api_token(self):
        secret = djhookbox.apitoken
        try:
            djhookbox.apitoken += '...not!'
            self.assertRaises(djhookbox.HookboxError, djhookbox.publish, '/a/',
                              json.dumps({'foo': 'bar'}))
            self.assertCreateCalls({})
        finally:
            djhookbox.apitoken = secret

    def test_webhook_secret(self):
        self.client.login(username='******', password='******')
        response = self.client.post(connect_url, {
            'channel_name': 'a',
            'secret': djhookbox.views.secret,
        })
        self.assertSuccess(response)

        response = self.client.post(connect_url, {
            'channel_name': 'a',
        })
        data = self.decode(response)
        self.assertFalse(
            data[0],
            'webhook secret verification should have failed (forgotton to set settings.HOOKBOX_WEBHOOK_SECRET?)'
        )

        response = self.client.post(
            connect_url, {
                'channel_name': 'a',
                'secret': djhookbox.views.secret + '...not!',
            })
        data = self.decode(response)
        self.assertFalse(data[0],
                         'webhook secret verification should have failed')

    def test_signals(self):
        class Listener(object):
            def __call__(self, *args, **kwargs):
                self.signal = kwargs.get('signal')
                self.sender = kwargs.get('sender').username
                self.kwargs = kwargs

        def doTest(which, params=dict(), **checks):
            listener = Listener()
            djhookbox.views.signals[which].connect(listener)

            self.client.login(username='******', password='******')
            params['secret'] = djhookbox.views.secret
            response = self.client.post(reverse('hookbox_%s' % which), params)

            self.assertSuccess(response)
            self.assertEquals(listener.sender, 'a')
            for (key, value) in checks.iteritems():
                self.assertEquals(listener.kwargs.get(key), value)

            self.client.logout()
            djhookbox.views.signals[which].disconnect(listener)

        doTest('connect')
        doTest('disconnect')
        doTest('subscribe', {'channel_name': 'b'}, channel='b')
        doTest('unsubscribe', {'channel_name': 'b'}, channel='b')

    def test_all_cbs(self):
        self.client.login(username='******', password='******')
        params = {
            'secret': djhookbox.views.secret,
            'channel_name': 'a',
        }

        response = self.client.post(connect_url, params)
        self.assertSuccess(response)
        self.assertAllCalls({'-': 1})

        response = self.client.post(reverse('hookbox_subscribe'), params)
        self.assertSuccess(response)
        self.assertAllCalls({'-': 1, 'a': 1})

        response = self.client.post(
            reverse('hookbox_publish'), {
                'secret': djhookbox.views.secret,
                'channel_name': 'a',
                'payload': json.dumps(["Hello world"]),
            })
        self.assertSuccess(response)
        self.assertAllCalls({'-': 1, 'a': 2})

        response = self.client.post(reverse('hookbox_destroy_channel'), params)
        self.assertSuccess(response)
        self.assertAllCalls({'-': 1, 'a': 3})

        response = self.client.post(reverse('hookbox_disconnect'), params)
        self.assertSuccess(response)
        self.assertAllCalls({'-': 2, 'a': 3})

    def test_warn_multiple_results(self):
        @djhookbox.whcallback
        def _cb_1(op, user, channel='-'):
            return [True, {}]

        @djhookbox.whcallback
        def _cb_2(op, user, channel='-'):
            return [True, {}]

        params = {'secret': djhookbox.views.secret}

        logging.getLogger('djhookbox').setLevel(logging.WARNING)

        response = self.client.post(connect_url, params)
        self.assertSuccess(response)
        self.assertAllCalls({'-': 1})

        response = self.client.post(reverse('hookbox_disconnect'), params)
        self.assertSuccess(response)
        self.assertAllCalls({'-': 2})

        self.logcap.check(
            ('djhookbox', 'WARNING',
             'multiple results returned from connect callback'),
            ('djhookbox', 'WARNING',
             'multiple results returned from disconnect callback'),
        )

    def test_explicit_deny(self):
        response = self.client.post(reverse('hookbox_create_channel'), {
            'secret': djhookbox.views.secret,
            'channel_name': '/b/',
        })

        data = self.decode(response)
        self.assertEquals(data[0], False, 'unexpected success')
        self.assertEquals(data[1], {'msg': 'denied'})
        self.assertAllCalls({'/b/': 1})

        response = self.client.post(reverse('hookbox_create_channel'), {
            'secret': djhookbox.views.secret,
            'channel_name': '/c/',
        })

        data = self.decode(response)
        self.assertEquals(data[0], False, 'unexpected success')
        self.assertEquals(data[1], {'msg': 'also denied'})
        self.assertAllCalls({'/b/': 1, '/c/': 1})

    def test_callback_error(self):
        @djhookbox.whcallback
        def _cb_1(op, user, channel='-'):
            raise Exception('something bad')

        response = self.client.post(reverse('hookbox_create_channel'), {
            'secret': djhookbox.views.secret,
            'channel_name': '/a/',
        })

        data = self.decode(response)
        self.assertEquals(data[0], False, 'unexpected success')
        self.assertEquals(data[1], {'msg': 'something bad'})
        self.assertAllCalls({'/a/': 1})

    def decode(self, response):
        self.assertEquals(response.status_code, 200)
        self.assert_(('Content-Type', 'application/json') in response.items())

        result = json.loads(response.content)
        self.assert_(
            isinstance(result, list),
            'unexpected result returned from server: %s' % str(result))
        self.assertEquals(len(result), 2)
        self.assert_(
            isinstance(result[0], bool),
            'unexpected result returned from server: %s' % str(result))
        self.assert_(
            isinstance(result[1], dict),
            'unexpected result returned from server: %s' % str(result))
        return result

    def assertSuccess(self, response):
        data = self.decode(response)

        if not data[0] and 'msg' in data[1]:
            self.fail(data[1]['msg'])
        else:
            self.assert_(data[0])

    def assertAllCalls(self, calls):
        self.assertEquals(self.all_calls, calls)

    def assertCreateCalls(self, calls):
        self.assertEquals(self.create_calls, calls)
コード例 #44
0
class SessionTests(MockOpenHelper, TestCase):

    def setUp(self):
        super(SessionTests, self).setUp()
        self.log = LogCapture()
        self.addCleanup(self.log.uninstall)

    def test_basic_request(self):
        session = Session('test')
        self.server.add(
            url='/login',
            params='method=GET',
            response='{"data": "foo"}'
        )
        compare(session.get('/login'), expected='foo')
        self.server.assert_called(times=1)
        self.log.check(
            ('workfront', 'INFO',
             "url: https://test.attask-ondemand.com/attask/api/unsupported"
             "/login "
             "params: {'method': 'GET'}"),
            ('workfront', 'DEBUG',
             'returned: {\n    "data": "foo"\n}')
        )

    def test_different_protocol_and_version(self):
        self.server.base_url = ''
        session = Session('test', protocol='http', api_version='v4.0')
        self.server.add(
            url='http://test.attask-ondemand.com/attask/api/v4.0/login',
            params='method=GET',
            response='{"data": "foo"}'
        )
        compare(session.get('/login'), expected='foo')
        self.server.assert_called(times=1)

    def test_different_url_template(self):
        self.server.base_url = ''
        session = Session('test', url_template=SANDBOX_TEMPLATE)
        self.server.add(
            url='https://test.attasksandbox.com/attask/api/unsupported/login',
            params='method=GET',
            response='{"data": "foo"}'
        )
        compare(session.get('/login'), expected='foo')
        self.server.assert_called(times=1)

    def test_http_error(self):
        # somewhat hypothetical, error is usually in the return json
        session = Session('test')
        self.server.add(
            url='/login',
            params='method=GET',
            response=MockHTTPError('{"data": "foo"}', 500),
        )
        with ShouldRaise(WorkfrontAPIError('Unknown error, check log', 500)):
            session.get('/login')
        self.server.assert_called(times=1)

    def test_api_error(self):
        session = Session('test')
        self.server.add(
            url='/',
            params='method=GET',
            response='{"error":{'
                     '"class":"java.lang.UnsupportedOperationException",'
                     '"message":"you must specify an action"}}'
        )
        with ShouldRaise(WorkfrontAPIError(
                {u'message': u'you must specify an action',
                 u'class': u'java.lang.UnsupportedOperationException'},
                200
        )):
            session.get('/')
        self.server.assert_called(times=1)

    def test_api_error_str_and_repr(self):
        error = WorkfrontAPIError('data', 503)
        compare(str(error), expected="503: 'data'")
        compare(repr(error), expected="WorkfrontAPIError('data', 503)")

    def test_other_error(self):
        session = Session('test')
        self.server.add(
            url='/',
            params='method=GET',
            response=Exception('boom!')
        )
        with ShouldRaise(Exception('boom!')):
            session.get('/')
        self.server.assert_called(times=1)

    def test_bad_json(self):
        session = Session('test')
        self.server.add(
            url='/',
            params='method=GET',
            response="{'oops': 'not json'}"
        )
        with ShouldRaise(WorkfrontAPIError(
                {'exception': 'Expecting property name enclosed in double '
                              'quotes: line 1 column 2 (char 1)',
                 'response': u"{'oops': 'not json'}"},
                200
        )):
            session.get('/')
        self.server.assert_called(times=1)

    def test_insecure_context(self):
        context = ssl._create_stdlib_context()
        session = Session('test', ssl_context=context)
        self.server.add(
            url='/login',
            params='method=GET',
            response='{"data": "foo"}',
            ssl_context=context
        )
        compare(session.get('/login'), expected='foo')
        self.server.assert_called(times=1)

    def test_login(self):
        session = Session('test')
        self.server.add(
            url='/login',
            params='method=GET&username=u&password=p',
            response='{"data": {"sessionID": "x", "userID": "uid"}}'
        )
        session.login('u', 'p')
        compare(session.session_id, 'x')
        compare(session.user_id, 'uid')
        self.server.assert_called(times=1)
        return session

    def test_logout(self):
        session = self.test_login()
        self.server.add(
            url='/logout',
            params='method=GET&sessionID=x',
            response='{"data": null}'
        )
        session.logout()
        compare(session.session_id, None)
        compare(session.user_id, None)
        self.server.assert_called(times=2)

    def test_request_with_session_id(self):
        session = self.test_login()
        self.server.add(
            url='/ISSUE',
            params='method=GET&sessionID=x',
            response='{"data": "foo"}'
        )
        compare(session.get('/ISSUE'), 'foo')
        self.server.assert_called(times=2)

    def test_get_api_key(self):
        session = Session('test')
        self.server.add(
            url='/user',
            params='method=PUT&action=getApiKey&username=u&password=p',
            response='{"data": {"result": "xyz"}}'
        )
        compare(session.get_api_key('u', 'p'), 'xyz')
        self.server.assert_called(times=1)

    def test_request_with_api_key(self):
        session = Session('test', api_key='xyz')
        self.server.add(
            url='/ISSUE',
            params='method=GET&apiKey=xyz',
            response='{"data": "foo"}'
        )
        actual = session.request('GET', '/ISSUE')
        compare(actual, expected='foo')
        self.server.assert_called(times=1)

    def test_request_with_params(self):
        session = Session('test')
        self.server.add(
            url='/endpoint',
            params='method=GET&str=svalue&unicode=uvalue&int=1&float=1.0&'
                   'dict={"key": "value"}',
            response='{"data": "foo"}'
        )
        actual = session.request('GET', '/endpoint', params={
            'str': 'svalue',
            'unicode': u'uvalue',
            'int': 1,
            'float': 1.0,
            'dict': {'key': 'value'},
        })
        compare(actual, expected='foo')
        self.server.assert_called(times=1)

    def test_request_absolute_url(self):

        session = Session('test')
        self.server.add(
            url='/some/url',
            params='method=GET',
            response='{"data": "foo"}'
        )
        actual = session.request(
            'GET',
            'https://test.attask-ondemand.com/attask/api/unsupported/some/url'
        )
        compare(actual, expected='foo')
        self.server.assert_called(times=1)

    def test_request_with_dodgy_absolute_url(self):

        session = Session('test')
        with ShouldRaise(TypeError(
            'url not for this session: '
            'https://bad.example.com/attask/api/unsupported/some/url'
        )):
            session.request(
                'GET',
                'https://bad.example.com/attask/api/unsupported/some/url'
            )

    def test_get(self):
        session = self.test_login()
        self.server.add(
            url='/ISSUE',
            params='sessionID=x&method=GET',
            response='{"data": "foo"}'
        )
        actual = session.get('/ISSUE')
        compare(actual, expected='foo')
        self.server.assert_called(times=2)

    def test_post(self):
        session = self.test_login()
        self.server.add(
            url='/ISSUE',
            params='sessionID=x&method=POST',
            response='{"data": "foo"}'
        )
        actual = session.post('/ISSUE')
        compare(actual, expected='foo')
        self.server.assert_called(times=2)

    def test_put(self):
        session = Session('test', api_key='xyz')
        self.server.add(
            url='/ISSUE',
            params='method=PUT&apiKey=xyz',
            response='{"data": "foo"}'
        )
        actual = session.put('/ISSUE')
        compare(actual, expected='foo')
        self.server.assert_called(times=1)

    def test_delete(self):
        session = Session('test', api_key='xyz')
        self.server.add(
            url='/ISSUE',
            params='method=DELETE&apiKey=xyz',
            response='{"data": "foo"}'
        )
        actual = session.delete('/ISSUE')
        compare(actual, expected='foo')
        self.server.assert_called(times=1)

    def test_warn_on_unknown_api(self):
        with ShouldWarn(UserWarning(
            'No APIVersion for silly, only basic requests possible'
        )):
            Session('test', api_version='silly')
コード例 #45
0
ファイル: test_main.py プロジェクト: Simplistix/archivist
class TestSafeNotifications(TestCase):

    def setUp(self):
        self.capture = LogCapture()
        self.addCleanup(self.capture.uninstall)
        self.logger = getLogger()

    def test_okay(self):
        with SafeNotifications([
            DummyNotifier('one', self.logger),
            DummyNotifier('two', self.logger),
        ]):
            self.logger.info('payload')

        self.capture.check(
            ('root', 'INFO', 'start-one'),
            ('root', 'INFO', 'start-two'),
            ('root', 'INFO', 'payload'),
            ('root', 'INFO', 'finish-two'),
            ('root', 'INFO', 'finish-one'),
        )

    def test_exception(self):
        with SafeNotifications([DummyNotifier('one', self.logger)]):
            raise Exception('Boom!')

        self.capture.check(
            ('root', 'INFO', 'start-one'),
            ('archivist.main', 'ERROR', 'unexpected error:'),
            ('root', 'INFO', 'finish-one'),
        )

    def test_notification_start_fail(self):
        with SafeNotifications([
            DummyNotifier('one', self.logger),
            DummyNotifier('two', self.logger, bad_start=True),
        ]):
            self.logger.info('payload')

    def test_notification_finish_failed(self):
        with SafeNotifications([
            DummyNotifier('one', self.logger),
            DummyNotifier('two', self.logger, bad_finish=True),
        ]):
            self.logger.info('payload')

    def test_notification_start_none_setup(self):
        with ShouldRaise(Exception('start-one')):
            with SafeNotifications([
                DummyNotifier('one', self.logger, bad_start=True)
            ]):
                self.logger.info('payload')

        self.capture.check() # no logging!

    def test_notification_start_none_finished(self):
        with ShouldRaise(Exception('finish-one')):
            with SafeNotifications([
                DummyNotifier('one', self.logger, bad_finish=True)
            ]):
                self.logger.info('payload')

        self.capture.check(
            ('root', 'INFO', 'start-one'),
            ('root', 'INFO', 'payload'),
        )
コード例 #46
0
class ShowBearsTest(unittest.TestCase):
    def setUp(self):
        self.console_printer = ConsolePrinter(print_colored=False)
        self.logs = LogCapture()
        self.logs.__enter__()

    deprecation_messages = [
        ('root', 'WARNING', 'show_description parameter is deprecated'),
        ('root', 'WARNING', 'show_params parameter is deprecated')
    ]

    def tearDown(self):
        self.logs.__exit__(None, None, None)

    def test_show_bear_minimal(self):
        with retrieve_stdout() as stdout:
            show_bear(SomelocalBear, False, False, self.console_printer)
            self.assertEqual(stdout.getvalue(), 'SomelocalBear\n')

        self.logs.check(*self.deprecation_messages)

    def test_show_bear_desc_only(self):
        with retrieve_stdout() as stdout:
            show_bear(SomelocalBear, True, False, self.console_printer)
            self.assertEqual(
                stdout.getvalue(),
                'SomelocalBear\n  Some local-bear Description.\n\n')

        self.logs.check(*self.deprecation_messages)

    def test_show_bear_details_only(self):
        with retrieve_stdout() as stdout:
            show_bear(SomelocalBear, False, True, self.console_printer)
            self.assertEqual(
                stdout.getvalue(), 'SomelocalBear\n'
                '  The bear does not provide information about '
                'which languages it can analyze.\n\n'
                '  No needed settings.\n\n'
                '  No optional settings.\n\n'
                '  This bear does not provide information about '
                'what categories it can detect.\n\n'
                '  This bear cannot fix issues or does not '
                'provide information about what categories it '
                'can fix.\n\n  Path:\n   ' +
                repr(SomelocalBear.source_location) + '\n\n')

        self.logs.check(*self.deprecation_messages)

    def test_show_bear_long_without_content(self):
        with retrieve_stdout() as stdout:
            show_bear(SomelocalBear, True, True, self.console_printer)
            self.assertEqual(
                stdout.getvalue(), 'SomelocalBear\n'
                '  Some local-bear Description.\n\n'
                '  The bear does not provide information about '
                'which languages it can analyze.\n\n'
                '  No needed settings.\n\n'
                '  No optional settings.\n\n'
                '  This bear does not provide information about '
                'what categories it can detect.\n\n'
                '  This bear cannot fix issues or does not '
                'provide information about what categories it '
                'can fix.\n\n  Path:\n   ' +
                repr(SomelocalBear.source_location) + '\n\n')

        self.logs.check(*self.deprecation_messages)

    def test_show_bear_with_content(self):
        with retrieve_stdout() as stdout:
            show_bear(TestBear, True, True, self.console_printer)
            self.assertEqual(
                stdout.getvalue(), 'TestBear\n'
                '  Test bear Description.\n\n'
                '  Supported languages:\n'
                '   * F#\n'
                '   * Shakespearean Programming Language\n\n'
                '  Needed Settings:\n'
                '   * setting1: Required Setting.\n\n'
                '  Optional Settings:\n'
                '   * setting2: Optional Setting. ('
                "Optional, defaults to 'None'."
                ')\n\n'
                '  Can detect:\n   * Formatting\n\n'
                '  Can fix:\n   * Formatting\n\n  Path:\n   ' +
                repr(TestBear.source_location) + '\n\n')

        self.logs.check(*self.deprecation_messages)

    def test_show_bear_settings_only(self):
        with retrieve_stdout() as stdout:
            args = default_arg_parser().parse_args(['--show-settings'])
            show_bear(TestBear, False, False, self.console_printer, args)
            self.assertEqual(
                stdout.getvalue(), 'TestBear\n'
                '  Needed Settings:\n'
                '   * setting1: Required Setting.\n\n'
                '  Optional Settings:\n'
                '   * setting2: Optional Setting. ('
                "Optional, defaults to 'None'.)\n\n")

        self.logs.check(*self.deprecation_messages)

    def test_show_bears_empty(self):
        with retrieve_stdout() as stdout:
            show_bears({}, {}, True, True, self.console_printer)
            self.assertIn('No bears to show.', stdout.getvalue())

        self.logs.check(*self.deprecation_messages)

    def test_show_bears_with_json(self):
        args = default_arg_parser().parse_args(['--json'])
        with retrieve_stdout() as stdout:
            show_bears({}, {}, True, True, self.console_printer, args)
            self.assertEqual('{\n  "bears": []\n}\n', stdout.getvalue())

        self.logs.check(*self.deprecation_messages)

    @patch('coalib.output.ConsoleInteraction.show_bear')
    def test_show_bears(self, show_bear):
        local_bears = OrderedDict([('default', [SomelocalBear]),
                                   ('test', [SomelocalBear])])
        show_bears(local_bears, {}, True, True, self.console_printer)
        show_bear.assert_called_once_with(SomelocalBear, True, True,
                                          self.console_printer, None)

        self.logs.check(*self.deprecation_messages)

    def test_show_bears_sorted(self):
        local_bears = OrderedDict([('default', [SomelocalBear]),
                                   ('test', [aSomelocalBear])])
        global_bears = OrderedDict([('default', [SomeglobalBear]),
                                    ('test', [BSomeglobalBear])])

        with retrieve_stdout() as stdout:
            show_bears(local_bears, global_bears, False, False,
                       self.console_printer)
            self.assertEqual(
                stdout.getvalue(), 'aSomelocalBear\n'
                'BSomeglobalBear\n'
                'SomeglobalBear\n'
                'SomelocalBear\n')

        self.logs.check(*(self.deprecation_messages * 5))

    def test_show_bears_capabilities(self):
        with retrieve_stdout() as stdout:
            show_language_bears_capabilities(
                {
                    'some_language':
                    ({'Formatting', 'Security'}, {'Formatting'})
                }, self.console_printer)
            self.assertIn(
                'coala can do the following for SOME_LANGUAGE\n'
                '    Can detect only: Formatting, Security\n'
                '    Can fix        : Formatting\n', stdout.getvalue())
            show_language_bears_capabilities({'some_language': (set(), set())},
                                             self.console_printer)
            self.assertIn('coala does not support some_language',
                          stdout.getvalue())
            show_language_bears_capabilities({}, self.console_printer)
            self.assertIn('There is no bear available for this language',
                          stdout.getvalue())
            show_language_bears_capabilities(
                {'some_language': ({'Formatting', 'Security'}, set())},
                self.console_printer)
            self.assertIn(
                'coala can do the following for SOME_LANGUAGE\n'
                '    Can detect only: Formatting, Security\n',
                stdout.getvalue())
コード例 #47
0
class TestStandardLibraryTarget(TestCase):
    def setUp(self):
        self.capture = LogCapture(attributes=('name', 'levelname',
                                              'getMessage', 'shoehorn_event'))
        self.addCleanup(self.capture.uninstall)

    def test_minimal(self):
        logger.info(event='test')
        self.capture.check(
            ('root', 'INFO', '', Event(event='test', level='info')))

    def test_named_logger(self):
        logger = get_logger('foo')
        logger.info(event='test')
        self.capture.check(
            ('foo', 'INFO', '', Event(event='test', logger='foo',
                                      level='info')))

    def test_level(self):
        logger.warning(event='test')
        self.capture.check(
            ('root', 'WARNING', '', Event(event='test', level='warning')))

    def test_sub_args(self):
        logger.info('foo %s', 'bar')
        self.capture.check(('root', 'INFO', 'foo bar',
                            Event(message='foo %s',
                                  args=('bar', ),
                                  level='info')))

    def test_exc_info(self):
        bad = Exception('bad')
        try:
            raise bad
        except:
            logger.exception('foo')
        self.capture.check(('root', 'ERROR', 'foo',
                            Event(level='error', message='foo',
                                  exc_info=True)))
        compare(bad, actual=self.capture.records[-1].exc_info[1])

    def test_stack_info(self):
        if PY2:
            return
        logger.info('foo', stack_info=True)
        self.capture.check(('root', 'INFO', 'foo',
                            Event(message='foo', stack_info=True,
                                  level='info')))
        compare('Stack (most recent call last):',
                actual=self.capture.records[-1].stack_info.split('\n')[0])

    def test_default_logger(self):
        from shoehorn import logger
        logger.info('er hi')
        self.capture.check(
            ('root', 'INFO', 'er hi', Event(message='er hi', level='info')))
コード例 #48
0
class TestControlNodeSerial(unittest.TestCase):
    def setUp(self):
        self.popen_patcher = mock.patch(
            'gateway_code.utils.subprocess_timeout.Popen')
        popen_class = self.popen_patcher.start()
        self.popen = popen_class.return_value

        self.popen.terminate.side_effect = self._terminate
        self.popen.poll.return_value = None

        self.readline_ret_vals = Queue.Queue(0)
        self.popen.stderr.readline.side_effect = self.readline_ret_vals.get
        self.readline_ret_vals.put('cn_serial_ready\n')

        self.cn = cn_interface.ControlNodeSerial('tty')
        self.log_error = LogCapture('gateway_code', level=logging.WARNING)

    def tearDown(self):
        self.cn.stop()
        mock.patch.stopall()
        self.log_error.uninstall()

    def _terminate(self):
        self.readline_ret_vals.put('')

    def test_normal_start_stop(self):
        ret_start = self.cn.start()
        self.assertEquals(0, ret_start)
        self.assertTrue(self.popen.stderr.readline.called)

        self.cn.stop()
        self.assertTrue(self.popen.terminate.called)
        self.assertTrue(self.readline_ret_vals.empty())

    def test_start_error_in_cn_serial(self):

        # poll should return an error
        self.popen.poll.return_value = 2

        ret_start = self.cn.start()
        self.assertNotEquals(0, ret_start)
        self.log_error.check(
            ('gateway_code', 'ERROR',
             'Control node serial reader thread ended prematurely'))
        self.cn.stop()

    def test_stop_before_start(self):
        self.cn.stop()

    def test_stop_with_cn_interface_allready_stopped(self):

        # Simulate cn_interface stopped
        self.readline_ret_vals.put('')
        self.popen.stdin.write.side_effect = IOError()
        self.popen.terminate.side_effect = OSError()

        self.cn.start()

        # try sending command
        ret = self.cn.send_command(['test', 'cmd'])
        self.assertEquals(None, ret)
        self.log_error.check(('gateway_code', 'ERROR',
                              'control_node_serial process is terminated'))

        self.log_error.clear()
        self.cn.stop()
        self.log_error.check(('gateway_code', 'ERROR',
                              'Control node process already terminated'))

    def test_stop_terminate_failed(self):
        """Stop cn_interface but terminate does not stop it."""
        # terminate does not stop process
        self.popen.terminate.side_effect = None
        timeout_expired = cn_interface.subprocess_timeout.TimeoutExpired
        self.popen.wait.side_effect = timeout_expired('cn_serial_interface', 3)
        # kill does it
        self.popen.kill.side_effect = self._terminate

        self.cn.start()
        self.cn.stop()

        self.assertTrue(self.popen.kill.called)
        self.log_error.check(('gateway_code', 'WARNING',
                              'Control node serial not terminated, kill it'))

# Test command sending

    def test_send_command(self):
        self.popen.stdin.write.side_effect = \
            (lambda *x: self.readline_ret_vals.put('start ACK\n'))

        self.cn.start()
        ret = self.cn.send_command(['start', 'DC'])
        self.assertEquals(['start', 'ACK'], ret)
        self.cn.stop()

    def test_send_command_no_answer(self):
        self.cn.start()
        ret = self.cn.send_command(['start', 'DC'])
        self.assertIsNone(ret)
        self.cn.stop()

    def test_send_command_cn_interface_stoped(self):
        ret = self.cn.send_command(['lala'])
        self.assertIsNone(ret)

    def test_answer_and_answer_with_queue_full(self):
        # get two answers without sending command
        self.readline_ret_vals.put('set ACK\n')
        self.readline_ret_vals.put('start ACK\n')

        self.cn.start()
        self.cn.stop()

        self.log_error.check(
            ('gateway_code', 'ERROR',
             'Control node answer queue full: %r' % ['start', 'ACK']))

# _cn_interface_args

    def test__cn_interface_args(self):
        args = self.cn._cn_interface_args()
        self.assertIn(self.cn.tty, args)
        self.assertNotIn('-c', args)
        self.assertNotIn('-d', args)

        # OML config
        args = self.cn._cn_interface_args('<omlc></omlc>')
        self.assertIn('-c', args)
        self.assertNotIn('-d', args)
        self.cn._oml_cfg_file.close()

        # Debug mode
        self.cn.measures_debug = (lambda x: None)
        args = self.cn._cn_interface_args()
        self.assertNotIn('-c', args)
        self.assertIn('-d', args)


# _config_oml coverage tests

    def test_empty_config_oml(self):
        # No experiment description
        ret = self.cn._oml_config_file(None)
        self.assertIsNone(ret)

    @mock.patch(utils.READ_CONFIG, utils.read_config_mock('m3'))
    def test_config_oml(self):
        oml_xml_cfg = '''<omlc id='{node_id}' exp_id='{exp_id}'>\n</omlc>'''
        self.cn.start(oml_xml_cfg)
        self.assertIsNotNone(self.cn._oml_cfg_file)

        self.cn.stop()

    def test_oml_xml_config(self):
        exp_files = {
            'consumption': '/tmp/consumption',
            'radio': '/tmp/radio',
            'event': '/tmp/event',
            'sniffer': '/tmp/sniffer',
            'log': '/tmp/log',
        }

        oml_xml_cfg = self.cn.oml_xml_config('m3-1', '1234', exp_files)
        self.assertIsNotNone(oml_xml_cfg)
        self.assertTrue(oml_xml_cfg.startswith('<omlc'))

        # No output if none or empty
        oml_xml_cfg = self.cn.oml_xml_config('m3-1', '1234', None)
        self.assertIsNone(oml_xml_cfg)
        oml_xml_cfg = self.cn.oml_xml_config('m3-1', '1234', {})
        self.assertIsNone(oml_xml_cfg)
コード例 #49
0
class TestBackendParsing(unittest.TestCase):
    
    def setUp(self):
        self.l = LogCapture()
        
    def tearDown(self):
        self.l.uninstall()
    
    def test_that_parse_returns_a_backend_dictionary_if_xml_contains_config_element_including_backends_list(self):
        root = ET.Element('config')
        ET.SubElement(root, 'backends')
        op = BackendParser()
        
        op.parse(root)
        result = op.backends
        
        assert_that(result, is_not(None))
        
    def test_that_config_includes_a_backends_list_if_config_contains_backends_definition(self):
        root = ET.Element('config')
        backends = ET.SubElement(root, 'backends')
        name = 'db'
        plugin = 'mysql'
        ET.SubElement(backends, 'backend', {'name':name, 'plugin':plugin})
        op = BackendParser()
        _dump_xml_as_file(root, 'backend.xml')
        op.parse(root)
        result = op.backends
        
        assert_that(result, is_not(None))
        assert_that(len(result), is_not(0))
        assert_that(result, has_key(name))
        assert_that(result[name].plugin, is_(plugin))
        
    def test_that_config_backend_is_ignored_if_plugin_is_empty(self):
        root = ET.Element('config')
        backends = ET.SubElement(root, 'backends')
        ET.SubElement(backends, 'backend', {'name':'db', 'plugin':''})
        op = BackendParser()
        
        op.parse(root)
        result = op.backends
        
        self.l.check(('root', 'WARNING', "Ignoring invalid backend definition, name = 'db', plugin = ''"))
        assert_that(result, is_not(has_key('db')))
        
    def test_that_config_backend_is_ignored_if_name_is_not_specified(self):
        root = ET.Element('config')
        backends = ET.SubElement(root, 'backends')
        ET.SubElement(backends, 'backend', {'plugin':'mysql'})
        op = BackendParser()
        
        op.parse(root)
        result = op.backends
        
        self.l.check(('root', 'WARNING', "Ignoring invalid backend definition, name = 'None', plugin = 'mysql'"))
        assert_that(len(result), is_(0))
        
    def test_that_backends_are_ignored_if_not_included_in_a_config_element(self):
        root = ET.Element('random_tag')
        ET.SubElement(root, 'backends')
        op = BackendParser()
        
        result = op.parse(root)
        
        assert_that(result, is_(None))
        
    def test_that_dictionary_of_parameters_is_created_if_parameters_specified(self):
        (root, backend) = _create_valid_backend()
        key = 'ip'
        value = '1.2.3.4'
        params = ET.SubElement(backend, 'params')
        param = ET.SubElement(params, key)
        param.text = value   
        op = BackendParser()
        
        op.parse(root)
        result = op.backends
        
        assert_that(result[backend.get('name')].params, has_entry(key, value))
コード例 #50
0
class TestStartExtension(TestCase):
    """Test the start extension.
    """

    def setUp(self):
        self.buildout_config = {
            'buildout': {'versions': 'versions'},
            'versions': {'A-Package': '1.0'},
            }
        self.i = Installer(versions=self.buildout_config['versions'])
        self.logging = LogCapture('zc.buildout.easy_install')
        # Run the extension, which includes installing our patches.
        start(self.buildout_config)
        # Some other extension, like mr.developer, may run after us
        # and call 'default_versions' after changing something to the
        # buildout config versions.  We should be fine with that.
        self.buildout_config['versions']['extra-lower'] = '4.2'
        self.buildout_config['versions']['ExtraUpper'] = '4.2'
        default_versions(self.buildout_config['versions'])

    def tearDown(self):
        self.logging.uninstall()

    def _check(self, requirement, expected):
        parsed_req = tuple(parse_requirements(requirement))[0]
        result = self.i._constrain(parsed_req)
        self.failUnless(isinstance(result, Requirement))
        compare(expected, str(result))

    def test_normal(self):
        self._check('A-Package', 'A-Package==1.0')
        self.logging.check()

    def test_lowercase(self):
        self._check('a_package', 'a-package==1.0')
        self.logging.check()

    def test_uppercase(self):
        self._check('A_PACKAGE', 'A-PACKAGE==1.0')
        self.logging.check()

    def test_sanity(self):
        # A non-pinned package should still be reported as such.
        self._check('B_Package', 'B-Package')
        self.logging.check()

    def test_extra(self):
        # A pin added after our extension has run is picked up as well.
        self._check('extra-lower', 'extra-lower==4.2')
        self.logging.check()

    def test_extra_lower(self):
        # A pin added after our extension has run is not lowercased
        # though.
        self._check('ExtraUpper', 'ExtraUpper')
        self.logging.check()
コード例 #51
0
    def test_update_node_information(self, mock_shell):
        """
        Test that the correct work of this function
        """
        l = LogCapture()  # we capture the logger
        command = "pbsnodes"
        params = ["-x"]

        # We store some data in the db for the test.
        # We add a testbed to the db
        testbed = Testbed("name1", True, Testbed.torque_category,
                          Testbed.protocol_ssh, "user@server", ['torque'])

        # We add some nodes to Testbed_1
        node_1 = Node()
        node_1.name = "node-1.novalocal"
        node_1.information_retrieved = True
        node_2 = Node()
        node_2.name = "node-2.novalocal"
        node_2.information_retrieved = True
        testbed.nodes = [node_1, node_2]
        node_1.disabled = True

        db.session.add(testbed)
        db.session.commit()

        # We mock the command call
        mock_shell.return_value = self.command_pbsnodes_output

        testbeds.facade.update_testbed_node_information(testbed)

        # We verify the results
        node_1 = db.session.query(Node).filter_by(
            name='node-1.novalocal').first()
        node_2 = db.session.query(Node).filter_by(
            name='node-2.novalocal').first()
        self.assertEqual('free', node_1.state)
        self.assertEqual(1, len(node_1.memories))
        self.assertEqual(Memory.KILOBYTE, node_1.memories[0].units)
        self.assertEqual(131583196, node_1.memories[0].size)
        self.assertEqual(1, len(node_1.gpus))

        self.assertEqual('free', node_2.state)
        self.assertEqual(1, len(node_2.memories))
        self.assertEqual(Memory.KILOBYTE, node_2.memories[0].units)
        self.assertEqual(131583197, node_2.memories[0].size)
        self.assertEqual(0, len(node_2.gpus))

        mock_shell.assert_called_with(command=command,
                                      server="user@server",
                                      params=params)
        self.assertEqual(1, mock_shell.call_count)

        # Checking that we are logging the correct messages
        l.check(
            ('root', 'INFO',
             'Updating information for node: node-1.novalocal if necessary'),
            ('root', 'INFO',
             'Updating memory information for node: node-1.novalocal'),
            ('root', 'INFO',
             'Updating gpu information for node: node-1.novalocal'),
            ('root', 'INFO',
             'Updating information for node: node-2.novalocal if necessary'),
            ('root', 'INFO',
             'Updating memory information for node: node-2.novalocal'),
        )
        l.uninstall()  # We uninstall the capture of the logger
コード例 #52
0
ファイル: tests.py プロジェクト: daxr/django-hookbox
class DjangoHookboxTest(TestCase):

    def _cb_all(self, op, user, channel = '-', payload = None):
        if channel in self.all_calls:
            self.all_calls[channel] += 1
        else:
            self.all_calls[channel] = 1
        return None

    def _cb_create(self, op, user, channel = None):
        if channel in self.create_calls:
            self.create_calls[channel] += 1
        else:
            self.create_calls[channel] = 1

        if channel == '/a/':
            return {
                'history_size': 2,
                'reflective':   False,
                'presenceful':  False,
                'moderated':    True,
            }
        elif channel == '/b/':
            return 'denied'
        elif channel == '/c/':
            return [False, {'msg': 'also denied'}]
        else:
            return None

    def setUp(self):
        self.all_calls = {}
        self.create_calls = {}

        # HACK: don't allow other apps to mess with us or vice versa...
        self.old_cbs = djhookbox.views._callbacks
        djhookbox.views._callbacks = []
        djhookbox.whcallback(self._cb_all)
        djhookbox.whcallback('create')(self._cb_create)

        User.objects.create_user('a', '*****@*****.**', 'a').save()

        self.logcap = LogCapture()

    def tearDown(self):
        djhookbox.views._callbacks = self.old_cbs
        self.logcap.uninstall()

    @server
    def test_create(self):
        self.assertRaises(djhookbox.HookboxError,
            djhookbox.publish, '/a/', json.dumps({'foo': 'bar'}))

        djhookbox.create('/a/')
        djhookbox.publish('/a/', json.dumps({'foo': 'bar'}))

        # TODO: Test send_hook works
        # TODO: Confirm it actually did something

    @server
    def test_web_api_token(self):
        secret = djhookbox.apitoken
        try:
            djhookbox.apitoken += '...not!'
            self.assertRaises(djhookbox.HookboxError,
                              djhookbox.publish, '/a/', json.dumps({'foo': 'bar'}))
            self.assertCreateCalls({})
        finally:
            djhookbox.apitoken = secret

    def test_webhook_secret(self):
        self.client.login(username = '******', password = '******')
        response = self.client.post(connect_url, {
            'channel_name': 'a',
            'secret':       djhookbox.views.secret,
        })
        self.assertSuccess(response)

        response = self.client.post(connect_url, {
            'channel_name': 'a',
        })
        data = self.decode(response)
        self.assertFalse(data[0], 'webhook secret verification should have failed (forgotton to set settings.HOOKBOX_WEBHOOK_SECRET?)')

        response = self.client.post(connect_url, {
            'channel_name': 'a',
            'secret':       djhookbox.views.secret + '...not!',
        })
        data = self.decode(response)
        self.assertFalse(data[0], 'webhook secret verification should have failed')

    def test_signals(self):
        class Listener(object):
            def __call__(self, *args, **kwargs):
                self.signal = kwargs.get('signal')
                self.sender = kwargs.get('sender').username
                self.kwargs = kwargs

        def doTest(which, params = dict(), **checks):
            listener = Listener()
            djhookbox.views.signals[which].connect(listener)

            self.client.login(username = '******', password = '******')
            params['secret'] = djhookbox.views.secret
            response = self.client.post(reverse('hookbox_%s' % which), params)

            self.assertSuccess(response)
            self.assertEquals(listener.sender, 'a')
            for (key, value) in checks.iteritems():
                self.assertEquals(listener.kwargs.get(key), value)

            self.client.logout()
            djhookbox.views.signals[which].disconnect(listener)

        doTest('connect')
        doTest('disconnect')
        doTest('subscribe', {'channel_name': 'b'}, channel = 'b')
        doTest('unsubscribe', {'channel_name': 'b'}, channel = 'b')

    def test_all_cbs(self):
        self.client.login(username = '******', password = '******')
        params = {
            'secret': djhookbox.views.secret,
            'channel_name': 'a',
        }

        response = self.client.post(connect_url, params)
        self.assertSuccess(response)
        self.assertAllCalls({'-': 1})

        response = self.client.post(reverse('hookbox_subscribe'), params)
        self.assertSuccess(response)
        self.assertAllCalls({'-': 1, 'a': 1})

        response = self.client.post(reverse('hookbox_publish'), {
            'secret': djhookbox.views.secret,
            'channel_name': 'a',
            'payload': json.dumps(["Hello world"]),
        })
        self.assertSuccess(response)
        self.assertAllCalls({'-': 1, 'a': 2})

        response = self.client.post(reverse('hookbox_destroy_channel'), params)
        self.assertSuccess(response)
        self.assertAllCalls({'-': 1, 'a': 3})

        response = self.client.post(reverse('hookbox_disconnect'), params)
        self.assertSuccess(response)
        self.assertAllCalls({'-': 2, 'a': 3})

    def test_warn_multiple_results(self):

        @djhookbox.whcallback
        def _cb_1(op, user, channel = '-'):
            return [True, {}]

        @djhookbox.whcallback
        def _cb_2(op, user, channel = '-'):
            return [True, {}]

        params = {'secret': djhookbox.views.secret}

        logging.getLogger('djhookbox').setLevel(logging.WARNING)

        response = self.client.post(connect_url, params)
        self.assertSuccess(response)
        self.assertAllCalls({'-': 1})

        response = self.client.post(reverse('hookbox_disconnect'), params)
        self.assertSuccess(response)
        self.assertAllCalls({'-': 2})

        self.logcap.check(
            ('djhookbox', 'WARNING', 'multiple results returned from connect callback'),
            ('djhookbox', 'WARNING', 'multiple results returned from disconnect callback'),
        )

    def test_explicit_deny(self):
        response = self.client.post(reverse('hookbox_create_channel'), {
            'secret': djhookbox.views.secret,
            'channel_name': '/b/',
        })

        data = self.decode(response)
        self.assertEquals(data[0], False, 'unexpected success')
        self.assertEquals(data[1], {'msg': 'denied'})
        self.assertAllCalls({'/b/': 1})

        response = self.client.post(reverse('hookbox_create_channel'), {
            'secret': djhookbox.views.secret,
            'channel_name': '/c/',
        })

        data = self.decode(response)
        self.assertEquals(data[0], False, 'unexpected success')
        self.assertEquals(data[1], {'msg': 'also denied'})
        self.assertAllCalls({'/b/': 1, '/c/': 1})

    def test_callback_error(self):

        @djhookbox.whcallback
        def _cb_1(op, user, channel = '-'):
            raise Exception('something bad')

        response = self.client.post(reverse('hookbox_create_channel'), {
            'secret': djhookbox.views.secret,
            'channel_name': '/a/',
        })

        data = self.decode(response)
        self.assertEquals(data[0], False, 'unexpected success')
        self.assertEquals(data[1], {'msg': 'something bad'})
        self.assertAllCalls({'/a/': 1})

    def decode(self, response):
        self.assertEquals(response.status_code, 200)
        self.assert_(('Content-Type', 'application/json') in response.items())

        result = json.loads(response.content)
        self.assert_(isinstance(result, list), 'unexpected result returned from server: %s' % str(result))
        self.assertEquals(len(result), 2)
        self.assert_(isinstance(result[0], bool), 'unexpected result returned from server: %s' % str(result))
        self.assert_(isinstance(result[1], dict), 'unexpected result returned from server: %s' % str(result))
        return result

    def assertSuccess(self, response):
        data = self.decode(response)
        
        if not data[0] and 'msg' in data[1]:
            self.fail(data[1]['msg'])
        else:
            self.assert_(data[0])

    def assertAllCalls(self, calls):
        self.assertEquals(self.all_calls, calls)

    def assertCreateCalls(self, calls):
        self.assertEquals(self.create_calls, calls)
コード例 #53
0
	def test_build_singularity_container(self, mock_shell, mock_scp):
		"""
		It test the correct work of the function
		create_singularity_image
		"""

		l = LogCapture()

		filename = compiler.build_singularity_container('*****@*****.**', '/test/test.def', 'image.img', '/tmp')

		#mock_shell.assert_called_with('sudo', '*****@*****.**', ['singularity', 'bootstrap', 'image.img', 'test.def'])
		mock_scp.assert_called_with(filename, '*****@*****.**', 'image.img', False)

		filename = filename[5:-4]

		try:
			val = UUID(filename, version=4)
		except ValueError:
			self.fail("Filname is not uuid4 complaint: " + filename)

		# In case not necessary to use sudo
		filename = compiler.build_singularity_container('*****@*****.**', '/test/test.def', 'image.img', '/tmp', become=False)

		#mock_shell.assert_called_with('singularity', '*****@*****.**', ['bootstrap', 'image.img', 'test.def'])
		mock_scp.assert_called_with(filename, '*****@*****.**', 'image.img', False)

		filename = filename[5:-4]

		try:
			val = UUID(filename, version=4)
		except ValueError:
			self.fail("Filname is not uuid4 complaint: " + filename)

		# In case of local compilation
		filename = compiler.build_singularity_container('', '/test/test.def', 'image.img', '/tmp', become=False)

		filename = filename[5:-4]

		try:
			val = UUID(filename, version=4)
		except ValueError:
			self.fail("Filname is not uuid4 complaint: " + filename)

		## WE VERIFY ALL THE CALLS:

		call_1 = call('sudo', '*****@*****.**', ['singularity', 'build', '-F', 'image.img', 'test.def'])
		call_2 = call('singularity', '*****@*****.**', ['build', '-F', 'image.img', 'test.def'])
		call_3 = call('singularity', '', ['build', '-F', 'image.img', '/test/test.def'])
		call_4 = call('mv', '', [ANY, ANY])
		calls = [ call_1, call_2, call_3, call_4]
		mock_shell.assert_has_calls(calls)

		# Checking that we are logging the correct messages
		l.check(
			('root', 'INFO', "Executing [[email protected]], 'sudo singulary build -F image.img test.def'"),
			('root', 'INFO', 'Downloading image from [email protected]'),
			('root', 'INFO', "Executing [[email protected]], 'singulary build -F image.img test.def'"),
			('root', 'INFO', 'Downloading image from [email protected]'),
			('root', 'INFO', "Executing [], 'singulary build -F image.img /test/test.def'"),
			('root', 'INFO', 'Moving image to final destination')
			)
		l.uninstall()
コード例 #54
0
class TestVpcBotoInteractions(unittest.TestCase):
    """
    We use the moto mock framework for boto in order to test our interactions
    with boto.

    """
    def setUp(self):
        self.lc = LogCapture()
        self.lc.addFilter(test_common.MyLogCaptureFilter())
        self.addCleanup(self.cleanup)
        # Hosts are chosen randomly from a prefix group. Therefore, we need to
        # seed the random number generator with a specific value in order to
        # have reproducible tests.
        random.seed(123)

    def cleanup(self):
        self.lc.uninstall()

    @mock_ec2_deprecated
    def make_mock_vpc(self):
        """
        Use plain (but mocked) boto functions to create a small VPC with two
        subnets and two instances as a basis for our tests.

        (not quite sure why this doesn't run in setUp().

        """
        con = boto.vpc.connect_to_region("ap-southeast-2")

        # Note that moto doesn't seem to honor the subnet and VPC address
        # ranges, it seems all instances always get something random from a
        # 10/8 range.
        self.new_vpc = con.create_vpc('10.0.0.0/16')
        self.new_subnet_a = con.create_subnet(self.new_vpc.id, '10.1.0.0/16')
        self.new_subnet_b = con.create_subnet(self.new_vpc.id, '10.2.0.0/16')

        res1 = con.run_instances('ami-1234abcd',
                                 subnet_id=self.new_subnet_a.id)
        res2 = con.run_instances('ami-1234abcd',
                                 subnet_id=self.new_subnet_b.id)
        self.i1 = res1.instances[0]
        self.i2 = res2.instances[0]
        self.i1ip = self.i1.private_ip_address
        self.i2ip = self.i2.private_ip_address

    @mock_ec2_deprecated
    def test_connect(self):
        self.make_mock_vpc()

        # With a test VPC created, we now test our own functions

        # In the mocked test the meta data won't contain the info we need (vpc
        # and region name), because the emulated EC2 instance isn't in any
        # region or vpc.
        meta = vpc.get_ec2_meta_data()
        self.assertTrue(meta == {})

        self.assertRaises(VpcRouteSetError, vpc.connect_to_region, "blah")

        con = vpc.connect_to_region("ap-southeast-2")

        # Error when specifying non-existent VPC
        self.assertRaises(VpcRouteSetError, vpc.get_vpc_overview, con,
                          "non-existent-vpc", "ap-southeast-2")

        # Get the default: First VPC if no VPC is specified
        d = vpc.get_vpc_overview(con, None, "ap-southeast-2")
        self.assertEqual(d['vpc'].id, "vpc-be745e76")

        # Get specified VPC
        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        self.assertEqual(d['vpc'].id, "vpc-be745e76")

        self.assertEqual(
            sorted([
                'subnets', 'route_tables', 'instance_by_id', 'instances',
                'subnet_rt_lookup', 'zones', 'vpc'
            ]), sorted(d.keys()))

        self.assertEqual(self.new_vpc.id, d['vpc'].id)
        self.assertTrue(self.new_subnet_a.id in [s.id for s in d['subnets']])
        self.assertTrue(self.new_subnet_b.id in [s.id for s in d['subnets']])
        self.assertTrue(len(d['zones']) == 3)
        self.assertTrue(len(d['route_tables']) == 1)
        self.assertTrue(len(d['instance_by_id'].keys()) == 2)
        self.assertTrue(d['instance_by_id'][self.i1.id].id == self.i1.id)
        self.assertTrue(d['instance_by_id'][self.i2.id].id == self.i2.id)

        self.assertRaises(VpcRouteSetError, vpc.find_instance_and_eni_by_ip, d,
                          "9.9.9.9")  # Non existent IP
        self.assertTrue(
            vpc.find_instance_and_eni_by_ip(d, self.i1ip)[0].id == self.i1.id)
        self.assertTrue(
            vpc.find_instance_and_eni_by_ip(d, self.i2ip)[0].id == self.i2.id)

    def _prepare_mock_env(self):
        self.make_mock_vpc()

        con = vpc.connect_to_region("ap-southeast-2")

        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")

        i1, eni1 = vpc.find_instance_and_eni_by_ip(d, self.i1ip)
        i2, eni2 = vpc.find_instance_and_eni_by_ip(d, self.i2ip)

        rt_id = d['route_tables'][0].id

        return con, d, i1, eni1, i2, eni2, rt_id

    @mock_ec2_deprecated
    def test_process_route_spec_config(self):
        con, d, i1, eni1, i2, eni2, rt_id = self._prepare_mock_env()

        route_spec = {u"10.1.0.0/16": [self.i1ip, self.i2ip]}

        # Process a simple route spec, a route should have been added
        self.lc.clear()
        vpc.process_route_spec_config(con, d, route_spec, [], [])
        # One of the hosts is randomly chosen. We seeded the random number
        # generator at in this module, so we know that it will choose the
        # second host in this case.
        self.lc.check(
            ('root', 'DEBUG', 'Route spec processing. No failed IPs.'),
            ('root', 'INFO', "--- adding route in RT '%s' "
             "10.1.0.0/16 -> %s (%s, %s)" %
             (rt_id, self.i1ip, i1.id, eni1.id)))

        # One of the two IPs questionable, switch over
        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        self.lc.clear()
        vpc.process_route_spec_config(con, d, route_spec, [], [self.i1ip])
        self.lc.check(
            ('root', 'DEBUG', 'Route spec processing. No failed IPs.'),
            ('root', 'INFO',
             "--- eni in route in RT 'rtb-84dc7f2c' can't be found: "
             "10.1.0.0/16 -> (none) (instance '%s')" % i1.id),
            ('root', 'INFO',
             "--- updating existing route in RT '%s' 10.1.0.0/16 -> "
             "%s (%s, %s) (old IP: None, reason: old IP failed/questionable "
             "or not eligible anymore)" % (rt_id, self.i2ip, i2.id, eni2.id)))

        # Now switch back
        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        self.lc.clear()
        vpc.process_route_spec_config(con, d, route_spec, [], [self.i2ip])
        self.lc.check(
            ('root', 'DEBUG', 'Route spec processing. No failed IPs.'),
            ('root', 'INFO',
             "--- eni in route in RT 'rtb-84dc7f2c' can't be found: "
             "10.1.0.0/16 -> (none) (instance '%s')" % i2.id),
            ('root', 'INFO',
             "--- updating existing route in RT '%s' 10.1.0.0/16 -> "
             "%s (%s, %s) (old IP: None, reason: old IP failed/questionable "
             "or not eligible anymore)" % (rt_id, self.i1ip, i1.id, eni1.id)))

        # One of the two IPs failed, switch over
        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        self.lc.clear()
        vpc.process_route_spec_config(con, d, route_spec, [self.i1ip], [])
        self.lc.check(
            ('root', 'DEBUG',
             'Route spec processing. Failed IPs: %s' % self.i1ip),
            ('root', 'INFO',
             "--- eni in route in RT 'rtb-84dc7f2c' can't be found: "
             "10.1.0.0/16 -> (none) (instance '%s')" % i1.id),
            ('root', 'INFO',
             "--- updating existing route in RT '%s' 10.1.0.0/16 -> "
             "%s (%s, %s) (old IP: None, reason: old IP failed/questionable "
             "or not eligible anymore)" % (rt_id, self.i2ip, i2.id, eni2.id)))

        # Now all IPs for a route have failed
        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        self.lc.clear()
        vpc.process_route_spec_config(con, d, route_spec,
                                      [self.i1ip, self.i2ip], [])
        self.lc.check(
            ('root', 'DEBUG', 'Route spec processing. Failed IPs: %s,%s' %
             (self.i1ip, self.i2ip)),
            ('root', 'INFO',
             "--- eni in route in RT 'rtb-84dc7f2c' can't be found: "
             "10.1.0.0/16 -> (none) (instance '%s')" % i2.id),
            ('root', 'WARNING',
             '--- cannot find available target for route update 10.1.0.0/16! '
             'Nothing I can do...'))

        # Add new route, remove old one
        route_spec = {u"10.2.0.0/16": [self.i1ip]}

        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        self.lc.clear()
        vpc.process_route_spec_config(con, d, route_spec, [], [])
        self.lc.check(
            ('root', 'DEBUG', 'Route spec processing. No failed IPs.'),
            ('root', 'INFO',
             "--- eni in route in RT 'rtb-84dc7f2c' can't be found: "
             "10.1.0.0/16 -> (none) (instance '%s')" % i2.id),
            ('root', 'INFO', "--- route not in spec, deleting in RT '%s': "
             "10.1.0.0/16 -> ... ((unknown), (unknown))" % rt_id),
            ('root', 'INFO', "--- adding route in RT '%s' "
             "10.2.0.0/16 -> %s (%s, %s)" %
             (rt_id, self.i1ip, i1.id, eni1.id)))

        # Protect old route (ignore_routes), add new route, watch the old route
        # NOT disappear.
        CURRENT_STATE.ignore_routes.append("10.2.0.0/16")  # protected route
        route_spec = {u"10.3.0.0/16": [self.i1ip]}

        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        self.lc.clear()
        vpc.process_route_spec_config(con, d, route_spec, [], [])
        # See in the logs that 10.2.0.0/16 wasn't deleted, even though it's not
        # in the route spec anymore.
        self.lc.check(
            ('root', 'DEBUG', 'Route spec processing. No failed IPs.'),
            ('root', 'INFO', "--- adding route in RT '%s' "
             "10.3.0.0/16 -> %s (%s, %s)" %
             (rt_id, self.i1ip, i1.id, eni1.id)))

    @mock_ec2_deprecated
    def test_add_new_route(self):
        con, d, i1, eni1, i2, eni2, rt_id = self._prepare_mock_env()

        self.lc.clear()
        vpc._add_new_route("10.9.0.0/16", self.i1ip, d, con, rt_id)
        self.lc.check(('root', 'INFO', "--- adding route in RT '%s' "
                       "10.9.0.0/16 -> %s (%s, %s)" %
                       (rt_id, self.i1ip, i1.id, eni1.id)))

        self.lc.clear()
        vpc._add_new_route("10.9.0.0/16", "99.99.99.99", d, con, rt_id)
        self.lc.check(
            ('root', 'ERROR', "*** failed to add route in RT '%s' "
             "10.9.0.0/16 -> 99.99.99.99 (Could not find instance/eni "
             "for '99.99.99.99' in VPC '%s'.)" % (rt_id, self.new_vpc.id)))

    @mock_ec2_deprecated
    def test_update_route(self):
        con, d, i1, eni1, i2, eni2, rt_id = self._prepare_mock_env()

        vpc._add_new_route("10.9.0.0/16", self.i1ip, d, con, rt_id)

        self.lc.clear()
        vpc._update_route("10.9.0.0/16", self.i2ip, self.i1ip, d, con, rt_id,
                          "foobar")
        self.lc.check(
            ('root', 'INFO', "--- updating existing route in RT '%s' "
             "10.9.0.0/16 -> %s (%s, %s) "
             "(old IP: %s, reason: foobar)" %
             (rt_id, self.i2ip, i2.id, eni2.id, self.i1ip)))

        self.lc.clear()
        vpc._update_route("10.9.0.0/16", "9.9.9.9", self.i2ip, d, con, rt_id,
                          "foobar")
        self.lc.check(
            ('root', 'ERROR', "*** failed to update route in RT '%s' "
             "10.9.0.0/16 -> %s (Could not find instance/eni "
             "for '9.9.9.9' in VPC '%s'.)" %
             (rt_id, self.i2ip, self.new_vpc.id)))

        # Trying to update a non-existent route
        self.lc.clear()
        vpc._update_route("10.9.9.9/16", self.i1ip, self.i2ip, d, con, rt_id,
                          "foobar")
        self.lc.check(
            ('root', 'INFO',
             "--- updating existing route in RT '%s' 10.9.9.9/16 -> %s "
             "(%s, %s) (old IP: %s, reason: foobar)" %
             (rt_id, self.i1ip, i1.id, eni1.id, self.i2ip)),
            ('root', 'ERROR',
             "*** failed to update route in RT '%s' 10.9.9.9/16 -> %s "
             "(replace_route failed: u'%s~10.9.9.9/16')" %
             (rt_id, self.i2ip, rt_id)))

    @mock_ec2_deprecated
    def test_get_real_instance_if_mismatched(self):
        con, d, i1, eni1, i2, eni2, rt_id = self._prepare_mock_env()

        self.assertFalse(vpc._get_real_instance_if_mismatch(d, None, i1, eni1))
        ret = vpc._get_real_instance_if_mismatch(d, self.i1ip, i1, eni1)
        self.assertFalse(ret)

        for inst, eni in [(i2, eni2), (i1, eni2), (i2, eni1), (i1, None),
                          (None, eni1), (i2, None), (None, eni2),
                          (None, None)]:
            ret = vpc._get_real_instance_if_mismatch(d, self.i1ip, inst, eni)
            self.assertEqual(ret.id, i1.id)

    @mock_ec2_deprecated
    def test_get_host_for_route(self):
        con, d, i1, eni1, i2, eni2, rt_id = self._prepare_mock_env()

        vpc._add_new_route("10.9.0.0/16", self.i1ip, d, con, rt_id)

        rt = d['route_tables'][0]
        self.assertEqual(rt.id, rt_id)

        route = rt.routes[0]
        # Moto doesn't maintain intance or interface ID in the routes
        # correctly, so need to set this one manually
        route.instance_id = i1.id
        route.interface_id = eni1.id

        # Find correct host for route (the passed in cidr is only used for
        # logging)
        self.assertEqual((i1.id, self.i1ip, eni1.id),
                         vpc._get_host_for_route(d, route, rt, "cidr-log"))

        # Look for broken route without an instance id
        route.instance_id = None
        self.lc.clear()
        self.assertEqual(('(unknown)', None, '(unknown)'),
                         vpc._get_host_for_route(d, route, rt, "cidr-log"))
        self.lc.check(
            ('root', 'INFO', "--- obsoleted route in RT '%s' cidr-log -> "
             "... (doesn't point to instance anymore)" % rt_id))

        # Look for broken route with instance id for non-existent instance
        route.instance_id = "blah"
        self.lc.clear()
        self.assertEqual(('(unknown)', None, '(unknown)'),
                         vpc._get_host_for_route(d, route, rt, "cidr-log"))
        self.lc.check(('root', 'INFO',
                       "--- instance in route in RT '%s' can't be found: "
                       "cidr-log -> ... (instance 'blah')" % rt_id))

    @mock_ec2_deprecated
    def test_update_existing_routes(self):
        con, d, i1, eni1, i2, eni2, rt_id = self._prepare_mock_env()

        vpc._add_new_route("10.0.0.0/16", self.i1ip, d, con, rt_id)

        route_spec = {u"10.0.0.0/16": [self.i1ip]}
        routes_in_rts = {}

        # Test that a protected route doesn't get updated
        self.lc.clear()
        CURRENT_STATE.ignore_routes = ["10.0.0.0/8"]
        vpc._update_existing_routes(route_spec, [], [], d, con, routes_in_rts)
        self.assertTrue(rt_id in CURRENT_STATE.vpc_state['route_tables'])
        self.assertTrue(
            "10.0.0.0/16" in CURRENT_STATE.vpc_state['route_tables'][rt_id])
        self.assertTrue("Ignored: Protected CIDR" in CURRENT_STATE.
                        vpc_state['route_tables'][rt_id]["10.0.0.0/16"])
        self.lc.check()

        # Now we un-protect the route and try again. Moto doesn't manage the
        # instance or interface ID in routes, so this will fail, because the
        # route doesn't look like it's pointing to an instance
        CURRENT_STATE.ignore_routes = []
        vpc._update_existing_routes(route_spec, [], [], d, con, routes_in_rts)
        self.assertTrue("Ignored: Not a route to an instance" in CURRENT_STATE.
                        vpc_state['route_tables'][rt_id]["10.0.0.0/16"])
        self.lc.check()

        # Now we manually set the instance and eni id in the route, so that the
        # test can proceed.
        rt = d['route_tables'][0]
        self.assertEqual(rt.id, rt_id)

        route = rt.routes[0]
        # Moto doesn't maintain intance or interface ID in the routes
        # correctly, so need to set this one manually. This time the route spec
        # won't contain eligible hosts.
        route.instance_id = i1.id
        route.interface_id = eni1.id
        self.lc.clear()
        route_spec = {u"10.0.0.0/16": []}
        vpc._update_existing_routes(route_spec, [], [], d, con, routes_in_rts)
        self.lc.check(
            ('root', 'INFO',
             "--- route not in spec, deleting in RT '%s': 10.0.0.0/16 -> "
             "... (%s, %s)" % (rt_id, i1.id, eni1.id)))

        # Get a refresh, since deleting via Boto interface doesn't update the
        # cached vpc-info
        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        # There shouldn't be any routes left now
        rt = d['route_tables'][0]
        self.assertFalse(rt.routes)

        # Now try again, but with proper route spec. First we need to create
        # the route again and manually...
        vpc._add_new_route("10.0.0.0/16", self.i1ip, d, con, rt_id)
        # ... and update our cached vpc info
        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        rt = d['route_tables'][0]
        route = rt.routes[0]
        route.instance_id = i1.id
        route.interface_id = eni1.id

        route_spec = {u"10.0.0.0/16": [self.i2ip]}
        # Only IP for spec is in failed IPs, can't do anything
        self.lc.clear()
        vpc._update_existing_routes(route_spec, [self.i2ip], [], d, con,
                                    routes_in_rts)
        self.lc.check(('root', 'WARNING',
                       '--- cannot find available target for route update '
                       '10.0.0.0/16! Nothing I can do...'))

        # Now with available IPs
        self.lc.clear()
        vpc._update_existing_routes(route_spec, [], [], d, con, routes_in_rts)
        self.lc.check(
            ('root', 'INFO',
             "--- updating existing route in RT '%s' 10.0.0.0/16 -> "
             "%s (%s, %s) (old IP: %s, reason: old IP failed/questionable "
             "or not eligible anymore)" %
             (rt_id, self.i2ip, i2.id, eni2.id, self.i1ip)))

        # Now with same route spec again
        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        rt = d['route_tables'][0]
        route = rt.routes[0]
        route.instance_id = i2.id
        route.interface_id = eni2.id
        self.lc.clear()
        routes_in_rts = {}
        vpc._update_existing_routes(route_spec, [], [], d, con, routes_in_rts)
        self.lc.check(('root', 'INFO',
                       "--- route exists already in RT '%s': 10.0.0.0/16 -> "
                       "%s (%s, %s)" % (rt_id, self.i2ip, i2.id, eni2.id)))

    @mock_ec2_deprecated
    def test_add_missing_routes(self):
        con, d, i1, eni1, i2, eni2, rt_id = self._prepare_mock_env()

        route_spec = {u"10.0.0.0/16": [self.i1ip]}
        routes_in_rts = {}
        self.lc.clear()
        vpc._update_existing_routes(route_spec, [], [], d, con, routes_in_rts)
        self.lc.check()

        self.lc.clear()
        vpc._add_missing_routes(route_spec, [], [], {}, d, con, routes_in_rts)
        self.lc.check(
            ('root', 'INFO', "--- adding route in RT '%s' 10.0.0.0/16 -> "
             "%s (%s, %s)" % (rt_id, self.i1ip, i1.id, eni1.id)))

        # The route exists already (passed in routes_in_rts), so no new route
        # should be created here.
        self.lc.clear()
        vpc._add_missing_routes(route_spec, [], [], {"10.0.0.0/16": self.i1ip},
                                d, con, {rt_id: ["10.0.0.0/16"]})
        self.lc.check()

        # Force a route creation by passing nothing for routes_in_rts and
        # passing in a 'previous' choice for the router
        self.lc.clear()
        vpc._add_missing_routes(route_spec, [], [], {"10.0.0.0/16": self.i1ip},
                                d, con, {rt_id: []})
        self.lc.check(
            ('root', 'INFO', "--- adding route in RT '%s' 10.0.0.0/16 -> "
             "%s (%s, %s)" % (rt_id, self.i1ip, i1.id, eni1.id)))

        # Now try the same with the only possible IP in failed IPs.
        self.lc.clear()
        vpc._add_missing_routes(route_spec, [self.i1ip], [], {}, d, con,
                                {rt_id: []})
        self.lc.check(('root', 'WARNING',
                       '--- cannot find available target for route addition '
                       '10.0.0.0/16! Nothing I can do...'))

    @mock_ec2_deprecated
    def test_multi_address(self):
        # Testing that we can find interfaces, which have the specified IP on a
        # second, private IP address
        con, d, i1, eni1, i2, eni2, rt_id = self._prepare_mock_env()

        priv = eni1.private_ip_addresses[0]

        priv = boto.ec2.networkinterface.PrivateIPAddress(
            private_ip_address="10.9.9.9", primary=False)
        eni1.private_ip_addresses.append(priv)

        self.lc.clear()
        route_spec = {"10.0.0.0/16": ["10.9.9.9"]}
        self.lc.clear()
        vpc._add_missing_routes(route_spec, [], [], {}, d, con, {rt_id: []})
        self.lc.check(('root', 'INFO',
                       "--- adding route in RT '%s' 10.0.0.0/16 -> 10.9.9.9 "
                       "(%s, %s)" % (rt_id, i1.id, eni1.id)))

    @mock_ec2_deprecated
    def test_handle_spec(self):
        self.make_mock_vpc()

        # Need to take a peek inside the VPC so we can properly evaluate the
        # output later on
        con = vpc.connect_to_region("ap-southeast-2")
        d = vpc.get_vpc_overview(con, self.new_vpc.id, "ap-southeast-2")
        i, eni = vpc.find_instance_and_eni_by_ip(d, self.i1ip)

        rt_id = d['route_tables'][0].id

        route_spec = {u"10.2.0.0/16": [self.i1ip]}

        # Test handle_spec
        vid = self.new_vpc.id
        self.lc.clear()
        vpc.handle_spec("ap-southeast-2", vid, route_spec, [], [])
        self.lc.check(
            ('root', 'DEBUG', 'Handle route spec'),
            ('root', 'DEBUG', "Connecting to AWS region 'ap-southeast-2'"),
            ('root', 'DEBUG', "Retrieving information for VPC '%s'" % vid),
            ('root', 'DEBUG', 'Route spec processing. No failed IPs.'),
            ('root', 'INFO',
             "--- adding route in RT '%s' 10.2.0.0/16 -> %s (%s, %s)" %
             (rt_id, self.i1ip, self.i1.id, eni.id)))

        # mock the get_instance_private_ip_from_route() function in vpc. Reason
        # being: The boto mocking library (moto) doesn't handle ENIs in routes
        # correctly. Therefore, a match against the information we get from the
        # routes will never work. So, we provide a wrapper, which fills the
        # instance's ENI information into the route. This means that this
        # function now will always match. It's good for testing the 'match'
        # part of the code.
        old_func = vpc.get_instance_private_ip_from_route

        def my_get_instance_private_ip_from_route(instance, route):
            route.interface_id = instance.interfaces[0].id
            return old_func(instance, route)

        vpc.get_instance_private_ip_from_route = \
                                my_get_instance_private_ip_from_route
        self.lc.clear()
        vpc.handle_spec("ap-southeast-2", vid, route_spec, [], [])

        vpc.get_instance_private_ip_from_route = old_func

        self.lc.check(
            ('root', 'DEBUG', 'Handle route spec'),
            ('root', 'DEBUG', "Connecting to AWS region 'ap-southeast-2'"),
            ('root', 'DEBUG', "Retrieving information for VPC '%s'" % vid),
            ('root', 'DEBUG', 'Route spec processing. No failed IPs.'),
            ('root', 'INFO',
             "--- route exists already in RT '%s': 10.2.0.0/16 -> "
             "%s (%s, %s)" % (rt_id, self.i1ip, self.i1.id, eni.id)))
コード例 #55
0
ファイル: tests.py プロジェクト: wrichert/django-hookbox
class DjangoHookboxTest(TestCase):
    def _cb_all(self, op, user, channel="-", payload=None):
        if channel in self.all_calls:
            self.all_calls[channel] += 1
        else:
            self.all_calls[channel] = 1
        return None

    def _cb_create(self, op, user, channel=None):
        if channel in self.create_calls:
            self.create_calls[channel] += 1
        else:
            self.create_calls[channel] = 1

        if channel == "/a/":
            return {"history_size": 2, "reflective": False, "presenceful": False, "moderated": True}
        elif channel == "/b/":
            return "denied"
        elif channel == "/c/":
            return [False, {"msg": "also denied"}]
        else:
            return None

    def setUp(self):
        self.all_calls = {}
        self.create_calls = {}

        # HACK: don't allow other apps to mess with us or vice versa...
        self.old_cbs = djhookbox.views._callbacks
        djhookbox.views._callbacks = []
        djhookbox.whcallback(self._cb_all)
        djhookbox.whcallback("create")(self._cb_create)

        User.objects.create_user("a", "*****@*****.**", "a").save()

        self.logcap = LogCapture()

    def tearDown(self):
        djhookbox.views._callbacks = self.old_cbs
        self.logcap.uninstall()

    @server
    def test_create(self):
        self.assertRaises(djhookbox.HookboxError, djhookbox.publish, "/a/", json.dumps({"foo": "bar"}))

        djhookbox.create("/a/")
        djhookbox.publish("/a/", json.dumps({"foo": "bar"}))

        # TODO: Test send_hook works
        # TODO: Confirm it actually did something

    @server
    def test_web_api_token(self):
        secret = djhookbox.apitoken
        try:
            djhookbox.apitoken += "...not!"
            self.assertRaises(djhookbox.HookboxError, djhookbox.publish, "/a/", json.dumps({"foo": "bar"}))
            self.assertCreateCalls({})
        finally:
            djhookbox.apitoken = secret

    def test_webhook_secret(self):
        self.client.login(username="******", password="******")
        response = self.client.post(connect_url, {"channel_name": "a", "secret": djhookbox.views.secret})
        self.assertSuccess(response)

        response = self.client.post(connect_url, {"channel_name": "a"})
        data = self.decode(response)
        self.assertFalse(
            data[0],
            "webhook secret verification should have failed (forgotton to set settings.HOOKBOX_WEBHOOK_SECRET?)",
        )

        response = self.client.post(connect_url, {"channel_name": "a", "secret": djhookbox.views.secret + "...not!"})
        data = self.decode(response)
        self.assertFalse(data[0], "webhook secret verification should have failed")

    def test_signals(self):
        class Listener(object):
            def __call__(self, *args, **kwargs):
                self.signal = kwargs.get("signal")
                self.sender = kwargs.get("sender").username
                self.kwargs = kwargs

        def doTest(which, params=dict(), **checks):
            listener = Listener()
            djhookbox.views.signals[which].connect(listener)

            self.client.login(username="******", password="******")
            params["secret"] = djhookbox.views.secret
            response = self.client.post(reverse("hookbox_%s" % which), params)

            self.assertSuccess(response)
            self.assertEquals(listener.sender, "a")
            for (key, value) in checks.iteritems():
                self.assertEquals(listener.kwargs.get(key), value)

            self.client.logout()
            djhookbox.views.signals[which].disconnect(listener)

        doTest("connect")
        doTest("disconnect")
        doTest("subscribe", {"channel_name": "b"}, channel="b")
        doTest("unsubscribe", {"channel_name": "b"}, channel="b")

    def test_all_cbs(self):
        self.client.login(username="******", password="******")
        params = {"secret": djhookbox.views.secret, "channel_name": "a"}

        response = self.client.post(connect_url, params)
        self.assertSuccess(response)
        self.assertAllCalls({"-": 1})

        response = self.client.post(reverse("hookbox_subscribe"), params)
        self.assertSuccess(response)
        self.assertAllCalls({"-": 1, "a": 1})

        response = self.client.post(
            reverse("hookbox_publish"),
            {"secret": djhookbox.views.secret, "channel_name": "a", "payload": json.dumps(["Hello world"])},
        )
        self.assertSuccess(response)
        self.assertAllCalls({"-": 1, "a": 2})

        response = self.client.post(reverse("hookbox_destroy_channel"), params)
        self.assertSuccess(response)
        self.assertAllCalls({"-": 1, "a": 3})

        response = self.client.post(reverse("hookbox_disconnect"), params)
        self.assertSuccess(response)
        self.assertAllCalls({"-": 2, "a": 3})

    def test_warn_multiple_results(self):
        @djhookbox.whcallback
        def _cb_1(op, user, channel="-"):
            return [True, {}]

        @djhookbox.whcallback
        def _cb_2(op, user, channel="-"):
            return [True, {}]

        params = {"secret": djhookbox.views.secret}

        logging.getLogger("djhookbox").setLevel(logging.WARNING)

        response = self.client.post(connect_url, params)
        self.assertSuccess(response)
        self.assertAllCalls({"-": 1})

        response = self.client.post(reverse("hookbox_disconnect"), params)
        self.assertSuccess(response)
        self.assertAllCalls({"-": 2})

        self.logcap.check(
            ("djhookbox", "WARNING", "multiple results returned from connect callback"),
            ("djhookbox", "WARNING", "multiple results returned from disconnect callback"),
        )

    def test_explicit_deny(self):
        response = self.client.post(
            reverse("hookbox_create_channel"), {"secret": djhookbox.views.secret, "channel_name": "/b/"}
        )

        data = self.decode(response)
        self.assertEquals(data[0], False, "unexpected success")
        self.assertEquals(data[1], {"msg": "denied"})
        self.assertAllCalls({"/b/": 1})

        response = self.client.post(
            reverse("hookbox_create_channel"), {"secret": djhookbox.views.secret, "channel_name": "/c/"}
        )

        data = self.decode(response)
        self.assertEquals(data[0], False, "unexpected success")
        self.assertEquals(data[1], {"msg": "also denied"})
        self.assertAllCalls({"/b/": 1, "/c/": 1})

    def test_callback_error(self):
        @djhookbox.whcallback
        def _cb_1(op, user, channel="-"):
            raise Exception("something bad")

        response = self.client.post(
            reverse("hookbox_create_channel"), {"secret": djhookbox.views.secret, "channel_name": "/a/"}
        )

        data = self.decode(response)
        self.assertEquals(data[0], False, "unexpected success")
        self.assertEquals(data[1], {"msg": "something bad"})
        self.assertAllCalls({"/a/": 1})

    def decode(self, response):
        self.assertEquals(response.status_code, 200)
        self.assert_(("Content-Type", "application/json") in response.items())

        result = json.loads(response.content)
        self.assert_(isinstance(result, list), "unexpected result returned from server: %s" % str(result))
        self.assertEquals(len(result), 2)
        self.assert_(isinstance(result[0], bool), "unexpected result returned from server: %s" % str(result))
        self.assert_(isinstance(result[1], dict), "unexpected result returned from server: %s" % str(result))
        return result

    def assertSuccess(self, response):
        data = self.decode(response)

        if not data[0] and "msg" in data[1]:
            self.fail(data[1]["msg"])
        else:
            self.assert_(data[0])

    def assertAllCalls(self, calls):
        self.assertEquals(self.all_calls, calls)

    def assertCreateCalls(self, calls):
        self.assertEquals(self.create_calls, calls)
コード例 #56
0
class TestCreate(ScriptsMixin, PackageTest):

    def setUp(self):
        super(TestCreate, self).setUp()
        self.db_url = 'sqlite:///'+self.dir.getpath('sqlite.db')
        self.log = LogCapture()
        self.addCleanup(self.log.uninstall)

    def _setup_config(self):
        # setup
        metadata = MetaData()
        self.mytable = Table('user', metadata,
                             Column('id', Integer, primary_key=True),
                             )
        self.config = Config(Source(self.mytable))
        
    def _check_db(self, expected_metadata):
        actual_metadata = MetaData(bind=create_engine(self.db_url))
        actual_metadata.reflect()
        # hmm, not much of a test right now, could do with more depth
        compare(expected_metadata.tables.keys(),
                actual_metadata.tables.keys())
            
    def test_url_from_command_line(self):
        self._setup_config()        
        # make sure we're actually using the url from the command line:
        db_url = self.db_url
        self.db_url = 'junk://'
        self._check('--url=%s create' % db_url, '''
For database at %s:
Creating the following tables:
user
''' % (db_url, ))
            
    def test_pass_in_argv(self):
        self._setup_config()
        # check we can pass in argv if we're being called as a sub-script
        self._check('not for us', '''
For database at %s:
Creating the following tables:
user
''' % (self.db_url, ),
                    kw=dict(argv=['create']))
        expected_metadata = MetaData()
        self.mytable.tometadata(expected_metadata)
        self._check_db(expected_metadata)

    def test_help(self):
        self._setup_config()
        output = self._check('--help', expected=SystemExit)
        self.assertTrue('acted on is at:\n'+self.db_url in output, output)
        self.assertTrue('in the current configuration:\nuser\n' in output, output)
        self.assertTrue('Create all the tables' in output, output)
        self.assertTrue('Drop all tables' in output, output)
        # db should be empty!
        self._check_db(MetaData())

    def test_password_in_help(self):
        self.db_url = "postgres://*****:*****@localhost/db"
        self._setup_config()
        output = self._check('--help', expected=SystemExit)
        self.assertFalse('pw' in output, output)

    def test_help_with_our_parser(self):
        self._setup_config()
        parser = ArgumentParser()
        self.db_url = None
        obj = self._callable()
        obj.setup_parser(parser)
        with OutputCapture() as capture:
            try:
               parser.parse_args(['--help'])
            except SystemExit as ex:
                pass
        output = capture.captured
        self.assertFalse('acted on is at:\n' in output, output)
        self.assertTrue('in the current configuration:\nuser\n' in output, output)
        self.assertTrue('Create all the tables' in output, output)
        self.assertTrue('Drop all tables' in output, output)

    def test_create_without_using_call(self):
        self._setup_config()
        db_url = self.db_url
        self.db_url = None

        parser = ArgumentParser()
        obj = self._callable()
        obj.setup_parser(parser)

        args = parser.parse_args(['create'])
        obj.run(db_url, args)

        self.log.check(
            (logger_name, 'INFO', 'For database at '+db_url+':'),
            (logger_name, 'INFO', 'Creating the following tables:'),
            (logger_name, 'INFO', 'user'),
        )

        expected_metadata = MetaData()
        self.mytable.tometadata(expected_metadata)
        self.db_url = db_url
        self._check_db(expected_metadata)

    def test_create_without_using_call_url_option_preferred(self):
        self._setup_config()
        db_url = self.db_url
        self.db_url = None

        parser = ArgumentParser()
        obj = self._callable()
        obj.setup_parser(parser)

        args = parser.parse_args(['--url', db_url, 'create'])
        obj.run('absolute rubbish', args)

        self.log.check(
            (logger_name, 'INFO', 'For database at '+db_url+':'),
            (logger_name, 'INFO', 'Creating the following tables:'),
            (logger_name, 'INFO', 'user'),
        )

        expected_metadata = MetaData()
        self.mytable.tometadata(expected_metadata)
        self.db_url = db_url
        self._check_db(expected_metadata)

    def test_create_logging_not_printing(self):
        self._setup_config()
        parser = ArgumentParser()
        obj = self._callable()
        obj.setup_parser(parser)

        with OutputCapture() as output:
            args = parser.parse_args(['create'])
            obj.run('absolute rubbish', args)

        self.log.check(
            (logger_name, 'INFO', 'For database at '+self.db_url+':'),
            (logger_name, 'INFO', 'Creating the following tables:'),
            (logger_name, 'INFO', 'user'),
        )

        output.compare('')

    def test_single_source(self):
        self._setup_config()
        # check         
        self._check('create','''
For database at %s:
Creating the following tables:
user
''' % (self.db_url, ))
        expected_metadata = MetaData()
        self.mytable.tometadata(expected_metadata)
        self._check_db(expected_metadata)

    def test_multi_source(self):
        
        # setup
        
        m1 = MetaData()
        t1 = Table('t1', m1,
                   Column('id', Integer, primary_key=True),
                   )
        m1 = MetaData()
        t2 = Table('t2', m1,
                   Column('jd', Integer, primary_key=True),
                   )
        self.config = Config(Source(t1),
                             Source(t2))
    
        # check 
        
        self._check('create','''
For database at %s:
Creating the following tables:
t1
t2
''' % (self.db_url, ))

        expected_metadata = MetaData()
        t1.tometadata(expected_metadata)
        t2.tometadata(expected_metadata)
        self._check_db(expected_metadata)
    
    def test_table_present(self):
        self._setup_config()
        self.mytable.create(create_engine(self.db_url))
        # check         
        self._check('create','''
For database at %s:
Refusing to create as the following tables exist:
user
''' % self.db_url)
        expected_metadata = MetaData()
        self.mytable.tometadata(expected_metadata)
コード例 #57
0
ファイル: test_file.py プロジェクト: peteches/servercheck
class TestFile:

    def __init__(self):
        self.tmpdir = tempfile.mkdtemp()
        self.file_that_exists = tempfile.mkstemp(dir=self.tmpdir)[1]
        self.file_that_does_not_exist = os.path.join(self.tmpdir,
                                                     'does_not_exist')
        os.chmod(self.file_that_exists, 0o644)
        self.link = os.path.join(self.tmpdir, 'symlink')

        os.symlink(self.file_that_exists, self.link)

        self.test_string = 'Hello, looking for me?'
        self.missing_string = 'HAHA you will never catch me!!'

        self.pass_str = '\033[1;32mPASS: File {} {}\033[0m'
        self.fail_str = '\033[1;31mFAIL: File {} {}\033[0m'

        self.log_name = 'servercheck.TestFileTester.{}'

        with open(self.file_that_exists, 'w') as fd:
            fd.writelines([self.test_string])

        self._file_types = ['reg',
                            'dir',
                            'symlink',
                            'broken symlink',
                            'missing',
                            ]

        self._file_type = {
            'reg': 'regular file',
            'dir': 'directory',
            'symlink': 'symlink',
            'broken symlink': 'symlink',
        }

    def setup(self):
        self.log_capture = LogCapture()

    def teardown(self):
        self.log_capture.uninstall()

    def generate_file_perms(self, num):
        def tup2str(t):
            return ''.join(map(str, t))

        rwx_perms = set(map(lambda x: x[0] | x[1] | x[2] | x[3],
                            itertools.combinations_with_replacement([4, 2, 1, 0],  # nopep8
                                                                    4)))
        perms = [tup2str(x)
                 for x in itertools.permutations(rwx_perms, 4)]

        random.shuffle(perms)

        return perms[1:num]

    def create_file(self, ft='reg', mode=644, content=None):
        if ft == 'reg':
            path = tempfile.mkstemp(dir=self.tmpdir)[1]
        elif ft == 'dir':
            path = tempfile.mkdtemp(dir=self.tmpdir)
        elif ft == 'symlink':
            link_dst = tempfile.mkstemp(dir=self.tmpdir)[1]
            path = tempfile.mktemp(dir=self.tmpdir)
            os.symlink(link_dst, path)
        elif ft == 'broken symlink':
            link_dst = tempfile.mkstemp(dir=self.tmpdir)[1]
            path = tempfile.mktemp(dir=self.tmpdir)
            os.symlink(link_dst, path)
            os.remove(link_dst)
        elif ft == 'missing':
            path = tempfile.mktemp()

        if ft in ['reg', 'symlink'] \
                and content:
            with open(path, 'w') as fd:
                fd.write(content)

        if ft not in ['missing', 'broken symlink']:
            os.chmod(path,
                     int(str(mode), 8))

        return path

    def check_file_path_attribute(self, ft):
        p = self.create_file(ft)
        filetester = TestFileTester(p)
        assert_equal(filetester._file_path, p)

    def test_file_path_attributes(self):
        for i in self._file_types:
            yield self.check_file_path_attribute, i

    def check_exists(self, file_type):
        p = self.create_file(ft=file_type)
        filetester = TestFileTester(p)

        filetester.exists()

        if file_type == 'missing':
            lvl = 'WARNING'
            msg = self.fail_str.format(p, 'does not exist.')
        elif file_type == 'broken symlink':
            lvl = 'WARNING'
            msg = self.fail_str.format(p, 'is a broken symlink.')
        else:
            lvl = 'INFO'
            msg = self.pass_str.format(p, 'exists.')

        self.log_capture.check(
            (
                self.log_name.format(p),
                lvl,
                msg,
            ),
        )

    def test_exists_checks(self):
        for file_type in self._file_types:
            yield self.check_exists, file_type

    def check_is_file(self, file_type):
        p = self.create_file(ft=file_type)
        filetester = TestFileTester(p)
        if file_type == 'reg':
            lvl = 'INFO'
            msg = self.pass_str.format(p, 'is a regular file.')
        elif file_type == 'missing':
            lvl = 'WARNING'
            msg = self.fail_str.format(p, 'does not exist.')
        elif file_type == 'broken symlink':
            lvl = 'WARNING'
            msg = self.fail_str.format(p, 'is a broken symlink.')
        else:
            lvl = 'WARNING'
            msg = self.fail_str.format(p, 'is not a regular file.')

        filetester.is_file()

        self.log_capture.check(
            (
                self.log_name.format(p),
                lvl,
                msg,
            ),
        )

    def test_is_file_checks(self):
        for file_type in self._file_types:
            yield self.check_is_file, file_type

    def check_file_is_dir(self, file_type):
        p = self.create_file(ft=file_type)

        filetester = TestFileTester(p)

        if file_type == 'dir':
            lvl = 'INFO'
            msg = self.pass_str.format(p,
                                       'is a {}.'.format(self._file_type[file_type]))  # nopep8
        elif file_type == 'missing':
            lvl = 'WARNING'
            msg = self.fail_str.format(p, 'does not exist.')
        elif file_type == 'broken symlink':
            lvl = 'WARNING'
            msg = self.fail_str.format(p, 'is a broken symlink.')
        else:
            lvl = 'WARNING'
            msg = self.fail_str.format(p, 'is not a directory.'
                                       ' {} is a {}.'.format(p,
                                                            self._file_type[file_type]))  # nopep8

        filetester.is_dir()

        self.log_capture.check(
            (self.log_name.format(p),
             lvl,
             msg,
             ),
        )

    def test_is_dir_checks(self):
        for ft in self._file_types:
            yield self.check_file_is_dir, ft

    def check_is_symlink(self, file_type):
        p = self.create_file(ft=file_type)

        filetester = TestFileTester(p)

        if file_type == 'symlink':
            lvl = 'INFO'
            msg = self.pass_str.format(p, 'is a symlink.')
        elif file_type == 'missing':
            lvl = 'WARNING'
            msg = self.fail_str.format(p, 'does not exist.')
        elif file_type == 'broken symlink':
            lvl = 'WARNING'
            msg = self.fail_str.format(p, 'is a broken symlink.')
        else:
            lvl = 'WARNING'
            msg = self.fail_str.format(p, 'is not a symlink.')

        filetester.is_symlink()

        self.log_capture.check(
            (
                self.log_name.format(p),
                lvl,
                msg,
            ),
        )

    def test_is_symlink_checks(self):
        for ft in self._file_types:
            yield self.check_is_symlink, ft

    def check_true_is_symlinked_to(self, file_type):
        src = self.create_file(file_type)
        dst = tempfile.mktemp()
        os.symlink(src, dst)

        filetester = TestFileTester(dst)

        filetester.is_symlinked_to(src)

        self.log_capture.check(
            (
                self.log_name.format(dst),
                'INFO',
                self.pass_str.format(dst,
                                     'is symlinked to {}.'.format(src))
            ),
        )

    def test_is_symlinked_to(self):
        for ft in [x for x in self._file_types
                   if x not in ['broken symlink',
                                'missing']]:
            yield self.check_true_is_symlinked_to, ft

    def check_file_mode(self, ft, file_mode, test_mode):
        p = self.create_file(ft, mode=file_mode)
        filetester = TestFileTester(p)

        filetester.mode(test_mode)

        if ft == 'missing':
            lvl = 'WARNING'
            msg = self.fail_str.format(p, 'does not exist.')
        elif ft == 'broken symlink':
            lvl = 'WARNING'
            msg = self.fail_str.format(p, 'is a broken symlink.')
        elif file_mode != test_mode:
            lvl = 'WARNING'
            msg = self.fail_str.format(p,
                                       'does not have expected permissions.')
        elif file_mode == test_mode:
            lvl = 'INFO'
            msg = self.pass_str.format(p, 'has correct perms.')

        self.log_capture.check(
            (self.log_name.format(p),
             lvl,
             msg,
             ),
        )

    def test_file_perms(self):
        for t in self._file_types:
            for x, y in zip(self.generate_file_perms(50),
                            self.generate_file_perms(50)):
                yield self.check_file_mode, t, x, y

            for p in self.generate_file_perms(50):
                yield self.check_file_mode, t, p, p

    def check_excecute_perms(self, p, u):
        os.chmod(self.file_that_exists, int(str(p), 8))

        ft = TestFileTester(self.file_that_exists)
        ft.is_executable_by(u)

        if u == 'user':
            mask = stat.S_IXUSR
        elif u == 'group':
            mask = stat.S_IXGRP
        elif u == 'other':
            mask = stat.S_IXOTH

        if int(str(p), 8) & mask:
            lvl = 'INFO'
            msg = self.pass_str.format(self.file_that_exists,
                                       'is executable by {}.'.format(u))
        else:
            lvl = 'WARNING'
            msg = self.fail_str.format(self.file_that_exists,
                                       'is not executable by {}.'.format(u))

        self.log_capture.check(
            (self.log_name.format(self.file_that_exists),
             lvl,
             msg
             )
        )

    def test_executable_generator(self):
        for i in ['user', 'group', 'other']:
            for p in self.generate_file_perms(20):
                yield self.check_excecute_perms, p, i

    def test_file_has_string(self):
        rand_string = ''.join(random.sample(string.ascii_letters, 20))
        p = self.create_file('reg', content=rand_string)

        filetester = TestFileTester(p)

        filetester.contains_string(rand_string)

        self.log_capture.check(
            (
                self.log_name.format(p),
                'INFO',
                self.pass_str.format(p, 'contains the string: "{}".'.format(rand_string))  # nopep8
            )
        )

    def test_false_file_has_string(self):
        string_in_file = ''.join(random.sample(string.ascii_letters, 20))
        string_to_search_for = ''.join(random.sample(string.ascii_letters, 25))
        p = self.create_file('reg', content=string_in_file)

        filetester = TestFileTester(p)

        filetester.contains_string(string_to_search_for)

        self.log_capture.check(
            (
                self.log_name.format(p),
                'WARNING',
                self.fail_str.format(p, 'does not contain the string: "{}".'.format(string_to_search_for))  # nopep8
            )
        )

    def check_owner_is(self, path, user, expected_result):
        filetester = TestFileTester(path)

        filetester.owner_is(user)

        if expected_result:
            lvl = 'INFO'
            msg = self.pass_str.format(path, 'is owned by {}.'.format(user))
        else:
            lvl = 'WARNING'
            msg = self.fail_str.format(path,
                                       'is not owned by {}.'.format(user))

        self.log_capture.check(
            (
                self.log_name.format(path),
                lvl,
                msg,
            ),
        )

    def check_owner_is_args(self, user):
        fail_str = '\033[1;31mFAIL: {}\033[0m'

        p = self.create_file()
        filetester = TestFileTester(p)

        try:
            if user.isdigit():
                user = int(user)
                msg = self.fail_str.format(p, 'no such uid {}.'.format(user))
            else:
                msg = self.fail_str.format(p, 'no such user {}.'.format(user))
        except AttributeError:
            msg = fail_str.format('Expected user described as int (uid) or str (user name).')  # nopep8

        filetester.owner_is(user)

        self.log_capture.check(
            (
                self.log_name.format(p),
                'WARNING',
                msg,
            ),
        )

    def test_file_owner_is(self):

        users = [
            pwd.getpwuid(os.getuid()),
            pwd.getpwnam('root'),
        ]

        for f in [x.pw_dir for x in users]:
            fuid = os.stat(f).st_uid
            for u in [y.pw_uid for y in users]:
                if fuid == u:
                    b = True
                else:
                    b = False
                yield self.check_owner_is, f, u, b

            for u in [y.pw_name for y in users]:
                if fuid == pwd.getpwnam(u).pw_uid:
                    b = True
                else:
                    b = False
                yield self.check_owner_is, f, u, b

        users = ['fdls', 'lpok']
        uids = ['7876', '9098', '8876']

        for u in users + uids:
            yield self.check_owner_is_args, u

    def check_group_is(self, path, grp, expected_result):
        filetester = TestFileTester(path)

        filetester.group_is(grp)

        if expected_result:
            lvl = 'INFO'
            msg = self.pass_str.format(path, 'is group owned by {}.'.format(grp))
        else:
            lvl = 'WARNING'
            msg = self.fail_str.format(path,
                                       'is not group owned by {}.'.format(grp))

        self.log_capture.check(
            (
                self.log_name.format(path),
                lvl,
                msg,
            ),
        )

    def check_group_is_args(self, grp):
        fail_str = '\033[1;31mFAIL: {}\033[0m'

        p = self.create_file()

        filetester = TestFileTester(p)

        try:
            if grp.isdigit():
                grp = int(grp)
                msg = self.fail_str.format(p, 'no such gid {}.'.format(grp))
            else:
                msg = self.fail_str.format(p, 'no such group {}.'.format(grp))

        except AttributeError:
            msg = fail_str.format('Expected group described as int (gid) or str (group name).')  # nopep8

        filetester.group_is(grp)

        self.log_capture.check(
            (
                self.log_name.format(p),
                'WARNING',
                msg,
            ),
        )

    def test_file_group_is(self):

        groups = [
            grp.getgrgid(os.getgid()),
            grp.getgrnam('root'),
        ]

        paths = [
            pwd.getpwuid(os.getuid()).pw_dir,
            '/root',
        ]

        for f in paths:
            fgid = os.stat(f).st_gid
            for g in [y.gr_gid for y in groups]:
                if fgid == g:
                    b = True
                else:
                    b = False
                yield self.check_group_is, f, g, b

            for g in [y.gr_name for y in groups]:
                if fgid == pwd.getpwnam(g).pw_gid:
                    b = True
                else:
                    b = False
                yield self.check_group_is, f, g, b

        groups = ['fdls', 'lpok']
        gids = ['7876', '9098', '8876']

        for g in groups + gids:
            yield self.check_group_is_args, g