11cb0ef41Sopenharmony_ci# Copyright 2018 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci# found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_cifrom collections import defaultdict 61cb0ef41Sopenharmony_ciimport time 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_cifrom . import base 91cb0ef41Sopenharmony_cifrom ..objects import testcase 101cb0ef41Sopenharmony_cifrom ..outproc import base as outproc 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ciclass CombinerProc(base.TestProc): 131cb0ef41Sopenharmony_ci def __init__(self, rng, min_group_size, max_group_size, count): 141cb0ef41Sopenharmony_ci """ 151cb0ef41Sopenharmony_ci Args: 161cb0ef41Sopenharmony_ci rng: random number generator 171cb0ef41Sopenharmony_ci min_group_size: minimum number of tests to combine 181cb0ef41Sopenharmony_ci max_group_size: maximum number of tests to combine 191cb0ef41Sopenharmony_ci count: how many tests to generate. 0 means infinite running 201cb0ef41Sopenharmony_ci """ 211cb0ef41Sopenharmony_ci super(CombinerProc, self).__init__() 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ci self._rng = rng 241cb0ef41Sopenharmony_ci self._min_size = min_group_size 251cb0ef41Sopenharmony_ci self._max_size = max_group_size 261cb0ef41Sopenharmony_ci self._count = count 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci # Index of the last generated test 291cb0ef41Sopenharmony_ci self._current_num = 0 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci # {suite name: instance of TestGroups} 321cb0ef41Sopenharmony_ci self._groups = defaultdict(TestGroups) 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci # {suite name: instance of TestCombiner} 351cb0ef41Sopenharmony_ci self._combiners = {} 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci def setup(self, requirement=base.DROP_RESULT): 381cb0ef41Sopenharmony_ci # Combiner is not able to pass results (even as None) to the previous 391cb0ef41Sopenharmony_ci # processor. 401cb0ef41Sopenharmony_ci assert requirement == base.DROP_RESULT 411cb0ef41Sopenharmony_ci self._next_proc.setup(base.DROP_RESULT) 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci def next_test(self, test): 441cb0ef41Sopenharmony_ci group_key = self._get_group_key(test) 451cb0ef41Sopenharmony_ci if not group_key: 461cb0ef41Sopenharmony_ci # Test not suitable for combining 471cb0ef41Sopenharmony_ci return False 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci self._groups[test.suite.name].add_test(group_key, test) 501cb0ef41Sopenharmony_ci return True 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci def _get_group_key(self, test): 531cb0ef41Sopenharmony_ci combiner = self._get_combiner(test.suite) 541cb0ef41Sopenharmony_ci if not combiner: 551cb0ef41Sopenharmony_ci print ('>>> Warning: There is no combiner for %s testsuite' % 561cb0ef41Sopenharmony_ci test.suite.name) 571cb0ef41Sopenharmony_ci return None 581cb0ef41Sopenharmony_ci return combiner.get_group_key(test) 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci def result_for(self, test, result): 611cb0ef41Sopenharmony_ci self._send_next_test() 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci def generate_initial_tests(self, num=1): 641cb0ef41Sopenharmony_ci for _ in range(0, num): 651cb0ef41Sopenharmony_ci self._send_next_test() 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci def _send_next_test(self): 681cb0ef41Sopenharmony_ci if self.is_stopped: 691cb0ef41Sopenharmony_ci return False 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci if self._count and self._current_num >= self._count: 721cb0ef41Sopenharmony_ci return False 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci combined_test = self._create_new_test() 751cb0ef41Sopenharmony_ci if not combined_test: 761cb0ef41Sopenharmony_ci # Not enough tests 771cb0ef41Sopenharmony_ci return False 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci return self._send_test(combined_test) 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci def _create_new_test(self): 821cb0ef41Sopenharmony_ci suite, combiner = self._select_suite() 831cb0ef41Sopenharmony_ci groups = self._groups[suite] 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci max_size = self._rng.randint(self._min_size, self._max_size) 861cb0ef41Sopenharmony_ci sample = groups.sample(self._rng, max_size) 871cb0ef41Sopenharmony_ci if not sample: 881cb0ef41Sopenharmony_ci return None 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci self._current_num += 1 911cb0ef41Sopenharmony_ci return combiner.combine('%s-%d' % (suite, self._current_num), sample) 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci def _select_suite(self): 941cb0ef41Sopenharmony_ci """Returns pair (suite name, combiner).""" 951cb0ef41Sopenharmony_ci selected = self._rng.randint(0, len(self._groups) - 1) 961cb0ef41Sopenharmony_ci for n, suite in enumerate(self._groups): 971cb0ef41Sopenharmony_ci if n == selected: 981cb0ef41Sopenharmony_ci return suite, self._combiners[suite] 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci def _get_combiner(self, suite): 1011cb0ef41Sopenharmony_ci combiner = self._combiners.get(suite.name) 1021cb0ef41Sopenharmony_ci if not combiner: 1031cb0ef41Sopenharmony_ci combiner = suite.get_test_combiner() 1041cb0ef41Sopenharmony_ci self._combiners[suite.name] = combiner 1051cb0ef41Sopenharmony_ci return combiner 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ciclass TestGroups(object): 1091cb0ef41Sopenharmony_ci def __init__(self): 1101cb0ef41Sopenharmony_ci self._groups = defaultdict(list) 1111cb0ef41Sopenharmony_ci self._keys = [] 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci def add_test(self, key, test): 1141cb0ef41Sopenharmony_ci self._groups[key].append(test) 1151cb0ef41Sopenharmony_ci self._keys.append(key) 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci def sample(self, rng, max_size): 1181cb0ef41Sopenharmony_ci # Not enough tests 1191cb0ef41Sopenharmony_ci if not self._groups: 1201cb0ef41Sopenharmony_ci return None 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci group_key = rng.choice(self._keys) 1231cb0ef41Sopenharmony_ci tests = self._groups[group_key] 1241cb0ef41Sopenharmony_ci return [rng.choice(tests) for _ in range(0, max_size)] 125