def test_split_case1(self): config = Configuration(["1", "2", "3", "4"]) expected = {Configuration(["1", "2"])} mode = execution.SplitSearch(MockVerifier(), iterative=False) conflicts = mode.run(config) self.assertEqual(expected, conflicts) config = Configuration(["1", "2", "3", "5", "9", "10", "11", "12"]) expected = {Configuration(["1", "2"]), Configuration(["3", "5"])} conflicts = mode.run(config) self.assertEqual(expected, conflicts)
def test_contains(self): self.assertTrue(Configuration(["plugin-A"]) in Configuration(("plugin-A", "plugin-B", "plugin-C", "plugin-D"))) self.assertTrue(Configuration(["plugin-A"]) in Configuration(["plugin-A"])) configs = [ Configuration(["plugin-A", "plugin-B", "plugin-C", "plugin-D"]), Configuration(["plugin-A", "plugin-B", "plugin-C"]), Configuration(["plugin-A", "plugin-B"]) ] self.assertTrue(Configuration(["plugin-A", "plugin-B"]) in configs) [self.assertTrue(Configuration(["plugin-A"]) in c) for c in configs]
def _iterative(self, conflicts, minimized, iteration=1): logging.debug(self.__remaining_plugins) for conflict in conflicts: if len(conflict) == 2: minimized.add(conflict) else: logging.info("Iterative run") seed = self.__INITIAL_SEED + iteration sub = self._search(conflict, Random(seed)) self._iterative(sub, minimized, iteration + 1) c = Configuration(self.__remaining_plugins) if self._verifier.is_conflicting(c): logging.info("Iterative run") seed = self.__INITIAL_SEED + iteration sub = self._search(c, Random(seed)) self._iterative(sub, minimized, iteration + 1)
def setUp(self): self.empty = [] self.disjoint_conflicts = { Configuration(["plugin-A", "plugin-B"]), Configuration(["plugin-D", "plugin-E"]), } self.conflicts = { Configuration(["plugin-A", "plugin-B"]), Configuration(["plugin-A", "plugin-D"]), Configuration(["plugin-B", "plugin-D"]), Configuration(["plugin-D", "plugin-E"]), }
def test_commutativity(self): plugins = ("plugin-A", "plugin-B", "plugin-C", "plugin-D") shuffler = random.Random(12345) for i in range(10): copy = [p for p in plugins] shuffler.shuffle(copy) self.assertEqual(Configuration(plugins), Configuration(copy)) c = Configuration(plugins) other = Configuration(plugins) shuffler.shuffle(other) self.assertEqual(other, c) self.assertEqual(Configuration(["1", "3"]), Configuration(["3", "1"]))
def test_iterative(self): config = Configuration(["1", "2", "3", "4", "5"]) expected = {Configuration(["1", "2"]), Configuration(["3", "5"])} mode = execution.SplitSearch(MockVerifier()) conflicts = mode.run(config) self.assertEqual(expected, conflicts)
def test_no_conflict(self): config = Configuration(["1", "3"]) expected = set({}) mode = execution.SplitSearch(MockVerifier(), iterative=False) conflicts = mode.run(config) self.assertEqual(expected, conflicts)
def test_single_pair(self): config = Configuration(["1", "2"]) expected = {config} mode = execution.SplitSearch(MockVerifier(), iterative=False) conflicts = mode.run(config) self.assertEqual(expected, conflicts)
def test_single_pair(self): config = Configuration(["1", "2"]) expected = {config} mode = execution.Pairwise(MockVerifier()) conflicts = mode.run(config) self.assertEqual(expected, conflicts)
def test_no_conflict(self): config = Configuration(["1", "3", "4"]) expected = set({}) mode = execution.Pairwise(MockVerifier()) conflicts = mode.run(config) self.assertEqual(expected, conflicts)
def test_run(self): config = Configuration(["1", "2", "3", "4", "5"]) expected = {Configuration(["1", "2"]), Configuration(["3", "5"])} mode = execution.Pairwise(MockVerifier()) conflicts = mode.run(config) self.assertEqual(expected, conflicts)
def is_conflicting(self, config): for p in {Configuration(["1", "2"]), Configuration(["3", "5"])}: if p in config: return True return False
def run(self): """ Description: PENA Runner Params: None Return: None """ if len(self.input_plugins) < 2: raise Exception( 'Plugin list invalid. The plugin list must have lenght 2 or more.' ) # deactivate plugins self.cli.deactivate(self.input_plugins) logging.info('RUNNING {}'.format(str(self.mode))) logging.info('RUNNING N={}'.format(len(self.input_plugins))) logging.info("Run Started") technnique = self.mode(self.verifier) # STEP 1 - DIMENSIONALITY REDUCTION reduced_plugins = dimensionality_reduction( self.input_plugins, self.web_driver, self.cli, skip=self.skip_dimensionality) # STEP 2 and 3 - SEARCH FOR CONFLICTS AND CLUSTERING if len(reduced_plugins) > 1: configuration = Configuration(reduced_plugins) conflicts = technnique.run(configuration) logging.info("Delta timer (in minutes): {}".format( Timer.get_delta())) if self.generate_configuration: ''' generate nodes of conflicts ''' self.generate_nodes(reduced_plugins, conflicts) return if conflicts: all_conflicts = copy.copy(conflicts) # REPORT CONFLICTS FOUND BEFORE CLEANSING logging.debug("Conflicts found after searching: {}".format( len(all_conflicts))) for conflict in all_conflicts: logging.debug("Conflict - {}".format(conflict)) changes = self.verifier.conflicting_changes(conflict) unexpected_added, unexpected_removed = changes[0], changes[ 1] if len(unexpected_added): added = [(" {}".format(line)) for line in unexpected_added] logging.info("{}: {}".format("Unexpected added", added)) if len(unexpected_removed): removed = [(" {}".format(line)) for line in unexpected_removed] logging.info("{}: {}".format("Unexpected removed", removed)) # STEP 4 - REPORT CLEANSING if self.remove_spurious: logging.info("Cleansing started") self.cleansing_data = { "non-determinism": [], "minify": [], "union_tags": [], "optional_closing": [] } temp_conflicts = copy.copy(all_conflicts) for conflict in all_conflicts: changes = self.verifier.conflicting_changes(conflict) unexpected_added, unexpected_removed, typeof_removal = Analyser( changes[0], changes[1]).run() if (not unexpected_added) and (not unexpected_removed): self.cleansing_data[typeof_removal].append( conflict) temp_conflicts.remove(conflict) else: self.verifier.update_changes( conflict, unexpected_added, unexpected_removed) remaining_conflicts = self.cleansing(temp_conflicts) self.report_cleansing_data( len(temp_conflicts) - len(remaining_conflicts)) logging.info("Cleansing finished") all_conflicts = remaining_conflicts # STEP 5 - VISUAL ORACLE if self.visual_oracle: logging.info("Checking visual conflicts started") visual_conflicts = self.get_visual_conflicts(all_conflicts) for conflict in visual_conflicts: logging.info( 'Visual conflict identified: {}'.format(conflict)) logging.info("Checking visual conflicts finished") # REPORT CONFLICTS logging.debug("===== FINAL REPORT =====") for conflict in all_conflicts: logging.debug(conflict) logging.debug("Conflicting config - {}".format(conflict)) if self.show_lines: changes = self.verifier.conflicting_changes(conflict) unexpected_added, unexpected_removed = changes[ 0], changes[1] if len(unexpected_added): added = [(" {}".format(line)) for line in unexpected_added] logging.info("{}: {}".format( "Unexpected added", added)) if len(unexpected_removed): removed = [(" {}".format(line)) for line in unexpected_removed] logging.info("{}: {}".format( "Unexpected removed", removed)) freq = check_frequency(all_conflicts) [logging.debug("{}: {}".format(k, v)) for k, v in freq.items()] self.cli.deactivate(self.input_plugins) logging.info("Run Finished!") if not self.debug: self.web_driver.cleanup()
def test_reflexivity(self): self.assertEqual(Configuration(["plugin-A"]), Configuration(["plugin-A"]))
def test_difference(self): c1 = Configuration(["plugin-A", "plugin-B", "plugin-C", "plugin-D"]) c2 = Configuration(["plugin-A"]) self.assertEqual(Configuration(["plugin-B", "plugin-C", "plugin-D"]), c1.difference(c2))
def test_immutability(self): plugins = ["plugin-A"] c = Configuration(plugins) plugins.pop() self.assertEqual(len(c), 1) self.assertFalse(len(plugins))