• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2023 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5from __future__ import annotations
6
7import abc
8import datetime as dt
9import logging
10from typing import TYPE_CHECKING, Sequence
11
12from crossbench.path import safe_filename
13
14if TYPE_CHECKING:
15  from crossbench.runner.run import Run
16  from crossbench.types import JsonDict
17
18
19class Story(abc.ABC):
20  @classmethod
21  @abc.abstractmethod
22  def all_story_names(cls) -> Sequence[str]:
23    pass
24
25  def __init__(self,
26               name: str,
27               duration: dt.timedelta = dt.timedelta(seconds=15)):
28    assert name, "Invalid page name"
29    self._name = safe_filename(name)
30    self._duration = duration
31    if self._duration:
32      assert self._duration.total_seconds() > 0, (
33          f"Duration must be non-empty, but got: {duration}")
34
35  @property
36  def name(self) -> str:
37    return self._name
38
39  @property
40  def duration(self) -> dt.timedelta:
41    return self._duration
42
43  def details_json(self) -> JsonDict:
44    return {"name": self.name, "duration": self.duration.total_seconds()}
45
46  def log_run_details(self, run: Run) -> None:
47    logging.info("STORY:          %s", self)
48    timing = run.timing
49    logging.info("STORY DURATION: expected=%s timeout=%s",
50                 timing.timedelta(self.duration),
51                 timing.timeout_timedelta(self.duration))
52
53  def setup(self, run: Run) -> None:
54    """Setup work for a story that is not part of the main workload should
55    be put in this method. Probes can skip measuring this section.
56    i.e selecting substories to run.
57    """
58
59  @abc.abstractmethod
60  def run(self, run: Run) -> None:
61    """The main workload of a story that is measured by all Probes.
62    """
63
64  def teardown(self, run: Run) -> None:
65    """Cleanup work for a story that is not part of the main workload should
66    be put in this method. Probes can skip measuring this section.
67    """
68
69  def __str__(self) -> str:
70    return f"Story(name={self.name})"
71