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 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()