1# Copyright 2018 the V8 project authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import random 6from collections import defaultdict 7 8from . import base 9from ..utils import random_utils 10 11 12class SeedProc(base.TestProcProducer): 13 def __init__(self, count, seed=None, parallel_subtests=1): 14 """ 15 Args: 16 count: How many subtests with different seeds to create for each test. 17 0 means infinite. 18 seed: seed to use. None means random seed for each subtest. 19 parallel_subtests: How many subtest of each test to run at the same time. 20 """ 21 super(SeedProc, self).__init__('Seed') 22 self._count = count 23 self._seed = seed 24 self._last_idx = defaultdict(int) 25 self._todo = defaultdict(int) 26 self._parallel_subtests = parallel_subtests 27 if count: 28 self._parallel_subtests = min(self._parallel_subtests, count) 29 30 def setup(self, requirement=base.DROP_RESULT): 31 super(SeedProc, self).setup(requirement) 32 33 # SeedProc is optimized for dropping the result 34 assert requirement == base.DROP_RESULT 35 36 def _next_test(self, test): 37 is_loaded = False 38 for _ in range(0, self._parallel_subtests): 39 is_loaded |= self._try_send_next_test(test) 40 41 return is_loaded 42 43 def _result_for(self, test, subtest, result): 44 self._todo[test.procid] -= 1 45 if not self._try_send_next_test(test): 46 if not self._todo.get(test.procid): 47 del self._last_idx[test.procid] 48 del self._todo[test.procid] 49 self._send_result(test, None) 50 51 def _try_send_next_test(self, test): 52 def create_subtest(idx): 53 seed = self._seed or random_utils.random_seed() 54 return self._create_subtest(test, idx, random_seed=seed) 55 56 num = self._last_idx[test.procid] 57 if not self._count or num < self._count: 58 num += 1 59 self._todo[test.procid] += 1 60 self._last_idx[test.procid] = num 61 return self._send_test(create_subtest(num)) 62 63 return False 64