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_ciimport random
61cb0ef41Sopenharmony_cifrom collections import defaultdict
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_cifrom . import base
91cb0ef41Sopenharmony_cifrom ..utils import random_utils
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ciclass SeedProc(base.TestProcProducer):
131cb0ef41Sopenharmony_ci  def __init__(self, count, seed=None, parallel_subtests=1):
141cb0ef41Sopenharmony_ci    """
151cb0ef41Sopenharmony_ci    Args:
161cb0ef41Sopenharmony_ci      count: How many subtests with different seeds to create for each test.
171cb0ef41Sopenharmony_ci        0 means infinite.
181cb0ef41Sopenharmony_ci      seed: seed to use. None means random seed for each subtest.
191cb0ef41Sopenharmony_ci      parallel_subtests: How many subtest of each test to run at the same time.
201cb0ef41Sopenharmony_ci    """
211cb0ef41Sopenharmony_ci    super(SeedProc, self).__init__('Seed')
221cb0ef41Sopenharmony_ci    self._count = count
231cb0ef41Sopenharmony_ci    self._seed = seed
241cb0ef41Sopenharmony_ci    self._last_idx = defaultdict(int)
251cb0ef41Sopenharmony_ci    self._todo = defaultdict(int)
261cb0ef41Sopenharmony_ci    self._parallel_subtests = parallel_subtests
271cb0ef41Sopenharmony_ci    if count:
281cb0ef41Sopenharmony_ci      self._parallel_subtests = min(self._parallel_subtests, count)
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  def setup(self, requirement=base.DROP_RESULT):
311cb0ef41Sopenharmony_ci    super(SeedProc, self).setup(requirement)
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci    # SeedProc is optimized for dropping the result
341cb0ef41Sopenharmony_ci    assert requirement == base.DROP_RESULT
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci  def _next_test(self, test):
371cb0ef41Sopenharmony_ci    is_loaded = False
381cb0ef41Sopenharmony_ci    for _ in range(0, self._parallel_subtests):
391cb0ef41Sopenharmony_ci      is_loaded |= self._try_send_next_test(test)
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci    return is_loaded
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci  def _result_for(self, test, subtest, result):
441cb0ef41Sopenharmony_ci    self._todo[test.procid] -= 1
451cb0ef41Sopenharmony_ci    if not self._try_send_next_test(test):
461cb0ef41Sopenharmony_ci      if not self._todo.get(test.procid):
471cb0ef41Sopenharmony_ci        del self._last_idx[test.procid]
481cb0ef41Sopenharmony_ci        del self._todo[test.procid]
491cb0ef41Sopenharmony_ci        self._send_result(test, None)
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci  def _try_send_next_test(self, test):
521cb0ef41Sopenharmony_ci    def create_subtest(idx):
531cb0ef41Sopenharmony_ci      seed = self._seed or random_utils.random_seed()
541cb0ef41Sopenharmony_ci      return self._create_subtest(test, idx, random_seed=seed)
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci    num = self._last_idx[test.procid]
571cb0ef41Sopenharmony_ci    if not self._count or num < self._count:
581cb0ef41Sopenharmony_ci      num += 1
591cb0ef41Sopenharmony_ci      self._todo[test.procid] += 1
601cb0ef41Sopenharmony_ci      self._last_idx[test.procid] = num
611cb0ef41Sopenharmony_ci      return self._send_test(create_subtest(num))
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci    return False
64