| koder aka kdanilov | 108ac36 | 2017-01-19 20:17:16 +0200 | [diff] [blame] | 1 | import abc | 
| kdanylov aka koder | b083333 | 2017-05-13 20:39:17 +0300 | [diff] [blame] | 2 | from typing import Dict, List, Any, Tuple, cast, Type, Iterator, Union | 
| koder aka kdanilov | f286517 | 2016-12-30 03:35:11 +0200 | [diff] [blame] | 3 |  | 
| kdanylov aka koder | b083333 | 2017-05-13 20:39:17 +0300 | [diff] [blame] | 4 | from cephlib.numeric_types import TimeSeries, DataSource | 
|  | 5 | from cephlib.statistic import StatProps | 
|  | 6 | from cephlib.istorage import IImagesStorage, Storable, ISensorStorage | 
| kdanylov aka koder | 026e5f2 | 2017-05-15 01:04:39 +0300 | [diff] [blame] | 7 | from cephlib.node import NodeInfo | 
|  | 8 | from cephlib.node_impl import IRPCNode | 
| koder aka kdanilov | ffaf48d | 2016-12-27 02:25:29 +0200 | [diff] [blame] | 9 |  | 
| koder aka kdanilov | f90de85 | 2017-01-20 18:12:27 +0200 | [diff] [blame] | 10 | from .suits.job import JobConfig | 
| koder aka kdanilov | 7022706 | 2016-11-26 23:23:21 +0200 | [diff] [blame] | 11 |  | 
|  | 12 |  | 
| koder aka kdanilov | f90de85 | 2017-01-20 18:12:27 +0200 | [diff] [blame] | 13 | class SuiteConfig(Storable): | 
| koder aka kdanilov | f286517 | 2016-12-30 03:35:11 +0200 | [diff] [blame] | 14 | """ | 
|  | 15 | Test suite input configuration. | 
|  | 16 |  | 
|  | 17 | test_type - test type name | 
|  | 18 | params - parameters from yaml file for this test | 
|  | 19 | run_uuid - UUID to be used to create file names & Co | 
|  | 20 | nodes - nodes to run tests on | 
|  | 21 | remote_dir - directory on nodes to be used for local files | 
|  | 22 | """ | 
| koder aka kdanilov | f90de85 | 2017-01-20 18:12:27 +0200 | [diff] [blame] | 23 | __ignore_fields__ = ['nodes', 'run_uuid', 'remote_dir'] | 
|  | 24 |  | 
| koder aka kdanilov | f286517 | 2016-12-30 03:35:11 +0200 | [diff] [blame] | 25 | def __init__(self, | 
|  | 26 | test_type: str, | 
|  | 27 | params: Dict[str, Any], | 
|  | 28 | run_uuid: str, | 
|  | 29 | nodes: List[IRPCNode], | 
| koder aka kdanilov | 108ac36 | 2017-01-19 20:17:16 +0200 | [diff] [blame] | 30 | remote_dir: str, | 
| koder aka kdanilov | a732a60 | 2017-02-01 20:29:56 +0200 | [diff] [blame] | 31 | idx: int, | 
|  | 32 | keep_raw_files: bool) -> None: | 
| koder aka kdanilov | f286517 | 2016-12-30 03:35:11 +0200 | [diff] [blame] | 33 | self.test_type = test_type | 
|  | 34 | self.params = params | 
|  | 35 | self.run_uuid = run_uuid | 
|  | 36 | self.nodes = nodes | 
| koder aka kdanilov | 108ac36 | 2017-01-19 20:17:16 +0200 | [diff] [blame] | 37 | self.nodes_ids = [node.node_id for node in nodes] | 
| koder aka kdanilov | f286517 | 2016-12-30 03:35:11 +0200 | [diff] [blame] | 38 | self.remote_dir = remote_dir | 
| koder aka kdanilov | a732a60 | 2017-02-01 20:29:56 +0200 | [diff] [blame] | 39 | self.keep_raw_files = keep_raw_files | 
|  | 40 |  | 
|  | 41 | if 'load' in self.params: | 
|  | 42 | self.storage_id = "{}_{}_{}".format(self.test_type, self.params['load'], idx) | 
|  | 43 | else: | 
|  | 44 | self.storage_id = "{}_{}".format(self.test_type, idx) | 
| koder aka kdanilov | f286517 | 2016-12-30 03:35:11 +0200 | [diff] [blame] | 45 |  | 
| koder aka kdanilov | 108ac36 | 2017-01-19 20:17:16 +0200 | [diff] [blame] | 46 | def __eq__(self, o: object) -> bool: | 
|  | 47 | if type(o) is not self.__class__: | 
|  | 48 | return False | 
|  | 49 |  | 
| koder aka kdanilov | f90de85 | 2017-01-20 18:12:27 +0200 | [diff] [blame] | 50 | other = cast(SuiteConfig, o) | 
| koder aka kdanilov | 108ac36 | 2017-01-19 20:17:16 +0200 | [diff] [blame] | 51 |  | 
| koder aka kdanilov | f286517 | 2016-12-30 03:35:11 +0200 | [diff] [blame] | 52 | return (self.test_type == other.test_type and | 
|  | 53 | self.params == other.params and | 
|  | 54 | set(self.nodes_ids) == set(other.nodes_ids)) | 
|  | 55 |  | 
| koder aka kdanilov | f286517 | 2016-12-30 03:35:11 +0200 | [diff] [blame] | 56 |  | 
| koder aka kdanilov | f286517 | 2016-12-30 03:35:11 +0200 | [diff] [blame] | 57 | # (node_name, source_dev, metric_name) => metric_results | 
|  | 58 | JobMetrics = Dict[Tuple[str, str, str], TimeSeries] | 
| koder aka kdanilov | f286517 | 2016-12-30 03:35:11 +0200 | [diff] [blame] | 59 | JobStatMetrics = Dict[Tuple[str, str, str], StatProps] | 
|  | 60 |  | 
|  | 61 |  | 
| koder aka kdanilov | f90de85 | 2017-01-20 18:12:27 +0200 | [diff] [blame] | 62 | class JobResult: | 
| koder aka kdanilov | f286517 | 2016-12-30 03:35:11 +0200 | [diff] [blame] | 63 | """Contains done test job information""" | 
|  | 64 |  | 
|  | 65 | def __init__(self, | 
| koder aka kdanilov | f90de85 | 2017-01-20 18:12:27 +0200 | [diff] [blame] | 66 | info: JobConfig, | 
| koder aka kdanilov | f286517 | 2016-12-30 03:35:11 +0200 | [diff] [blame] | 67 | begin_time: int, | 
|  | 68 | end_time: int, | 
|  | 69 | raw: JobMetrics) -> None: | 
| koder aka kdanilov | ffaf48d | 2016-12-27 02:25:29 +0200 | [diff] [blame] | 70 | self.info = info | 
| koder aka kdanilov | f286517 | 2016-12-30 03:35:11 +0200 | [diff] [blame] | 71 | self.run_interval = (begin_time, end_time) | 
|  | 72 | self.raw = raw  # type: JobMetrics | 
|  | 73 | self.processed = None  # type: JobStatMetrics | 
| koder aka kdanilov | 108ac36 | 2017-01-19 20:17:16 +0200 | [diff] [blame] | 74 |  | 
|  | 75 |  | 
| kdanylov aka koder | 026e5f2 | 2017-05-15 01:04:39 +0300 | [diff] [blame] | 76 | class IWallyStorage(ISensorStorage, IImagesStorage, metaclass=abc.ABCMeta): | 
| kdanylov aka koder | cdfcdaf | 2017-04-29 10:03:39 +0300 | [diff] [blame] | 77 |  | 
|  | 78 | @abc.abstractmethod | 
| kdanylov aka koder | 84de1e4 | 2017-05-22 14:00:07 +0300 | [diff] [blame] | 79 | def flush(self) -> None: | 
|  | 80 | pass | 
|  | 81 |  | 
|  | 82 | @abc.abstractmethod | 
| koder aka kdanilov | f90de85 | 2017-01-20 18:12:27 +0200 | [diff] [blame] | 83 | def put_or_check_suite(self, suite: SuiteConfig) -> None: | 
| koder aka kdanilov | 108ac36 | 2017-01-19 20:17:16 +0200 | [diff] [blame] | 84 | pass | 
|  | 85 |  | 
|  | 86 | @abc.abstractmethod | 
| koder aka kdanilov | f90de85 | 2017-01-20 18:12:27 +0200 | [diff] [blame] | 87 | def put_job(self, suite: SuiteConfig, job: JobConfig) -> None: | 
| koder aka kdanilov | 108ac36 | 2017-01-19 20:17:16 +0200 | [diff] [blame] | 88 | pass | 
|  | 89 |  | 
|  | 90 | @abc.abstractmethod | 
| koder aka kdanilov | 108ac36 | 2017-01-19 20:17:16 +0200 | [diff] [blame] | 91 | def put_extra(self, data: bytes, source: DataSource) -> None: | 
|  | 92 | pass | 
|  | 93 |  | 
|  | 94 | @abc.abstractmethod | 
|  | 95 | def put_stat(self, data: StatProps, source: DataSource) -> None: | 
|  | 96 | pass | 
|  | 97 |  | 
|  | 98 | @abc.abstractmethod | 
|  | 99 | def get_stat(self, stat_cls: Type[StatProps], source: DataSource) -> StatProps: | 
|  | 100 | pass | 
|  | 101 |  | 
|  | 102 | @abc.abstractmethod | 
| koder aka kdanilov | f90de85 | 2017-01-20 18:12:27 +0200 | [diff] [blame] | 103 | def iter_suite(self, suite_type: str = None) -> Iterator[SuiteConfig]: | 
| koder aka kdanilov | 108ac36 | 2017-01-19 20:17:16 +0200 | [diff] [blame] | 104 | pass | 
|  | 105 |  | 
|  | 106 | @abc.abstractmethod | 
| koder aka kdanilov | f90de85 | 2017-01-20 18:12:27 +0200 | [diff] [blame] | 107 | def iter_job(self, suite: SuiteConfig) -> Iterator[JobConfig]: | 
| koder aka kdanilov | 108ac36 | 2017-01-19 20:17:16 +0200 | [diff] [blame] | 108 | pass | 
|  | 109 |  | 
| koder aka kdanilov | 108ac36 | 2017-01-19 20:17:16 +0200 | [diff] [blame] | 110 | # return path to file to be inserted into report | 
|  | 111 | @abc.abstractmethod | 
|  | 112 | def put_plot_file(self, data: bytes, source: DataSource) -> str: | 
|  | 113 | pass | 
| kdanylov aka koder | b083333 | 2017-05-13 20:39:17 +0300 | [diff] [blame] | 114 |  | 
|  | 115 | @abc.abstractmethod | 
|  | 116 | def get_job_info(self, suite: SuiteConfig, job: JobConfig, key: str) -> Any: | 
|  | 117 | pass | 
|  | 118 |  | 
|  | 119 | @abc.abstractmethod | 
|  | 120 | def get_ts(self, ds: DataSource) -> TimeSeries: | 
|  | 121 | pass | 
|  | 122 |  | 
|  | 123 | @abc.abstractmethod | 
|  | 124 | def put_ts(self, ts: TimeSeries) -> None: | 
|  | 125 | pass | 
|  | 126 |  | 
|  | 127 | @abc.abstractmethod | 
|  | 128 | def iter_ts(self, **ds_parts) -> Iterator[DataSource]: | 
|  | 129 | pass | 
|  | 130 |  | 
|  | 131 | @abc.abstractmethod | 
|  | 132 | def put_job_info(self, suite: SuiteConfig, job: JobConfig, key: str, data: Any) -> None: | 
|  | 133 | pass | 
|  | 134 |  | 
|  | 135 | @abc.abstractmethod | 
| kdanylov aka koder | 026e5f2 | 2017-05-15 01:04:39 +0300 | [diff] [blame] | 136 | def load_nodes(self) -> List[NodeInfo]: | 
| kdanylov aka koder | b083333 | 2017-05-13 20:39:17 +0300 | [diff] [blame] | 137 | pass |