hardpy 0.19.1__py3-none-any.whl → 0.20.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hardpy/__init__.py +9 -0
- hardpy/cli/cli.py +29 -0
- hardpy/common/config.py +19 -0
- hardpy/hardpy_panel/api.py +62 -1
- hardpy/hardpy_panel/frontend/dist/assets/{allPaths-C_-7WXHD.js → allPaths-CLpOX_m7.js} +1 -1
- hardpy/hardpy_panel/frontend/dist/assets/{allPathsLoader-DgH0Xily.js → allPathsLoader-BZScMaOY.js} +2 -2
- hardpy/hardpy_panel/frontend/dist/assets/{browser-ponyfill-BbOvdqIF.js → browser-ponyfill-BTcpcLno.js} +1 -1
- hardpy/hardpy_panel/frontend/dist/assets/{index-DEJb2W0B.js → index-1i9Rm0C7.js} +189 -322
- hardpy/hardpy_panel/frontend/dist/assets/index-DN3Ur-pw.css +1 -0
- hardpy/hardpy_panel/frontend/dist/assets/{splitPathsBySizeLoader-o5HCcdVL.js → splitPathsBySizeLoader-CfM4kXSA.js} +1 -1
- hardpy/hardpy_panel/frontend/dist/index.html +2 -2
- hardpy/pytest_hardpy/db/__init__.py +0 -2
- hardpy/pytest_hardpy/db/runstore.py +378 -10
- hardpy/pytest_hardpy/db/statestore.py +390 -5
- hardpy/pytest_hardpy/db/tempstore.py +219 -17
- hardpy/pytest_hardpy/plugin.py +2 -2
- hardpy/pytest_hardpy/result/__init__.py +2 -0
- hardpy/pytest_hardpy/result/report_loader/json_loader.py +49 -0
- hardpy/pytest_hardpy/result/report_synchronizer/synchronizer.py +25 -9
- {hardpy-0.19.1.dist-info → hardpy-0.20.1.dist-info}/METADATA +32 -15
- {hardpy-0.19.1.dist-info → hardpy-0.20.1.dist-info}/RECORD +24 -24
- hardpy/hardpy_panel/frontend/dist/assets/index-B7T9xvaW.css +0 -1
- hardpy/pytest_hardpy/db/base_store.py +0 -179
- {hardpy-0.19.1.dist-info → hardpy-0.20.1.dist-info}/WHEEL +0 -0
- {hardpy-0.19.1.dist-info → hardpy-0.20.1.dist-info}/entry_points.txt +0 -0
- {hardpy-0.19.1.dist-info → hardpy-0.20.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2024 Everypin
|
|
2
|
-
# GNU General Public License v3.0 (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
3
|
-
|
|
4
|
-
from json import dumps
|
|
5
|
-
from logging import getLogger
|
|
6
|
-
from typing import Any
|
|
7
|
-
|
|
8
|
-
from glom import assign, glom
|
|
9
|
-
from pycouchdb import Server as DbServer
|
|
10
|
-
from pycouchdb.client import Database
|
|
11
|
-
from pycouchdb.exceptions import Conflict, GenericError, NotFound
|
|
12
|
-
from pydantic._internal._model_construction import ModelMetaclass
|
|
13
|
-
from requests.exceptions import ConnectionError # noqa: A004
|
|
14
|
-
|
|
15
|
-
from hardpy.common.config import ConfigManager
|
|
16
|
-
from hardpy.pytest_hardpy.db.const import DatabaseField as DF # noqa: N817
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class BaseStore:
|
|
20
|
-
"""HardPy base storage interface for CouchDB."""
|
|
21
|
-
|
|
22
|
-
def __init__(self, db_name: str) -> None:
|
|
23
|
-
config_manager = ConfigManager()
|
|
24
|
-
config = config_manager.config
|
|
25
|
-
self._db_srv = DbServer(config.database.url)
|
|
26
|
-
self._db_name = db_name
|
|
27
|
-
self._db = self._init_db()
|
|
28
|
-
self._doc_id = config.database.doc_id
|
|
29
|
-
self._log = getLogger(__name__)
|
|
30
|
-
self._doc: dict = self._init_doc()
|
|
31
|
-
self._schema: ModelMetaclass
|
|
32
|
-
|
|
33
|
-
def compact(self) -> None:
|
|
34
|
-
"""Compact database."""
|
|
35
|
-
self._db.compact()
|
|
36
|
-
|
|
37
|
-
def get_field(self, key: str) -> Any: # noqa: ANN401
|
|
38
|
-
"""Get field from the state store.
|
|
39
|
-
|
|
40
|
-
Args:
|
|
41
|
-
key (str): field name
|
|
42
|
-
|
|
43
|
-
Returns:
|
|
44
|
-
Any: field value
|
|
45
|
-
"""
|
|
46
|
-
return glom(self._doc, key)
|
|
47
|
-
|
|
48
|
-
def update_doc_value(self, key: str, value: Any) -> None: # noqa: ANN401
|
|
49
|
-
"""Update document value.
|
|
50
|
-
|
|
51
|
-
HardPy collecting uses a simple key without dots.
|
|
52
|
-
Assign is used to update a document.
|
|
53
|
-
Assign is a longer function.
|
|
54
|
-
|
|
55
|
-
Args:
|
|
56
|
-
key (str): document key
|
|
57
|
-
value: document value
|
|
58
|
-
"""
|
|
59
|
-
try:
|
|
60
|
-
dumps(value)
|
|
61
|
-
except Exception: # noqa: BLE001
|
|
62
|
-
# serialize non-serializable objects as string
|
|
63
|
-
value = dumps(value, default=str)
|
|
64
|
-
if "." in key:
|
|
65
|
-
assign(self._doc, key, value)
|
|
66
|
-
else:
|
|
67
|
-
self._doc[key] = value
|
|
68
|
-
|
|
69
|
-
def update_db(self) -> None:
|
|
70
|
-
"""Update database by current document."""
|
|
71
|
-
try:
|
|
72
|
-
self._doc = self._db.save(self._doc)
|
|
73
|
-
except Conflict:
|
|
74
|
-
self._doc["_rev"] = self._db.get(self._doc_id)["_rev"]
|
|
75
|
-
self._doc = self._db.save(self._doc)
|
|
76
|
-
|
|
77
|
-
def update_doc(self) -> None:
|
|
78
|
-
"""Update current document by database."""
|
|
79
|
-
self._doc["_rev"] = self._db.get(self._doc_id)["_rev"]
|
|
80
|
-
self._doc = self._db.get(self._doc_id)
|
|
81
|
-
|
|
82
|
-
def get_document(self) -> ModelMetaclass:
|
|
83
|
-
"""Get document by schema.
|
|
84
|
-
|
|
85
|
-
Returns:
|
|
86
|
-
ModelMetaclass: document by schema
|
|
87
|
-
"""
|
|
88
|
-
self._doc = self._db.get(self._doc_id)
|
|
89
|
-
return self._schema(**self._doc)
|
|
90
|
-
|
|
91
|
-
def clear(self) -> None:
|
|
92
|
-
"""Clear database."""
|
|
93
|
-
try:
|
|
94
|
-
# Clear statestore and runstore databases before each launch
|
|
95
|
-
self._db.delete(self._doc_id)
|
|
96
|
-
except (Conflict, NotFound):
|
|
97
|
-
self._log.debug("Database will be created for the first time")
|
|
98
|
-
self._doc: dict = self._init_doc()
|
|
99
|
-
|
|
100
|
-
def _init_db(self) -> Database:
|
|
101
|
-
try:
|
|
102
|
-
return self._db_srv.create(self._db_name) # type: ignore
|
|
103
|
-
except Conflict:
|
|
104
|
-
# database is already created
|
|
105
|
-
return self._db_srv.database(self._db_name)
|
|
106
|
-
except GenericError as exc:
|
|
107
|
-
msg = f"Error initializing database {exc}"
|
|
108
|
-
raise RuntimeError(msg) from exc
|
|
109
|
-
except ConnectionError as exc:
|
|
110
|
-
msg = f"Error initializing database: {exc}"
|
|
111
|
-
raise RuntimeError(msg) from exc
|
|
112
|
-
|
|
113
|
-
def _init_doc(self) -> dict:
|
|
114
|
-
try:
|
|
115
|
-
doc = self._db.get(self._doc_id)
|
|
116
|
-
except NotFound:
|
|
117
|
-
return {
|
|
118
|
-
"_id": self._doc_id,
|
|
119
|
-
DF.MODULES: {},
|
|
120
|
-
DF.DUT: {
|
|
121
|
-
DF.TYPE: None,
|
|
122
|
-
DF.NAME: None,
|
|
123
|
-
DF.REVISION: None,
|
|
124
|
-
DF.SERIAL_NUMBER: None,
|
|
125
|
-
DF.PART_NUMBER: None,
|
|
126
|
-
DF.SUB_UNITS: [],
|
|
127
|
-
DF.INFO: {},
|
|
128
|
-
},
|
|
129
|
-
DF.TEST_STAND: {
|
|
130
|
-
DF.HW_ID: None,
|
|
131
|
-
DF.NAME: None,
|
|
132
|
-
DF.REVISION: None,
|
|
133
|
-
DF.TIMEZONE: None,
|
|
134
|
-
DF.LOCATION: None,
|
|
135
|
-
DF.NUMBER: None,
|
|
136
|
-
DF.INSTRUMENTS: [],
|
|
137
|
-
DF.DRIVERS: {},
|
|
138
|
-
DF.INFO: {},
|
|
139
|
-
},
|
|
140
|
-
DF.PROCESS: {
|
|
141
|
-
DF.NAME: None,
|
|
142
|
-
DF.NUMBER: None,
|
|
143
|
-
DF.INFO: {},
|
|
144
|
-
},
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
# init document
|
|
148
|
-
if DF.MODULES not in doc:
|
|
149
|
-
doc[DF.MODULES] = {}
|
|
150
|
-
|
|
151
|
-
doc[DF.DUT] = {
|
|
152
|
-
DF.TYPE: None,
|
|
153
|
-
DF.NAME: None,
|
|
154
|
-
DF.REVISION: None,
|
|
155
|
-
DF.SERIAL_NUMBER: None,
|
|
156
|
-
DF.PART_NUMBER: None,
|
|
157
|
-
DF.SUB_UNITS: [],
|
|
158
|
-
DF.INFO: {},
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
doc[DF.TEST_STAND] = {
|
|
162
|
-
DF.HW_ID: None,
|
|
163
|
-
DF.NAME: None,
|
|
164
|
-
DF.REVISION: None,
|
|
165
|
-
DF.TIMEZONE: None,
|
|
166
|
-
DF.LOCATION: None,
|
|
167
|
-
DF.NUMBER: None,
|
|
168
|
-
DF.INSTRUMENTS: [],
|
|
169
|
-
DF.DRIVERS: {},
|
|
170
|
-
DF.INFO: {},
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
doc[DF.PROCESS] = {
|
|
174
|
-
DF.NAME: None,
|
|
175
|
-
DF.NUMBER: None,
|
|
176
|
-
DF.INFO: {},
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
return doc
|
|
File without changes
|
|
File without changes
|
|
File without changes
|