Exemple #1
0
def main():
    test_name = 'GET fuzzed'
    get_template = Template(
        name=test_name,
        fields=[
            XmlElement(
                name='html',
                element_name='html',
                content=[
                    XmlElement(
                        name='head',
                        element_name='head',
                        content='<meta http-equiv="refresh" content="5; url=/">'
                    ),
                    XmlElement(name='body',
                               element_name='body',
                               content='123',
                               fuzz_content=True),
                ])
        ])

    fuzzer = ClientFuzzer(name='Example 2 - Browser Fuzzer (Remote)')
    fuzzer.set_interface(WebInterface(host='0.0.0.0', port=26000))

    target = ClientTarget(name='BrowserTarget')

    #
    # Note: to avoid opening the process on our X server, we use another display for it
    # display ':2' that is specified below was started this way:
    # >> sudo apt-get install xvfb
    # >> Xvfb :2 -screen 2 1280x1024x8
    #
    env = os.environ.copy()
    env['DISPLAY'] = ':2'
    controller = ClientProcessController('BrowserController',
                                         '/usr/bin/opera',
                                         ['http://localhost:8082/fuzzed'],
                                         process_env=env)
    target.set_controller(controller)
    target.set_mutation_server_timeout(20)

    model = GraphModel()
    model.connect(get_template)
    fuzzer.set_model(model)
    fuzzer.set_target(target)

    #
    # only fuzz the half of the mutations, just as an example
    fuzzer.set_range(end_index=model.num_mutations() // 2)
    fuzzer.set_delay_between_tests(0.1)

    remote = RpcServer(host='localhost', port=26007, impl=fuzzer)
    remote.start()
Exemple #2
0
def main():
    test_name = 'GET /fuzzed'
    get_template = Template(name=test_name, fields=[
        XmlElement(name='html', element_name='html', content=[
            XmlElement(name='head', element_name='head', content='<meta http-equiv="refresh" content="5; url=/">'),
            XmlElement(name='body', element_name='body', content='123', fuzz_content=True),
        ])
    ])

    fuzzer = ClientFuzzer(name='BrowserFuzzer')
    fuzzer.set_interface(WebInterface(host='0.0.0.0', port=26000))

    target = ClientTarget(name='BrowserTarget')

    #
    # Note: to avoid opening the process on our X server, we use another display for it
    # display ':2' that is specified below was started this way:
    # >> sudo apt-get install xvfb
    # >> Xvfb :2 -screen 2 1280x1024x8
    #
    env = os.environ.copy()
    env['DISPLAY'] = ':2'
    controller = ClientProcessController(
        'BrowserController',
        '/usr/bin/opera',
        ['http://localhost:8082/fuzzed'],
        process_env=env
    )
    target.set_controller(controller)
    target.set_mutation_server_timeout(20)

    model = GraphModel()
    model.connect(get_template)
    fuzzer.set_model(model)
    fuzzer.set_target(target)

    #
    # only fuzz the half of the mutations, just as an example
    fuzzer.set_range(end_index=model.num_mutations() / 2)
    fuzzer.set_delay_between_tests(0.1)

    remote = RpcServer(host='localhost', port=26007, impl=fuzzer)
    remote.start()
Exemple #3
0
class GraphModelTests(unittest.TestCase):

    def setUp(self):
        self.logger = get_test_logger()
        self.logger.debug('TESTING METHOD: %s', self._testMethodName)
        self.model = GraphModel()
        self.templates = self.get_templates()
        self.todo = []

    def get_templates(self):
        res = []
        res.append(Template(name='t1', fields=[String('data1')]))
        res.append(Template(name='t2', fields=[String('data2'), UInt32(300)]))
        res.append(Template(name='t3', fields=[UInt32(400)]))
        return res

    def _check_sequences(self, expected_sequences):
        self.logger.debug('check num_mutations()')
        t_num_mutations = sum(s[-1].num_mutations() for s in expected_sequences)
        m_num_mutations = self.model.num_mutations()
        self.assertEqual(t_num_mutations, m_num_mutations)
        sequences = {}
        while self.model.mutate():
            sequence = tuple(self.model.get_sequence())
            if sequence not in sequences:
                sequences[sequence] = 1
            else:
                sequences[sequence] += 1
        self.assertEqual(len(sequences), len(expected_sequences))
        self.logger.debug('check that each sequence appears the appropriate number of times')
        for sequence, count in sequences.items():
            seq_templates = [e.dst for e in sequence]
            self.assertIn(seq_templates, expected_sequences)
            last = seq_templates[-1]
            last_num_mutations = last.num_mutations()
            self.assertEqual(count, last_num_mutations)

    def test_sequence_single_template(self):
        t = self.templates[0]
        self.model.connect(t)
        expected_sequences = [[t]]
        self._check_sequences(expected_sequences)

    def test_sequence_direct_path(self):
        '''
        root -> t1
        '''
        self.model.connect(self.templates[0])
        for i in range(len(self.templates) - 1):
            self.model.connect(self.templates[i], self.templates[i + 1])
        expected_sequences = list(self.templates[:i + 1] for i in range(len(self.templates)))
        self._check_sequences(expected_sequences)

    def test_sequence_complex_path(self):
        '''
        root -> t1
        root -> t1 -> t2
        root -> t1 -> t3
        root -> t1 -> t2 -> t3
        '''
        self.model.connect(self.templates[0])
        self.model.connect(self.templates[0], self.templates[1])
        self.model.connect(self.templates[0], self.templates[2])
        self.model.connect(self.templates[1], self.templates[2])
        expected_sequences = [
            [self.templates[0]],
            [self.templates[0], self.templates[1]],
            [self.templates[0], self.templates[2]],
            [self.templates[0], self.templates[1], self.templates[2]]
        ]
        self._check_sequences(expected_sequences)

    def test_multi_head_path(self):
        '''
        root -> t1
        root -> t2
        root -> t3
        '''
        expected_sequences = []
        for t in self.templates:
            expected_sequences.append([t])
            self.model.connect(t)
        self._check_sequences(expected_sequences)

    def _check_skip(self, to_skip, expected_skipped, expected_mutated):
        skipped = self.model.skip(to_skip)
        self.assertEqual(expected_skipped, skipped)
        mutated = 0
        while self.model.mutate():
            mutated += 1
        self.assertEqual(expected_mutated, mutated)

    def test_skip_zero_single_template(self):
        self.model.connect(self.templates[0])
        m_num_mutations = self.model.num_mutations()
        to_skip = 0
        expected_skipped = to_skip
        expected_mutated = m_num_mutations
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def test_skip_half_single_template(self):
        self.model.connect(self.templates[0])
        m_num_mutations = self.model.num_mutations()
        to_skip = m_num_mutations / 2
        expected_skipped = to_skip
        expected_mutated = m_num_mutations - expected_skipped
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def test_skip_exact_single_template(self):
        self.model.connect(self.templates[0])
        m_num_mutations = self.model.num_mutations()
        to_skip = m_num_mutations
        expected_skipped = to_skip
        expected_mutated = m_num_mutations - expected_skipped
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def test_skip_too_much_single_template(self):
        self.model.connect(self.templates[0])
        m_num_mutations = self.model.num_mutations()
        to_skip = m_num_mutations + 10
        expected_skipped = m_num_mutations
        expected_mutated = m_num_mutations - expected_skipped
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def test_skip_zero_multi_template(self):
        self.model.connect(self.templates[0])
        self.model.connect(self.templates[0], self.templates[1])
        m_num_mutations = self.model.num_mutations()
        to_skip = 0
        expected_skipped = to_skip
        expected_mutated = m_num_mutations
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def test_skip_half_multi_template(self):
        self.model.connect(self.templates[0])
        self.model.connect(self.templates[0], self.templates[1])
        m_num_mutations = self.model.num_mutations()
        to_skip = m_num_mutations / 2
        expected_skipped = to_skip
        expected_mutated = m_num_mutations - expected_skipped
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def test_skip_exact_multi_template(self):
        self.model.connect(self.templates[0])
        self.model.connect(self.templates[0], self.templates[1])
        m_num_mutations = self.model.num_mutations()
        to_skip = m_num_mutations
        expected_skipped = to_skip
        expected_mutated = m_num_mutations - expected_skipped
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def test_skip_too_much_multi_template(self):
        self.model.connect(self.templates[0])
        self.model.connect(self.templates[0], self.templates[1])
        m_num_mutations = self.model.num_mutations()
        to_skip = m_num_mutations + 10
        expected_skipped = m_num_mutations
        expected_mutated = m_num_mutations - expected_skipped
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def test_failure_to_to(self):
        self.assertEqual(len(self.todo), 0)

    def test_exception_if_loop(self):
        self.model.connect(self.templates[0])
        self.model.connect(self.templates[0], self.templates[1])
        self.model.connect(self.templates[1], self.templates[0])
        with self.assertRaises(KittyException):
            self.model.num_mutations()
class TestClientFuzzer(unittest.TestCase):
    def setUp(self):
        self.logger = get_test_logger()
        self.logger.debug('TESTING METHOD: %s', self._testMethodName)
        self._default_stage = 'simple_str_template'

        self.t_str = Template(name=self._default_stage,
                              fields=[String(name='str1', value='kitty')])

        self.t_int = Template(name='simple_int_template',
                              fields=[UInt32(name='int1', value=0x1234)])
        self.fuzzer = None
        self.mutations = {}
        self.prepare()

    def tearDown(self):
        if self.fuzzer:
            self.fuzzer.stop()

    def default_callback(self, test, stage, resp):
        if test not in self.mutations:
            self.mutations[test] = []
        self.mutations[test].append((stage, resp))

    def prepare(self):
        self.start_index = 10
        self.end_index = 20
        self.delay_duration = 0
        self.fuzzer = ClientFuzzer(name="TestServerFuzzer", logger=self.logger)

        self.interface = EmptyInterface()
        self.fuzzer.set_interface(self.interface)

        self.model = GraphModel()
        self.model.logger = self.logger

        self.model.connect(self.t_str)
        self.fuzzer.set_model(self.model)

        self.default_config = {
            'always': {
                'trigger': {
                    'fuzzer': self.fuzzer,
                    'stages': [(self._default_stage, {})]
                }
            }
        }
        self.target = ClientTargetMock(self.default_config,
                                       self.default_callback,
                                       logger=self.logger)
        self.fuzzer.set_target(self.target)

        self.fuzzer.set_range(self.start_index, self.end_index)
        self.fuzzer.set_delay_between_tests(self.delay_duration)

    def testRaisesExceptionWhenStartedWithoutModel(self):

        self.fuzzer.set_model(None)
        self.assertRaises(AssertionError, self.fuzzer.start)
        self.fuzzer = None

    def testRaisesExceptionWhenStartedWithoutTarget(self):
        self.fuzzer.set_target(None)
        self.assertRaises(AssertionError, self.fuzzer.start)
        self.fuzzer = None

    def testRaisesExceptionWhenStartedWithoutInterface(self):
        self.fuzzer.set_interface(None)
        self.assertRaises(AssertionError, self.fuzzer.start)
        self.fuzzer = None

    def testVanilla(self):
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        info = self.fuzzer._get_session_info()
        # reports = self.fuzzer._get_reports_manager()
        # self.assertEqual(len(reports), 0)
        self.assertEqual(info.failure_count, 0)
        self.assertEqual(info.current_index, None)
        # self.assertEqual(info.original_start_index, 10)
        self.assertEqual(info.start_index, self.start_index)
        self.assertEqual(info.end_index, self.end_index)

    def testStartingFromStartIndex(self):
        start_index = self.model.num_mutations() - 2
        self.fuzzer.set_range(start_index)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()

        info = self.fuzzer._get_session_info()
        self.assertEqual(info.current_index, None)
        self.assertEqual(info.end_index, self.model.last_index())

    def testEndingAtEndIndex(self):
        start_index = 0
        end_index = 3
        self.fuzzer.set_range(start_index, end_index)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()

        info = self.fuzzer._get_session_info()
        self.assertEqual(info.start_index, 0)
        self.assertEqual(info.end_index, 3)
        self.assertEqual(info.current_index, None)

    def testFullMutationRange(self):
        self.fuzzer.set_range()
        self.fuzzer.start()
        self.fuzzer.wait_until_done()

        info = self.fuzzer._get_session_info()
        self.assertEqual(info.start_index, 0)
        self.assertEqual(info.end_index, self.model.last_index())
        self.assertEqual(info.current_index, None)

    def testTestFailedWhenReportIsFailed(self):
        config = {
            '13': {
                'report': {
                    'status': 'failed',
                    'reason': 'failure reason'
                }
            }
        }
        config.update(self.default_config)
        target = ClientTargetMock(config,
                                  self.default_callback,
                                  logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        info = self.fuzzer._get_session_info()
        reports = self.fuzzer.dataman.get_report_test_ids()
        self.assertEqual(
            sorted(reports),
            sorted([int(x) for x in config.keys() if x != 'always']))
        self.assertEqual(info.failure_count, len(config) - 1)

    def testAllFailedTestsHaveReports(self):
        config = {
            '10': {
                'report': {
                    'status': 'failed',
                    'reason': 'failure reason'
                }
            },
            '11': {
                'report': {
                    'status': 'failed',
                    'reason': 'failure reason'
                }
            },
            '12': {
                'report': {
                    'status': 'failed',
                    'reason': 'failure reason'
                }
            },
            '13': {
                'report': {
                    'status': 'failed',
                    'reason': 'failure reason'
                }
            }
        }
        config.update(self.default_config)
        target = ClientTargetMock(config,
                                  self.default_callback,
                                  logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        info = self.fuzzer._get_session_info()
        reports = self.fuzzer.dataman.get_report_test_ids()
        self.assertEqual(
            sorted(reports),
            sorted([int(x) for x in config.keys() if x != 'always']))
        self.assertEqual(info.failure_count, len(config) - 1)

    def testStoringAllReportsWhenStoreAllReportsIsSetToTrue(self):
        config = {}
        config.update(self.default_config)
        target = ClientTargetMock(config,
                                  self.default_callback,
                                  logger=self.logger)
        self.fuzzer.set_store_all_reports(True)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        info = self.fuzzer._get_session_info()
        reports = self.fuzzer.dataman.get_report_test_ids()
        expected_mutation_count = self.end_index - self.start_index + 1
        expected_failure_count = 0
        self.assertEqual(len(reports), expected_mutation_count)
        self.assertEqual(info.failure_count, expected_failure_count)

    def testOnlyTestsInSetRangeAreExecuted(self):
        start_index = self.model.num_mutations() - 5
        self.model.connect(self.t_str, self.t_int)
        expected_end_index = self.model.last_index()
        self.fuzzer.set_range(start_index)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        info = self.fuzzer._get_session_info()
        self.assertEqual(info.failure_count, 0)
        self.assertEqual(info.current_index, None)
        self.assertEqual(info.start_index, start_index)
        self.assertEqual(info.end_index, expected_end_index)

    def testGetMutationForStage(self):
        self.fuzzer.set_range(0, 1)
        config = {
            'always': {
                'trigger': {
                    'fuzzer': self.fuzzer,
                    'stages': [(self._default_stage, {})]
                }
            }
        }
        target = ClientTargetMock(config,
                                  self.default_callback,
                                  logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        self.assertIn(0, self.mutations)
        self.assertEqual(self.mutations[0][0][0], self._default_stage)
        self.assertIsNotNone(self.mutations[0][0][1])

    def testGetMutationForStageTwice(self):
        self.fuzzer.set_range(0, 1)
        config = {
            'always': {
                'trigger': {
                    'fuzzer':
                    self.fuzzer,
                    'stages': [(self._default_stage, {}),
                               (self._default_stage, {})]
                }
            }
        }
        target = ClientTargetMock(config,
                                  self.default_callback,
                                  logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        self.assertIn(0, self.mutations)
        self.assertEqual(self.mutations[0][0][0], self._default_stage)
        self.assertIsNotNone(self.mutations[0][0][1])
        self.assertEqual(self.mutations[0][1][0], self._default_stage)
        self.assertIsNotNone(self.mutations[0][1][1])

    def testGetMutationWrongStage(self):
        self.fuzzer.set_range(0, 1)
        wrong_stage = 'simple_str_template1'
        config = {
            'always': {
                'trigger': {
                    'fuzzer': self.fuzzer,
                    'stages': [
                        (wrong_stage, {}),
                    ]
                }
            }
        }
        target = ClientTargetMock(config,
                                  self.default_callback,
                                  logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        self.assertIn(0, self.mutations)
        self.assertEqual(self.mutations[0][0][0], wrong_stage)
        self.assertIsNone(self.mutations[0][0][1])

    def testGetMutationWrongAfterCorrectStage(self):
        self.fuzzer.set_range(0, 1)
        wrong_stage = 'simple_str_template1'
        config = {
            'always': {
                'trigger': {
                    'fuzzer': self.fuzzer,
                    'stages': [
                        (self._default_stage, {}),
                        (wrong_stage, {}),
                    ]
                }
            }
        }
        target = ClientTargetMock(config,
                                  self.default_callback,
                                  logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        self.assertIn(0, self.mutations)
        self.assertEqual(self.mutations[0][0][0], self._default_stage)
        self.assertIsNotNone(self.mutations[0][0][1])
        self.assertEqual(self.mutations[0][1][0], wrong_stage)
        self.assertIsNone(self.mutations[0][1][1])

    def testGetMutationCorrectAfterWrongStage(self):
        self.fuzzer.set_range(0, 1)
        wrong_stage = 'simple_str_template1'
        config = {
            'always': {
                'trigger': {
                    'fuzzer': self.fuzzer,
                    'stages': [
                        (wrong_stage, {}),
                        (self._default_stage, {}),
                    ]
                }
            }
        }
        target = ClientTargetMock(config,
                                  self.default_callback,
                                  logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        self.assertIn(0, self.mutations)
        self.assertEqual(self.mutations[0][0][0], wrong_stage)
        self.assertIsNone(self.mutations[0][0][1])
        self.assertEqual(self.mutations[0][1][0], self._default_stage)
        self.assertIsNotNone(self.mutations[0][1][1])

    def testGetMutationWithWildcard(self):
        self.fuzzer.set_range(0, 1)
        config = {
            'always': {
                'trigger': {
                    'fuzzer': self.fuzzer,
                    'stages': [(ClientFuzzer.STAGE_ANY, {})]
                }
            }
        }
        target = ClientTargetMock(config,
                                  self.default_callback,
                                  logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        self.assertIn(0, self.mutations)
        self.assertEqual(self.mutations[0][0][0], ClientFuzzer.STAGE_ANY)
        self.assertIsNotNone(self.mutations[0][0][1])
Exemple #5
0
class TestServerFuzzer(unittest.TestCase):

    def setUp(self):
        self.logger = get_test_logger()
        self.logger.debug('TESTING METHOD: %s', self._testMethodName)

        self.t_str = Template(name='simple_str_template', fields=[String(name='str1', value='kitty')])

        self.t_int = Template(name='simple_int_template', fields=[UInt32(name='int1', value=0x1234)])
        self.fuzzer = None
        self.prepare()

    def tearDown(self):
        if self.fuzzer:
            self.fuzzer.stop()
        if self.session_file_name:
            if os.path.exists(self.session_file_name):
                os.remove(self.session_file_name)

    def prepare(self):
        self.start_index = 10
        self.end_index = 20
        self.delay_duration = 0
        self.session_file_name = None

        self.interface = EmptyInterface()

        self.model = GraphModel()
        self.model.logger = self.logger
        self.model.connect(self.t_str)

        self.target = ServerTargetMock({}, logger=self.logger)

        self.fuzzer = ServerFuzzer(name="TestServerFuzzer", logger=self.logger)
        self.fuzzer.set_interface(self.interface)
        self.fuzzer.set_model(self.model)
        self.fuzzer.set_target(self.target)
        self.fuzzer.set_range(self.start_index, self.end_index)
        self.fuzzer.set_delay_between_tests(self.delay_duration)

    def testRaisesExceptionWhenStartedWithoutModel(self):

        self.fuzzer.set_model(None)
        self.assertRaises(AssertionError, self.fuzzer.start)
        self.fuzzer = None

    def testRaisesExceptionWhenStartedWithoutTarget(self):
        self.fuzzer.set_target(None)
        self.assertRaises(AssertionError, self.fuzzer.start)
        self.fuzzer = None

    def testRaisesExceptionWhenStartedWithoutInterface(self):
        self.fuzzer.set_interface(None)
        self.assertRaises(AssertionError, self.fuzzer.start)
        self.fuzzer = None

    def testCommandLineArgumentsStart(self):
        self.start_index = 10
        cmd_line = '--start=%d' % self.start_index
        self.fuzzer = ServerFuzzer(name="TestServerFuzzer", logger=self.logger, option_line=cmd_line)
        self.fuzzer.set_interface(self.interface)
        self.fuzzer.set_model(self.model)
        self.fuzzer.set_target(self.target)
        self.fuzzer.set_delay_between_tests(self.delay_duration)
        self.fuzzer.start()

        info = self.fuzzer._get_session_info()
        self.assertEqual(info.current_index, self.model.last_index())
        self.assertEqual(info.start_index, self.start_index)

    def testCommandLineArgumentsEnd(self):
        self.end_index = 10
        cmd_line = '--end=%d' % self.end_index
        self.fuzzer = ServerFuzzer(name="TestServerFuzzer", logger=self.logger, option_line=cmd_line)
        self.fuzzer.set_interface(self.interface)
        self.fuzzer.set_model(self.model)
        self.fuzzer.set_target(self.target)
        self.fuzzer.set_delay_between_tests(self.delay_duration)
        self.fuzzer.start()

        info = self.fuzzer._get_session_info()
        self.assertEqual(info.start_index, 0)
        self.assertEqual(info.end_index, self.end_index)
        self.assertEqual(info.current_index, self.end_index)

    def testCommandLineArgumentDelay(self):
        self.delay_duration = 0.1
        cmd_line = '--delay=%s' % self.delay_duration
        self.fuzzer = ServerFuzzer(name="TestServerFuzzer", logger=self.logger, option_line=cmd_line)
        self.fuzzer.set_interface(self.interface)
        self.fuzzer.set_model(self.model)
        self.fuzzer.set_target(self.target)
        self.fuzzer.set_range(self.start_index, self.end_index)
        self.assertEqual(self.delay_duration, self.fuzzer.config.delay_secs)
        start_time = time.time()
        self.fuzzer.start()
        end_time = time.time()
        expected_runtime = self.delay_duration * (self.end_index - self.start_index + 1)
        actual_runtime = end_time - start_time
        self.assertAlmostEqual(int(actual_runtime), int(expected_runtime))

    def testCommandLineArgumentSession(self):
        self.session_file_name = 'mysession.sqlite'
        cmd_line = '--session=%s' % self.session_file_name
        self.fuzzer = ServerFuzzer(name="TestServerFuzzer", logger=self.logger, option_line=cmd_line)
        self.fuzzer.set_interface(self.interface)
        self.fuzzer.set_model(self.model)
        self.fuzzer.set_target(self.target)
        self.fuzzer.set_delay_between_tests(self.delay_duration)
        self.fuzzer.set_range(self.start_index, self.end_index)
        self.assertEqual(self.session_file_name, self.fuzzer.config.session_file_name)
        self.fuzzer.start()

    def testVanilla(self):
        self.fuzzer.start()
        info = self.fuzzer._get_session_info()
        # reports = self.fuzzer._get_reports_manager()
        # self.assertEqual(len(reports), 0)
        self.assertEqual(info.failure_count, 0)
        self.assertEqual(info.current_index, self.end_index)
        # self.assertEqual(info.original_start_index, 10)
        self.assertEqual(info.start_index, self.start_index)
        self.assertEqual(info.end_index, self.end_index)
        mutations_tested = info.current_index - info.start_index
        self.assertEqual(mutations_tested, self.end_index - self.start_index)

    def testStartingFromStartIndex(self):
        start_index = self.model.num_mutations() - 2
        self.fuzzer.set_range(start_index)
        self.fuzzer.start()

        info = self.fuzzer._get_session_info()
        self.assertEqual(info.current_index, self.model.last_index())
        self.assertEqual(info.end_index, self.model.last_index())

    def testEndingAtEndIndex(self):
        start_index = 0
        end_index = 3
        self.fuzzer.set_range(start_index, end_index)
        self.fuzzer.start()

        info = self.fuzzer._get_session_info()
        self.assertEqual(info.start_index, 0)
        self.assertEqual(info.end_index, 3)
        self.assertEqual(info.current_index, 3)

    def testFullMutationRange(self):
        self.fuzzer.set_range()
        self.fuzzer.start()

        info = self.fuzzer._get_session_info()
        self.assertEqual(info.start_index, 0)
        self.assertEqual(info.end_index, self.model.last_index())
        self.assertEqual(info.current_index, self.model.last_index())

    def _MOVE_TO_TARGET_TESTS_test_send_failure(self):
        config = {
            '12': {
                'send': {"raise exception": True}
            }
        }
        send_error_target = ServerTargetMock(config, logger=self.logger)
        self.fuzzer.set_target(send_error_target)
        self.fuzzer.start()
        info = self.fuzzer._get_session_info()
        reports = self.fuzzer._get_reports_manager()
        self.assertEqual(len(reports), 1)
        self.assertTrue(12 in reports)
        self.assertEqual(info.failure_count, 1)

    def testTestFailedWhenReportIsFailed(self):
        config = {
            '13': {
                'report': {
                    'status': 'failed', 'reason': 'failure reason'
                }
            }
        }
        target = ServerTargetMock(config, logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        info = self.fuzzer._get_session_info()
        reports = self.fuzzer.dataman.get_report_test_ids()
        self.assertEqual(reports, [int(x) for x in config.keys()])
        self.assertEqual(info.failure_count, len(config))

    def testAllFailedTestsHaveReports(self):
        config = {
            '10': {'report': {'status': 'failed', 'reason': 'failure reason'}},
            '11': {'report': {'status': 'failed', 'reason': 'failure reason'}},
            '12': {'report': {'status': 'failed', 'reason': 'failure reason'}},
            '13': {'report': {'status': 'failed', 'reason': 'failure reason'}}
        }
        target = ServerTargetMock(config, logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        info = self.fuzzer._get_session_info()
        reports = self.fuzzer.dataman.get_report_test_ids()
        self.assertEqual(reports, sorted([int(x) for x in config.keys()]))
        self.assertEqual(info.failure_count, len(config))

    def testStoringAllReportsWhenStoreAllReportsIsSetToTrue(self):
        config = {}
        target = ServerTargetMock(config, logger=self.logger)
        self.fuzzer.set_store_all_reports(True)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        info = self.fuzzer._get_session_info()
        reports = self.fuzzer.dataman.get_report_test_ids()
        expected_mutation_count = self.end_index - self.start_index + 1
        expected_failure_count = 0
        self.assertEqual(len(reports), expected_mutation_count)
        self.assertEqual(info.failure_count, expected_failure_count)

    def testOnlyTestsInSetRangeAreExecuted(self):
        start_index = self.model.num_mutations() - 5
        self.model.connect(self.t_str, self.t_int)
        expected_end_index = self.model.last_index()
        expected_num_mutations = expected_end_index - start_index
        self.fuzzer.set_range(start_index)
        self.fuzzer.start()
        info = self.fuzzer._get_session_info()
        self.assertEqual(info.failure_count, 0)
        self.assertEqual(info.current_index, expected_end_index)
        mutations_tested = info.current_index - info.start_index
        self.assertEqual(mutations_tested, expected_num_mutations)
        self.assertEqual(info.start_index, start_index)
        self.assertEqual(info.end_index, expected_end_index)

    def testCallbackIsCalledBetweenTwoNodes(self):
        template1 = Template(name='template1', fields=String('str1'))
        template2 = Template(name='template2', fields=String('str2'))
        self.cb_call_count = 0

        def t1_t2_cb(fuzzer, edge, response):
            self.assertEqual(fuzzer, self.fuzzer)
            self.assertEqual(edge.src, template1)
            self.assertEqual(edge.dst, template2)
            self.cb_call_count += 1

        model = GraphModel()
        model.logger = self.logger
        model.connect(template1)
        model.connect(template1, template2, t1_t2_cb)
        self.model = model
        self.fuzzer.set_model(model)
        self.fuzzer.set_range()
        self.fuzzer.start()
        self.assertEqual(template2.num_mutations(), self.cb_call_count)

    def testCorrectCallbackIsCalledForEachEdge(self):
        template1 = Template(name='template1', fields=String('str1'))
        template2 = Template(name='template2', fields=String('str2'))
        template3 = Template(name='template3', fields=String('str3'))
        self.cb2_call_count = 0
        self.cb3_call_count = 0

        def t1_t2_cb(fuzzer, edge, response):
            self.assertEqual(fuzzer, self.fuzzer)
            self.assertEqual(edge.src, template1)
            self.assertEqual(edge.dst, template2)
            self.cb2_call_count += 1

        def t1_t3_cb(fuzzer, edge, response):
            self.assertEqual(fuzzer, self.fuzzer)
            self.assertEqual(edge.src, template1)
            self.assertEqual(edge.dst, template3)
            self.cb3_call_count += 1

        model = GraphModel()
        model.logger = self.logger
        model.connect(template1)
        model.connect(template1, template2, t1_t2_cb)
        model.connect(template1, template3, t1_t3_cb)
        self.model = model
        self.fuzzer.set_model(model)
        self.fuzzer.set_range()
        self.fuzzer.start()
        self.assertEqual(template2.num_mutations(), self.cb2_call_count)
        self.assertEqual(template3.num_mutations(), self.cb3_call_count)

    def testCorrectCallbackIsCalledForAllEdgesInPath(self):
        template1 = Template(name='template1', fields=String('str1'))
        template2 = Template(name='template2', fields=String('str2'))
        template3 = Template(name='template3', fields=String('str3'))
        self.cb2_call_count = 0
        self.cb3_call_count = 0

        def t1_t2_cb(fuzzer, edge, response):
            self.assertEqual(fuzzer, self.fuzzer)
            self.assertEqual(edge.src, template1)
            self.assertEqual(edge.dst, template2)
            self.cb2_call_count += 1

        def t2_t3_cb(fuzzer, edge, response):
            self.assertEqual(fuzzer, self.fuzzer)
            self.assertEqual(edge.src, template2)
            self.assertEqual(edge.dst, template3)
            self.cb3_call_count += 1

        model = GraphModel()
        model.logger = self.logger
        model.connect(template1)
        model.connect(template1, template2, t1_t2_cb)
        model.connect(template2, template3, t2_t3_cb)
        self.model = model
        self.fuzzer.set_model(model)
        self.fuzzer.set_range()
        self.fuzzer.start()
        self.assertEqual(template2.num_mutations() + template3.num_mutations(), self.cb2_call_count)
        self.assertEqual(template3.num_mutations(), self.cb3_call_count)
class TestClientFuzzer(unittest.TestCase):

    def setUp(self):
        self.logger = get_test_logger()
        self.logger.debug('TESTING METHOD: %s', self._testMethodName)
        self._default_stage = 'simple_str_template'

        self.t_str = Template(name=self._default_stage, fields=[String(name='str1', value='kitty')])

        self.t_int = Template(name='simple_int_template', fields=[UInt32(name='int1', value=0x1234)])
        self.fuzzer = None
        self.mutations = {}
        self.prepare()

    def tearDown(self):
        if self.fuzzer:
            self.fuzzer.stop()

    def default_callback(self, test, stage, resp):
        if test not in self.mutations:
            self.mutations[test] = []
        self.mutations[test].append((stage, resp))

    def prepare(self):
        self.start_index = 10
        self.end_index = 20
        self.delay_duration = 0
        self.fuzzer = ClientFuzzer(name="TestServerFuzzer", logger=self.logger)

        self.interface = EmptyInterface()
        self.fuzzer.set_interface(self.interface)

        self.model = GraphModel()
        self.model.logger = self.logger

        self.model.connect(self.t_str)
        self.fuzzer.set_model(self.model)

        self.default_config = {
            'always': {
                'trigger': {
                    'fuzzer': self.fuzzer,
                    'stages': [
                        (self._default_stage, {})
                    ]
                }
            }
        }
        self.target = ClientTargetMock(self.default_config, self.default_callback, logger=self.logger)
        self.fuzzer.set_target(self.target)

        self.fuzzer.set_range(self.start_index, self.end_index)
        self.fuzzer.set_delay_between_tests(self.delay_duration)

    def testRaisesExceptionWhenStartedWithoutModel(self):

        self.fuzzer.set_model(None)
        self.assertRaises(AssertionError, self.fuzzer.start)
        self.fuzzer = None

    def testRaisesExceptionWhenStartedWithoutTarget(self):
        self.fuzzer.set_target(None)
        self.assertRaises(AssertionError, self.fuzzer.start)
        self.fuzzer = None

    def testRaisesExceptionWhenStartedWithoutInterface(self):
        self.fuzzer.set_interface(None)
        self.assertRaises(AssertionError, self.fuzzer.start)
        self.fuzzer = None

    def testVanilla(self):
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        info = self.fuzzer._get_session_info()
        # reports = self.fuzzer._get_reports_manager()
        # self.assertEqual(len(reports), 0)
        self.assertEqual(info.failure_count, 0)
        self.assertEqual(info.current_index, None)
        # self.assertEqual(info.original_start_index, 10)
        self.assertEqual(info.start_index, self.start_index)
        self.assertEqual(info.end_index, self.end_index)

    def testStartingFromStartIndex(self):
        start_index = self.model.num_mutations() - 2
        self.fuzzer.set_range(start_index)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()

        info = self.fuzzer._get_session_info()
        self.assertEqual(info.current_index, None)
        self.assertEqual(info.end_index, self.model.last_index())

    def testEndingAtEndIndex(self):
        start_index = 0
        end_index = 3
        self.fuzzer.set_range(start_index, end_index)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()

        info = self.fuzzer._get_session_info()
        self.assertEqual(info.start_index, 0)
        self.assertEqual(info.end_index, 3)
        self.assertEqual(info.current_index, None)

    def testFullMutationRange(self):
        self.fuzzer.set_range()
        self.fuzzer.start()
        self.fuzzer.wait_until_done()

        info = self.fuzzer._get_session_info()
        self.assertEqual(info.start_index, 0)
        self.assertEqual(info.end_index, self.model.last_index())
        self.assertEqual(info.current_index, None)

    def testTestFailedWhenReportIsFailed(self):
        config = {
            '13': {
                'report': {
                    'status': 'failed', 'reason': 'failure reason'
                }
            }
        }
        config.update(self.default_config)
        target = ClientTargetMock(config, self.default_callback, logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        info = self.fuzzer._get_session_info()
        reports = self.fuzzer.dataman.get_report_test_ids()
        self.assertEqual(sorted(reports), sorted([int(x) for x in config.keys() if x != 'always']))
        self.assertEqual(info.failure_count, len(config) - 1)

    def testAllFailedTestsHaveReports(self):
        config = {
            '10': {'report': {'status': 'failed', 'reason': 'failure reason'}},
            '11': {'report': {'status': 'failed', 'reason': 'failure reason'}},
            '12': {'report': {'status': 'failed', 'reason': 'failure reason'}},
            '13': {'report': {'status': 'failed', 'reason': 'failure reason'}}
        }
        config.update(self.default_config)
        target = ClientTargetMock(config, self.default_callback, logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        info = self.fuzzer._get_session_info()
        reports = self.fuzzer.dataman.get_report_test_ids()
        self.assertEqual(sorted(reports), sorted([int(x) for x in config.keys() if x != 'always']))
        self.assertEqual(info.failure_count, len(config) - 1)

    def testStoringAllReportsWhenStoreAllReportsIsSetToTrue(self):
        config = {}
        config.update(self.default_config)
        target = ClientTargetMock(config, self.default_callback, logger=self.logger)
        self.fuzzer.set_store_all_reports(True)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        info = self.fuzzer._get_session_info()
        reports = self.fuzzer.dataman.get_report_test_ids()
        expected_mutation_count = self.end_index - self.start_index + 1
        expected_failure_count = 0
        self.assertEqual(len(reports), expected_mutation_count)
        self.assertEqual(info.failure_count, expected_failure_count)

    def testOnlyTestsInSetRangeAreExecuted(self):
        start_index = self.model.num_mutations() - 5
        self.model.connect(self.t_str, self.t_int)
        expected_end_index = self.model.last_index()
        self.fuzzer.set_range(start_index)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        info = self.fuzzer._get_session_info()
        self.assertEqual(info.failure_count, 0)
        self.assertEqual(info.current_index, None)
        self.assertEqual(info.start_index, start_index)
        self.assertEqual(info.end_index, expected_end_index)

    def testGetMutationForStage(self):
        self.fuzzer.set_range(0, 1)
        config = {
            'always': {
                'trigger': {
                    'fuzzer': self.fuzzer,
                    'stages': [
                        (self._default_stage, {})
                    ]
                }
            }
        }
        target = ClientTargetMock(config, self.default_callback, logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        self.assertIn(0, self.mutations)
        self.assertEquals(self.mutations[0][0][0], self._default_stage)
        self.assertIsNotNone(self.mutations[0][0][1])

    def testGetMutationForStageTwice(self):
        self.fuzzer.set_range(0, 1)
        config = {
            'always': {
                'trigger': {
                    'fuzzer': self.fuzzer,
                    'stages': [
                        (self._default_stage, {}),
                        (self._default_stage, {})
                    ]
                }
            }
        }
        target = ClientTargetMock(config, self.default_callback, logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        self.assertIn(0, self.mutations)
        self.assertEquals(self.mutations[0][0][0], self._default_stage)
        self.assertIsNotNone(self.mutations[0][0][1])
        self.assertEquals(self.mutations[0][1][0], self._default_stage)
        self.assertIsNotNone(self.mutations[0][1][1])

    def testGetMutationWrongStage(self):
        self.fuzzer.set_range(0, 1)
        wrong_stage = 'simple_str_template1'
        config = {
            'always': {
                'trigger': {
                    'fuzzer': self.fuzzer,
                    'stages': [
                        (wrong_stage, {}),
                    ]
                }
            }
        }
        target = ClientTargetMock(config, self.default_callback, logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        self.assertIn(0, self.mutations)
        self.assertEquals(self.mutations[0][0][0], wrong_stage)
        self.assertIsNone(self.mutations[0][0][1])

    def testGetMutationWrongAfterCorrectStage(self):
        self.fuzzer.set_range(0, 1)
        wrong_stage = 'simple_str_template1'
        config = {
            'always': {
                'trigger': {
                    'fuzzer': self.fuzzer,
                    'stages': [
                        (self._default_stage, {}),
                        (wrong_stage, {}),
                    ]
                }
            }
        }
        target = ClientTargetMock(config, self.default_callback, logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        self.assertIn(0, self.mutations)
        self.assertEquals(self.mutations[0][0][0], self._default_stage)
        self.assertIsNotNone(self.mutations[0][0][1])
        self.assertEquals(self.mutations[0][1][0], wrong_stage)
        self.assertIsNone(self.mutations[0][1][1])

    def testGetMutationCorrectAfterWrongStage(self):
        self.fuzzer.set_range(0, 1)
        wrong_stage = 'simple_str_template1'
        config = {
            'always': {
                'trigger': {
                    'fuzzer': self.fuzzer,
                    'stages': [
                        (wrong_stage, {}),
                        (self._default_stage, {}),
                    ]
                }
            }
        }
        target = ClientTargetMock(config, self.default_callback, logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        self.assertIn(0, self.mutations)
        self.assertEquals(self.mutations[0][0][0], wrong_stage)
        self.assertIsNone(self.mutations[0][0][1])
        self.assertEquals(self.mutations[0][1][0], self._default_stage)
        self.assertIsNotNone(self.mutations[0][1][1])

    def testGetMutationWithWildcard(self):
        self.fuzzer.set_range(0, 1)
        config = {
            'always': {
                'trigger': {
                    'fuzzer': self.fuzzer,
                    'stages': [
                        (ClientFuzzer.STAGE_ANY, {})
                    ]
                }
            }
        }
        target = ClientTargetMock(config, self.default_callback, logger=self.logger)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        self.fuzzer.wait_until_done()
        self.assertIn(0, self.mutations)
        self.assertEquals(self.mutations[0][0][0], ClientFuzzer.STAGE_ANY)
        self.assertIsNotNone(self.mutations[0][0][1])
Exemple #7
0
class GraphModelTests(unittest.TestCase):
    def setUp(self):
        self.logger = get_test_logger()
        self.logger.debug('TESTING METHOD: %s', self._testMethodName)
        self.model = GraphModel()
        self.templates = self.get_templates()
        self.todo = []

    def get_templates(self):
        res = []
        res.append(Template(name='t1', fields=[String('data1')]))
        res.append(Template(name='t2', fields=[String('data2'), UInt32(300)]))
        res.append(Template(name='t3', fields=[UInt32(400)]))
        return res

    def _check_sequences(self, expected_sequences):
        self.logger.debug('check num_mutations()')
        t_num_mutations = sum(s[-1].num_mutations()
                              for s in expected_sequences)
        m_num_mutations = self.model.num_mutations()
        self.assertEqual(t_num_mutations, m_num_mutations)
        sequences = {}
        while self.model.mutate():
            sequence = tuple(self.model.get_sequence())
            if sequence not in sequences:
                sequences[sequence] = 1
            else:
                sequences[sequence] += 1
        self.assertEqual(len(sequences), len(expected_sequences))
        self.logger.debug(
            'check that each sequence appears the appropriate number of times')
        for sequence, count in sequences.items():
            seq_templates = [e.dst for e in sequence]
            self.assertIn(seq_templates, expected_sequences)
            last = seq_templates[-1]
            last_num_mutations = last.num_mutations()
            self.assertEqual(count, last_num_mutations)

    def testSequenceSingleTemplate(self):
        t = self.templates[0]
        self.model.connect(t)
        expected_sequences = [[t]]
        self._check_sequences(expected_sequences)

    def testSequenceDirectPath(self):
        '''
        root -> t1
        '''
        self.model.connect(self.templates[0])
        for i in range(len(self.templates) - 1):
            self.model.connect(self.templates[i], self.templates[i + 1])
        expected_sequences = list(self.templates[:i + 1]
                                  for i in range(len(self.templates)))
        self._check_sequences(expected_sequences)

    def testSequenceComplexPath(self):
        '''
        root -> t1
        root -> t1 -> t2
        root -> t1 -> t3
        root -> t1 -> t2 -> t3
        '''
        self.model.connect(self.templates[0])
        self.model.connect(self.templates[0], self.templates[1])
        self.model.connect(self.templates[0], self.templates[2])
        self.model.connect(self.templates[1], self.templates[2])
        expected_sequences = [[self.templates[0]],
                              [self.templates[0], self.templates[1]],
                              [self.templates[0], self.templates[2]],
                              [
                                  self.templates[0], self.templates[1],
                                  self.templates[2]
                              ]]
        self._check_sequences(expected_sequences)

    def testMultiHeadPath(self):
        '''
        root -> t1
        root -> t2
        root -> t3
        '''
        expected_sequences = []
        for t in self.templates:
            expected_sequences.append([t])
            self.model.connect(t)
        self._check_sequences(expected_sequences)

    def _check_skip(self, to_skip, expected_skipped, expected_mutated):
        skipped = self.model.skip(to_skip)
        self.assertEqual(expected_skipped, skipped)
        mutated = 0
        while self.model.mutate():
            mutated += 1
        self.assertEqual(expected_mutated, mutated)

    def testSkipZeroSingleTemplate(self):
        self.model.connect(self.templates[0])
        m_num_mutations = self.model.num_mutations()
        to_skip = 0
        expected_skipped = to_skip
        expected_mutated = m_num_mutations
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def testSkipHalfSingleTemplate(self):
        self.model.connect(self.templates[0])
        m_num_mutations = self.model.num_mutations()
        to_skip = m_num_mutations // 2
        expected_skipped = to_skip
        expected_mutated = m_num_mutations - expected_skipped
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def testSkipExactSingleTemplate(self):
        self.model.connect(self.templates[0])
        m_num_mutations = self.model.num_mutations()
        to_skip = m_num_mutations
        expected_skipped = to_skip
        expected_mutated = m_num_mutations - expected_skipped
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def testSkipTooMuchSingleTemplate(self):
        self.model.connect(self.templates[0])
        m_num_mutations = self.model.num_mutations()
        to_skip = m_num_mutations + 10
        expected_skipped = m_num_mutations
        expected_mutated = m_num_mutations - expected_skipped
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def testSkipZeroMultiTemplate(self):
        self.model.connect(self.templates[0])
        self.model.connect(self.templates[0], self.templates[1])
        m_num_mutations = self.model.num_mutations()
        to_skip = 0
        expected_skipped = to_skip
        expected_mutated = m_num_mutations
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def testSkipHalfMultiTemplate(self):
        self.model.connect(self.templates[0])
        self.model.connect(self.templates[0], self.templates[1])
        m_num_mutations = self.model.num_mutations()
        to_skip = m_num_mutations // 2
        expected_skipped = to_skip
        expected_mutated = m_num_mutations - expected_skipped
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def testSkipExactMultiTemplate(self):
        self.model.connect(self.templates[0])
        self.model.connect(self.templates[0], self.templates[1])
        m_num_mutations = self.model.num_mutations()
        to_skip = m_num_mutations
        expected_skipped = to_skip
        expected_mutated = m_num_mutations - expected_skipped
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def testSkipTooMuchMultiTemplate(self):
        self.model.connect(self.templates[0])
        self.model.connect(self.templates[0], self.templates[1])
        m_num_mutations = self.model.num_mutations()
        to_skip = m_num_mutations + 10
        expected_skipped = m_num_mutations
        expected_mutated = m_num_mutations - expected_skipped
        self._check_skip(to_skip, expected_skipped, expected_mutated)

    def testFailureToTo(self):
        self.assertEqual(len(self.todo), 0)

    def testExceptionIfLoop(self):
        self.model.connect(self.templates[0])
        self.model.connect(self.templates[0], self.templates[1])
        self.model.connect(self.templates[1], self.templates[0])
        with self.assertRaises(KittyException):
            self.model.num_mutations()
Exemple #8
0
class TestServerFuzzer(unittest.TestCase):

    def setUp(self):
        self.logger = get_test_logger()
        self.logger.debug('TESTING METHOD: %s', self._testMethodName)

        self.t_str = Template(name='simple_str_template', fields=[String(name='str1', value='kitty')])

        self.t_int = Template(name='simple_int_template', fields=[UInt32(name='int1', value=0x1234)])
        self.fuzzer = None
        self.prepare()

    def tearDown(self):
        if self.fuzzer:
            self.fuzzer.stop()

    def prepare(self):
        self.start_index = 10
        self.end_index = 20
        self.delay_duration = 0
        self.fuzzer = ServerFuzzer(name="TestServerFuzzer", logger=self.logger)

        self.interface = EmptyInterface()
        self.fuzzer.set_interface(self.interface)

        self.model = GraphModel()

        self.model.connect(self.t_str)
        self.fuzzer.set_model(self.model)

        self.target = TargetMock({})
        self.fuzzer.set_target(self.target)

        self.fuzzer.set_range(self.start_index, self.end_index)
        self.fuzzer.set_delay_between_tests(self.delay_duration)

    def test_start_without_session(self):
        self.fuzzer.set_model(None)
        self.assertRaises(AssertionError, self.fuzzer.start)
        self.fuzzer = None

    def test_start_without_target(self):
        self.fuzzer.set_target(None)
        self.assertRaises(AssertionError, self.fuzzer.start)
        self.fuzzer = None

    def test_start_without_interface(self):
        self.fuzzer.set_interface(None)
        self.assertRaises(AssertionError, self.fuzzer.start)
        self.fuzzer = None

    def test_vanilla(self):
        self.fuzzer.start()
        info = self.fuzzer._get_session_info()
        # reports = self.fuzzer._get_reports_manager()
        # self.assertEqual(len(reports), 0)
        self.assertEqual(info.failure_count, 0)
        self.assertEqual(info.current_index, self.end_index)
        # self.assertEqual(info.original_start_index, 10)
        self.assertEqual(info.start_index, self.start_index)
        self.assertEqual(info.end_index, self.end_index)
        mutations_tested = info.current_index - info.start_index
        self.assertEqual(mutations_tested, self.end_index - self.start_index)

    def test_start_index(self):
        start_index = self.model.num_mutations() - 2
        self.fuzzer.set_range(start_index)
        self.fuzzer.start()

        info = self.fuzzer._get_session_info()
        self.assertEqual(info.current_index, self.model.last_index())
        self.assertEqual(info.end_index, self.model.last_index())

    def test_end_index(self):
        start_index = 0
        end_index = 3
        self.fuzzer.set_range(start_index, end_index)
        self.fuzzer.start()

        info = self.fuzzer._get_session_info()
        self.assertEqual(info.start_index, 0)
        self.assertEqual(info.end_index, 3)
        self.assertEqual(info.current_index, 3)

    def test_full_range(self):
        self.fuzzer.set_range()
        self.fuzzer.start()

        info = self.fuzzer._get_session_info()
        self.assertEqual(info.start_index, 0)
        self.assertEqual(info.end_index, self.model.last_index())
        self.assertEqual(info.current_index, self.model.last_index())

    def _MOVE_TO_TARGET_TESTS_test_send_failure(self):
        config = {
            '12': {
                'send': ["raise exception"]
            }
        }
        send_error_target = TargetMock(config)
        self.fuzzer.set_target(send_error_target)
        self.fuzzer.start()
        info = self.fuzzer._get_session_info()
        reports = self.fuzzer._get_reports_manager()
        self.assertEqual(len(reports), 1)
        self.assertTrue(12 in reports)
        self.assertEqual(info.failure_count, 1)

    def ___test_target_failed_is_true(self):
        config = {
            '12': {
                'report': {
                    'failed': False
                }
            },
            '13': {
                'report': {
                    'failed': True
                }
            }
        }
        target = TargetMock(config)
        self.fuzzer.set_target(target)
        self.fuzzer.start()
        info = self.fuzzer._get_session_info()
        reports = self.fuzzer._get_reports_manager()
        self.assertEqual(len(reports), 1)
        self.assertTrue(13 in reports)
        self.assertEqual(info.failure_count, 1)

    def test_set_range(self):
        start_index = self.model.num_mutations() - 5
        self.model.connect(self.t_str, self.t_int)
        expected_end_index = self.model.last_index()
        expected_num_mutations = expected_end_index - start_index
        self.fuzzer.set_range(start_index)
        self.fuzzer.start()
        info = self.fuzzer._get_session_info()
        self.assertEqual(info.failure_count, 0)
        self.assertEqual(info.current_index, expected_end_index)
        mutations_tested = info.current_index - info.start_index
        self.assertEqual(mutations_tested, expected_num_mutations)
        self.assertEqual(info.start_index, start_index)
        self.assertEqual(info.end_index, expected_end_index)