hardpy 0.5.1__tar.gz → 0.6.0__tar.gz
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-0.5.1 → hardpy-0.6.0}/PKG-INFO +25 -57
- hardpy-0.6.0/README.md +70 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/__init__.py +10 -0
- hardpy-0.6.0/hardpy/cli/cli.py +145 -0
- hardpy-0.6.0/hardpy/cli/template.py +210 -0
- hardpy-0.6.0/hardpy/common/config.py +159 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/api.py +49 -6
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/asset-manifest.json +3 -3
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/index.html +1 -1
- hardpy-0.6.0/hardpy/hardpy_panel/frontend/dist/static/js/main.7c954faf.js +3 -0
- hardpy-0.6.0/hardpy/hardpy_panel/frontend/dist/static/js/main.7c954faf.js.map +1 -0
- hardpy-0.6.0/hardpy/pytest_hardpy/__init__.py +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/db/base_server.py +4 -4
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/db/base_store.py +13 -3
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/db/const.py +3 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/db/schema.py +47 -11
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/db/statestore.py +11 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/plugin.py +90 -33
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/pytest_call.py +65 -5
- hardpy-0.6.0/hardpy/pytest_hardpy/pytest_wrapper.py +151 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/reporter/base.py +1 -1
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/reporter/hook_reporter.py +7 -3
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/result/report_loader/couchdb_loader.py +3 -2
- hardpy-0.6.0/hardpy/pytest_hardpy/result/report_reader/__init__.py +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/result/report_reader/couchdb_reader.py +2 -2
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/utils/__init__.py +7 -4
- hardpy-0.6.0/hardpy/pytest_hardpy/utils/connection_data.py +17 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/utils/const.py +4 -14
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/utils/dialog_box.py +1 -1
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/utils/exception.py +14 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/utils/node_info.py +1 -1
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/utils/progress_calculator.py +1 -1
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/utils/singleton.py +1 -1
- {hardpy-0.5.1 → hardpy-0.6.0}/pyproject.toml +6 -4
- hardpy-0.5.1/README.md +0 -104
- hardpy-0.5.1/hardpy/hardpy_panel/frontend/dist/static/js/main.da686f40.js +0 -3
- hardpy-0.5.1/hardpy/hardpy_panel/frontend/dist/static/js/main.da686f40.js.map +0 -1
- hardpy-0.5.1/hardpy/hardpy_panel/runner.py +0 -54
- hardpy-0.5.1/hardpy/pytest_hardpy/pytest_wrapper.py +0 -149
- hardpy-0.5.1/hardpy/pytest_hardpy/utils/config_data.py +0 -35
- {hardpy-0.5.1 → hardpy-0.6.0}/.gitignore +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/LICENSE +0 -0
- {hardpy-0.5.1/hardpy/hardpy_panel → hardpy-0.6.0/hardpy/cli}/__init__.py +0 -0
- {hardpy-0.5.1/hardpy/pytest_hardpy → hardpy-0.6.0/hardpy/common}/__init__.py +0 -0
- {hardpy-0.5.1/hardpy/pytest_hardpy/result/report_reader → hardpy-0.6.0/hardpy/hardpy_panel}/__init__.py +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/favicon.ico +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/logo512.png +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/manifest.json +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/css/main.e8a862f1.css +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/css/main.e8a862f1.css.map +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/js/808.ce070002.chunk.js +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/js/808.ce070002.chunk.js.map +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-16px-paths.d605910e.chunk.js +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-16px-paths.d605910e.chunk.js.map +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-20px-paths.7ee05cc8.chunk.js +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-20px-paths.7ee05cc8.chunk.js.map +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-all-paths-loader.0aa89747.chunk.js +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-all-paths-loader.0aa89747.chunk.js.map +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-all-paths.f63155c9.chunk.js +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-all-paths.f63155c9.chunk.js.map +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-split-paths-by-size-loader.52a072d3.chunk.js +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-split-paths-by-size-loader.52a072d3.chunk.js.map +0 -0
- /hardpy-0.5.1/hardpy/hardpy_panel/frontend/dist/static/js/main.da686f40.js.LICENSE.txt → /hardpy-0.6.0/hardpy/hardpy_panel/frontend/dist/static/js/main.7c954faf.js.LICENSE.txt +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.520846c6beb41df528c8.eot +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.5c52b39c697f2323ce8b.svg +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.84db1772f4bfb529f64f.woff +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.b67ee1736e20e37a3225.woff2 +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.e02ecf515378db143652.ttf +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-20.429cacb8accf72488451.ttf +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-20.6ae3791ee2d86fc228a6.svg +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-20.8cecf62de42997e4d82f.woff2 +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-20.afbadb627d43b7857223.eot +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-20.e857f5a5132b8bfa71a1.woff +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/hardpy_panel/frontend/dist/static/media/logo_smol.5b16f92447a4a9e80331.png +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/db/__init__.py +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/db/base_connector.py +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/db/runstore.py +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/reporter/__init__.py +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/reporter/runner_reporter.py +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/result/__init__.py +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/result/couchdb_config.py +0 -0
- {hardpy-0.5.1 → hardpy-0.6.0}/hardpy/pytest_hardpy/result/report_loader/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: hardpy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: HardPy library for device testing
|
|
5
5
|
Project-URL: Homepage, https://github.com/everypinio/hardpy/
|
|
6
6
|
Project-URL: Documentation, https://everypinio.github.io/hardpy/
|
|
@@ -28,7 +28,9 @@ Requires-Dist: glom>=23.3.0
|
|
|
28
28
|
Requires-Dist: natsort>=8.4.0
|
|
29
29
|
Requires-Dist: pycouchdb>=1.14.2
|
|
30
30
|
Requires-Dist: pydantic>=2.4.0
|
|
31
|
-
Requires-Dist: pytest<9
|
|
31
|
+
Requires-Dist: pytest<9,>=7
|
|
32
|
+
Requires-Dist: rtoml~=0.11.0
|
|
33
|
+
Requires-Dist: typer<1.0,>=0.12
|
|
32
34
|
Requires-Dist: uvicorn>=0.23.2
|
|
33
35
|
Provides-Extra: build
|
|
34
36
|
Requires-Dist: build==1.0.3; extra == 'build'
|
|
@@ -74,71 +76,37 @@ HardPy allows you to:
|
|
|
74
76
|
pip install hardpy
|
|
75
77
|
```
|
|
76
78
|
|
|
77
|
-
## Examples
|
|
78
|
-
|
|
79
|
-
Find examples of using the **HardPy** in the `examples` folder.
|
|
80
|
-
|
|
81
79
|
## Getting Started
|
|
82
80
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
For Windows, follow the instructions from the
|
|
87
|
-
[documentation](https://everypinio.github.io/hardpy/documentation/database/#couchdb-instance).
|
|
88
|
-
|
|
89
|
-
Launch CouchDB with Docker.
|
|
90
|
-
The Docker version must be 24.0.0 or higher.
|
|
91
|
-
Create `couchdb.ini` file:
|
|
92
|
-
|
|
93
|
-
```ini
|
|
94
|
-
[chttpd]
|
|
95
|
-
enable_cors=true
|
|
96
|
-
|
|
97
|
-
[cors]
|
|
98
|
-
origins = *
|
|
99
|
-
methods = GET, PUT, POST, HEAD, DELETE
|
|
100
|
-
credentials = true
|
|
101
|
-
headers = accept, authorization, content-type, origin, referer, x-csrf-token
|
|
81
|
+
1. Create your first test bench.
|
|
82
|
+
```bash
|
|
83
|
+
hardpy init
|
|
102
84
|
```
|
|
103
|
-
|
|
104
|
-
Run the Docker container from folder with couchdb.ini file:
|
|
105
|
-
|
|
85
|
+
2. Launch [CouchDB](https://couchdb.apache.org/) database via [docker compose](https://docs.docker.com/compose/) in the background.
|
|
106
86
|
```bash
|
|
107
|
-
|
|
87
|
+
cd tests
|
|
88
|
+
docker compose up -d
|
|
108
89
|
```
|
|
109
|
-
|
|
110
|
-
Command for Windows:
|
|
111
|
-
|
|
90
|
+
3. Launch HardPy operator panel.
|
|
112
91
|
```bash
|
|
113
|
-
|
|
92
|
+
hardpy run
|
|
114
93
|
```
|
|
94
|
+
4. View operator panel in browser: http://localhost:8000/
|
|
115
95
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
```python
|
|
121
|
-
# test_1.py
|
|
122
|
-
import pytest
|
|
123
|
-
|
|
124
|
-
def test_one():
|
|
125
|
-
assert True
|
|
126
|
-
```
|
|
127
|
-
#### Operator panel
|
|
96
|
+
<h1 align="center">
|
|
97
|
+
<img src="https://everypinio.github.io/hardpy/img/hardpy_operator_panel_hello_hardpy.png"
|
|
98
|
+
alt="hardpy operator panel" style="width:600px;">
|
|
99
|
+
</h1>
|
|
128
100
|
|
|
129
|
-
|
|
101
|
+
5. View the latest test report: http://localhost:5984/_utils
|
|
130
102
|
|
|
131
|
-
|
|
132
|
-
<img src="https://everypinio.github.io/hardpy/img/hardpy_operator_panel_hello_hardpy.png"
|
|
133
|
-
alt="hardpy operator panel" style="width:600px;">
|
|
134
|
-
</h1>
|
|
103
|
+
Login and password: **dev**, database - **runstore**, document - **current**.
|
|
135
104
|
|
|
136
|
-
|
|
105
|
+
<h1 align="center">
|
|
106
|
+
<img src="https://everypinio.github.io/hardpy/img/runstore_hello_hardpy.png"
|
|
107
|
+
alt="hardpy runstore" style="width:500px;">
|
|
108
|
+
</h1>
|
|
137
109
|
|
|
138
|
-
|
|
139
|
-
You can view the CouchDB instance through Fauxton web interface: http://localhost:5984/_utils
|
|
110
|
+
## Examples
|
|
140
111
|
|
|
141
|
-
|
|
142
|
-
<img src="https://everypinio.github.io/hardpy/img/runstore_hello_hardpy.png"
|
|
143
|
-
alt="hardpy runstore" style="width:600px;">
|
|
144
|
-
</h1>
|
|
112
|
+
Find more examples of using the **HardPy** in the [examples](https://github.com/everypinio/hardpy/tree/main/examples) folder.
|
hardpy-0.6.0/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<h1 align="center">
|
|
2
|
+
<img src="https://everypinio.github.io/hardpy/img/logo256.png" alt="HardPy" style="width:200px;">
|
|
3
|
+
</h1>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">
|
|
6
|
+
<b>HardPy</b>
|
|
7
|
+
</h1>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
HardPy is a python library for creating a test bench for devices.
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
**Documentation**: <a href=https://everypinio.github.io/hardpy/ target="_blank">https://everypinio.github.io/hardpy/</a>
|
|
16
|
+
|
|
17
|
+
**Source Code**: <a href=https://github.com/everypinio/hardpy target="_blank">https://github.com/everypinio/hardpy</a>
|
|
18
|
+
|
|
19
|
+
**PyPi**: <a href=https://pypi.org/project/hardpy/ target="_blank">https://pypi.org/project/hardpy/</a>
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Overview
|
|
24
|
+
|
|
25
|
+
HardPy allows you to:
|
|
26
|
+
|
|
27
|
+
* Create test benches for devices using [pytest](https://docs.pytest.org/);
|
|
28
|
+
* Use a browser to view, start, stop, and interact with tests;
|
|
29
|
+
* Store test results in the [CouchDB](https://couchdb.apache.org/) database.
|
|
30
|
+
|
|
31
|
+
## To Install
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install hardpy
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Getting Started
|
|
38
|
+
|
|
39
|
+
1. Create your first test bench.
|
|
40
|
+
```bash
|
|
41
|
+
hardpy init
|
|
42
|
+
```
|
|
43
|
+
2. Launch [CouchDB](https://couchdb.apache.org/) database via [docker compose](https://docs.docker.com/compose/) in the background.
|
|
44
|
+
```bash
|
|
45
|
+
cd tests
|
|
46
|
+
docker compose up -d
|
|
47
|
+
```
|
|
48
|
+
3. Launch HardPy operator panel.
|
|
49
|
+
```bash
|
|
50
|
+
hardpy run
|
|
51
|
+
```
|
|
52
|
+
4. View operator panel in browser: http://localhost:8000/
|
|
53
|
+
|
|
54
|
+
<h1 align="center">
|
|
55
|
+
<img src="https://everypinio.github.io/hardpy/img/hardpy_operator_panel_hello_hardpy.png"
|
|
56
|
+
alt="hardpy operator panel" style="width:600px;">
|
|
57
|
+
</h1>
|
|
58
|
+
|
|
59
|
+
5. View the latest test report: http://localhost:5984/_utils
|
|
60
|
+
|
|
61
|
+
Login and password: **dev**, database - **runstore**, document - **current**.
|
|
62
|
+
|
|
63
|
+
<h1 align="center">
|
|
64
|
+
<img src="https://everypinio.github.io/hardpy/img/runstore_hello_hardpy.png"
|
|
65
|
+
alt="hardpy runstore" style="width:500px;">
|
|
66
|
+
</h1>
|
|
67
|
+
|
|
68
|
+
## Examples
|
|
69
|
+
|
|
70
|
+
Find more examples of using the **HardPy** in the [examples](https://github.com/everypinio/hardpy/tree/main/examples) folder.
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
from hardpy.pytest_hardpy.result import CouchdbLoader
|
|
5
5
|
from hardpy.pytest_hardpy.utils import (
|
|
6
6
|
DuplicateSerialNumberError,
|
|
7
|
+
DuplicatePartNumberError,
|
|
8
|
+
DuplicateTestStandNameError,
|
|
7
9
|
DuplicateDialogBoxError,
|
|
8
10
|
)
|
|
9
11
|
from hardpy.pytest_hardpy.result.couchdb_config import CouchdbConfig
|
|
@@ -21,6 +23,8 @@ from hardpy.pytest_hardpy.pytest_call import (
|
|
|
21
23
|
get_current_report,
|
|
22
24
|
set_dut_info,
|
|
23
25
|
set_dut_serial_number,
|
|
26
|
+
set_dut_part_number,
|
|
27
|
+
set_stand_name,
|
|
24
28
|
set_stand_info,
|
|
25
29
|
set_case_artifact,
|
|
26
30
|
set_module_artifact,
|
|
@@ -28,6 +32,7 @@ from hardpy.pytest_hardpy.pytest_call import (
|
|
|
28
32
|
set_message,
|
|
29
33
|
set_driver_info,
|
|
30
34
|
run_dialog_box,
|
|
35
|
+
set_operator_message,
|
|
31
36
|
)
|
|
32
37
|
|
|
33
38
|
__all__ = [
|
|
@@ -37,16 +42,21 @@ __all__ = [
|
|
|
37
42
|
"get_current_report",
|
|
38
43
|
# Errors
|
|
39
44
|
"DuplicateSerialNumberError",
|
|
45
|
+
"DuplicatePartNumberError",
|
|
46
|
+
"DuplicateTestStandNameError",
|
|
40
47
|
"DuplicateDialogBoxError",
|
|
41
48
|
# Database info
|
|
42
49
|
"set_dut_info",
|
|
43
50
|
"set_dut_serial_number",
|
|
51
|
+
"set_dut_part_number",
|
|
52
|
+
"set_stand_name",
|
|
44
53
|
"set_stand_info",
|
|
45
54
|
"set_case_artifact",
|
|
46
55
|
"set_module_artifact",
|
|
47
56
|
"set_run_artifact",
|
|
48
57
|
"set_message",
|
|
49
58
|
"set_driver_info",
|
|
59
|
+
"set_operator_message",
|
|
50
60
|
# Dialog boxes
|
|
51
61
|
"run_dialog_box",
|
|
52
62
|
"DialogBox",
|
|
@@ -0,0 +1,145 @@
|
|
|
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
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Optional
|
|
8
|
+
from typing_extensions import Annotated
|
|
9
|
+
|
|
10
|
+
import typer
|
|
11
|
+
from uvicorn import run as uvicorn_run
|
|
12
|
+
|
|
13
|
+
from hardpy.cli.template import TemplateGenerator
|
|
14
|
+
from hardpy.common.config import ConfigManager
|
|
15
|
+
|
|
16
|
+
cli = typer.Typer(add_completion=False)
|
|
17
|
+
default_config = ConfigManager().get_config()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@cli.command()
|
|
21
|
+
def init( # noqa: WPS211
|
|
22
|
+
tests_dir: Annotated[Optional[str], typer.Argument()] = None,
|
|
23
|
+
create_database: bool = typer.Option(
|
|
24
|
+
True,
|
|
25
|
+
help="Create CouchDB database.",
|
|
26
|
+
),
|
|
27
|
+
database_user: str = typer.Option(
|
|
28
|
+
default_config.database.user,
|
|
29
|
+
help="Specify a database user.",
|
|
30
|
+
),
|
|
31
|
+
database_password: str = typer.Option(
|
|
32
|
+
default_config.database.password,
|
|
33
|
+
help="Specify a database user password.",
|
|
34
|
+
),
|
|
35
|
+
database_host: str = typer.Option(
|
|
36
|
+
default_config.database.host,
|
|
37
|
+
help="Specify a database host.",
|
|
38
|
+
),
|
|
39
|
+
database_port: int = typer.Option(
|
|
40
|
+
default_config.database.port,
|
|
41
|
+
help="Specify a database port.",
|
|
42
|
+
),
|
|
43
|
+
frontend_host: str = typer.Option(
|
|
44
|
+
default_config.frontend.host,
|
|
45
|
+
help="Specify a frontend host.",
|
|
46
|
+
),
|
|
47
|
+
frontend_port: int = typer.Option(
|
|
48
|
+
default_config.frontend.port,
|
|
49
|
+
help="Specify a frontend port.",
|
|
50
|
+
),
|
|
51
|
+
socket_host: str = typer.Option(
|
|
52
|
+
default_config.socket.host,
|
|
53
|
+
help="Specify a socket host.",
|
|
54
|
+
),
|
|
55
|
+
socket_port: int = typer.Option(
|
|
56
|
+
default_config.socket.port,
|
|
57
|
+
help="Specify a socket port.",
|
|
58
|
+
),
|
|
59
|
+
):
|
|
60
|
+
"""Initialize HardPy tests directory.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
tests_dir (str | None): Tests directory. Current directory + `tests` by default
|
|
64
|
+
create_database (bool): Flag to create database
|
|
65
|
+
database_user (str): Database user name
|
|
66
|
+
database_password (str): Database password
|
|
67
|
+
database_host (str): Database host
|
|
68
|
+
database_port (int): Database port
|
|
69
|
+
frontend_host (str): Panel operator host
|
|
70
|
+
frontend_port (int): Panel operator port
|
|
71
|
+
socket_host (str): Socket host
|
|
72
|
+
socket_port (int): Socket port
|
|
73
|
+
"""
|
|
74
|
+
_tests_dir = tests_dir if tests_dir else default_config.tests_dir
|
|
75
|
+
ConfigManager().init_config(
|
|
76
|
+
tests_dir=str(_tests_dir),
|
|
77
|
+
database_user=database_user,
|
|
78
|
+
database_password=database_password,
|
|
79
|
+
database_host=database_host,
|
|
80
|
+
database_port=database_port,
|
|
81
|
+
frontend_host=frontend_host,
|
|
82
|
+
frontend_port=frontend_port,
|
|
83
|
+
socket_host=socket_host,
|
|
84
|
+
socket_port=socket_port,
|
|
85
|
+
)
|
|
86
|
+
# create tests directory
|
|
87
|
+
dir_path = Path(Path.cwd() / _tests_dir)
|
|
88
|
+
os.makedirs(dir_path, exist_ok=True)
|
|
89
|
+
|
|
90
|
+
if create_database:
|
|
91
|
+
# create database directory
|
|
92
|
+
os.makedirs(dir_path / "database", exist_ok=True)
|
|
93
|
+
|
|
94
|
+
# create hardpy.toml
|
|
95
|
+
ConfigManager().create_config(dir_path)
|
|
96
|
+
config = ConfigManager().read_config(dir_path)
|
|
97
|
+
if not config:
|
|
98
|
+
print(f"hardpy.toml config by path {dir_path} not detected.")
|
|
99
|
+
sys.exit()
|
|
100
|
+
|
|
101
|
+
template = TemplateGenerator(config)
|
|
102
|
+
|
|
103
|
+
files = {}
|
|
104
|
+
|
|
105
|
+
if create_database:
|
|
106
|
+
files[Path(dir_path / "docker-compose.yaml")] = template.docker_compose_yaml
|
|
107
|
+
files[Path(dir_path / "database" / "couchdb.ini")] = template.couchdb_ini
|
|
108
|
+
|
|
109
|
+
files[Path(dir_path / "pytest.ini")] = template.pytest_ini
|
|
110
|
+
files[Path(dir_path / "test_1.py")] = template.test_1_py
|
|
111
|
+
files[Path(dir_path / "conftest.py")] = template.conftest_py
|
|
112
|
+
|
|
113
|
+
for key, value in files.items():
|
|
114
|
+
template.create_file(key, value)
|
|
115
|
+
|
|
116
|
+
print(f"HardPy project {dir_path.name} initialized successfully.")
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
@cli.command()
|
|
120
|
+
def run(tests_dir: Annotated[Optional[str], typer.Argument()] = None):
|
|
121
|
+
"""Run HardPy server.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
tests_dir (Optional[str]): Test directory. Current directory by default
|
|
125
|
+
"""
|
|
126
|
+
dir_path = Path.cwd() / tests_dir if tests_dir else Path.cwd()
|
|
127
|
+
config = ConfigManager().read_config(dir_path)
|
|
128
|
+
|
|
129
|
+
if not config:
|
|
130
|
+
print(f"Config at path {dir_path} not found.")
|
|
131
|
+
sys.exit()
|
|
132
|
+
|
|
133
|
+
print("\nLaunch the HardPy operator panel...")
|
|
134
|
+
print(f"http://{config.frontend.host}:{config.frontend.port}\n")
|
|
135
|
+
|
|
136
|
+
uvicorn_run(
|
|
137
|
+
"hardpy.hardpy_panel.api:app",
|
|
138
|
+
host=config.frontend.host,
|
|
139
|
+
port=config.frontend.port,
|
|
140
|
+
log_level="critical",
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
if __name__ == "__main__":
|
|
145
|
+
cli()
|
|
@@ -0,0 +1,210 @@
|
|
|
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 pathlib import Path
|
|
5
|
+
|
|
6
|
+
from hardpy.common.config import HardpyConfig
|
|
7
|
+
|
|
8
|
+
docker_compose_yaml = """version: "3.8"
|
|
9
|
+
|
|
10
|
+
services:
|
|
11
|
+
couchserver:
|
|
12
|
+
image: couchdb:3.3.2
|
|
13
|
+
ports:
|
|
14
|
+
- "{}:5984"
|
|
15
|
+
environment:
|
|
16
|
+
COUCHDB_USER: {}
|
|
17
|
+
COUCHDB_PASSWORD: {}
|
|
18
|
+
volumes:
|
|
19
|
+
- ./database/dbdata:/opt/couchdb/data
|
|
20
|
+
- ./database/couchdb.ini:/opt/couchdb/etc/local.ini
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
couchdb_ini = """; CouchDB Configuration Settings
|
|
24
|
+
|
|
25
|
+
; Custom settings should be made in this file. They will override settings
|
|
26
|
+
; in default.ini, but unlike changes made to default.ini, this file won't be
|
|
27
|
+
; overwritten on server upgrade.
|
|
28
|
+
|
|
29
|
+
[couchdb]
|
|
30
|
+
;max_document_size = 4294967296 ; bytes
|
|
31
|
+
;os_process_timeout = 5000
|
|
32
|
+
|
|
33
|
+
[couch_peruser]
|
|
34
|
+
; If enabled, couch_peruser ensures that a private per-user database
|
|
35
|
+
; exists for each document in _users. These databases are writable only
|
|
36
|
+
; by the corresponding user. Databases are in the following form:
|
|
37
|
+
; userdb-{{hex encoded username}}
|
|
38
|
+
;enable = true
|
|
39
|
+
|
|
40
|
+
; If set to true and a user is deleted, the respective database gets
|
|
41
|
+
; deleted as well.
|
|
42
|
+
;delete_dbs = true
|
|
43
|
+
|
|
44
|
+
; Set a default q value for peruser-created databases that is different from
|
|
45
|
+
; cluster / q
|
|
46
|
+
;q = 1
|
|
47
|
+
|
|
48
|
+
[chttpd]
|
|
49
|
+
;port = {}
|
|
50
|
+
;bind_address = {}
|
|
51
|
+
|
|
52
|
+
; Options for the MochiWeb HTTP server.
|
|
53
|
+
;server_options = [{{backlog, 128}}, {{acceptor_pool_size, 16}}]
|
|
54
|
+
|
|
55
|
+
; For more socket options, consult Erlang's module 'inet' man page.
|
|
56
|
+
;socket_options = [{{sndbuf, 262144}}, {{nodelay, true}}]
|
|
57
|
+
|
|
58
|
+
enable_cors=true
|
|
59
|
+
|
|
60
|
+
[httpd]
|
|
61
|
+
; NOTE that this only configures the "backend" node-local port, not the
|
|
62
|
+
; "frontend" clustered port. You probably don't want to change anything in
|
|
63
|
+
; this section.
|
|
64
|
+
; Uncomment next line to trigger basic-auth popup on unauthorized requests.
|
|
65
|
+
;WWW-Authenticate = Basic realm="administrator"
|
|
66
|
+
|
|
67
|
+
; Uncomment next line to set the configuration modification whitelist. Only
|
|
68
|
+
; whitelisted values may be changed via the /_config URLs. To allow the admin
|
|
69
|
+
; to change this value over HTTP, remember to include {{httpd,config_whitelist}}
|
|
70
|
+
; itself. Excluding it from the list would require editing this file to update
|
|
71
|
+
; the whitelist.
|
|
72
|
+
;config_whitelist = [{{httpd,config_whitelist}}, {{log,level}}, {{etc,etc}}]
|
|
73
|
+
|
|
74
|
+
[cors]
|
|
75
|
+
origins = *
|
|
76
|
+
methods = GET, PUT, POST, HEAD, DELETE
|
|
77
|
+
credentials = true
|
|
78
|
+
headers = accept, authorization, content-type, origin, referer, x-csrf-token
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
[ssl]
|
|
82
|
+
;enable = true
|
|
83
|
+
;cert_file = /full/path/to/server_cert.pem
|
|
84
|
+
;key_file = /full/path/to/server_key.pem
|
|
85
|
+
;password = somepassword
|
|
86
|
+
|
|
87
|
+
; set to true to validate peer certificates
|
|
88
|
+
;verify_ssl_certificates = false
|
|
89
|
+
|
|
90
|
+
; Set to true to fail if the client does not send a certificate. Only used if verify_ssl_certificates is true.
|
|
91
|
+
;fail_if_no_peer_cert = false
|
|
92
|
+
|
|
93
|
+
; Path to file containing PEM encoded CA certificates (trusted
|
|
94
|
+
; certificates used for verifying a peer certificate). May be omitted if
|
|
95
|
+
; you do not want to verify the peer.
|
|
96
|
+
;cacert_file = /full/path/to/cacertf
|
|
97
|
+
|
|
98
|
+
; The verification fun (optional) if not specified, the default
|
|
99
|
+
; verification fun will be used.
|
|
100
|
+
;verify_fun = {{Module, VerifyFun}}
|
|
101
|
+
|
|
102
|
+
; maximum peer certificate depth
|
|
103
|
+
;ssl_certificate_max_depth = 1
|
|
104
|
+
|
|
105
|
+
; Reject renegotiations that do not live up to RFC 5746.
|
|
106
|
+
;secure_renegotiate = true
|
|
107
|
+
|
|
108
|
+
; The cipher suites that should be supported.
|
|
109
|
+
; Can be specified in erlang format "{{ecdhe_ecdsa,aes_128_cbc,sha256}}"
|
|
110
|
+
; or in OpenSSL format "ECDHE-ECDSA-AES128-SHA256".
|
|
111
|
+
;ciphers = ["ECDHE-ECDSA-AES128-SHA256", "ECDHE-ECDSA-AES128-SHA"]
|
|
112
|
+
|
|
113
|
+
; The SSL/TLS versions to support
|
|
114
|
+
;tls_versions = [tlsv1, 'tlsv1.1', 'tlsv1.2']
|
|
115
|
+
|
|
116
|
+
; To enable Virtual Hosts in CouchDB, add a vhost = path directive. All requests to
|
|
117
|
+
; the Virtual Host will be redirected to the path. In the example below all requests
|
|
118
|
+
; to http://example.com/ are redirected to /database.
|
|
119
|
+
; If you run CouchDB on a specific port, include the port number in the vhost:
|
|
120
|
+
; example.com:5984 = /database
|
|
121
|
+
[vhosts]
|
|
122
|
+
;example.com = /database/
|
|
123
|
+
|
|
124
|
+
; To create an admin account uncomment the '[admins]' section below and add a
|
|
125
|
+
; line in the format 'username = password'. When you next start CouchDB, it
|
|
126
|
+
; will change the password to a hash (so that your passwords don't linger
|
|
127
|
+
; around in plain-text files). You can add more admin accounts with more
|
|
128
|
+
; 'username = password' lines. Don't forget to restart CouchDB after
|
|
129
|
+
; changing this.
|
|
130
|
+
[admins]
|
|
131
|
+
;admin = mysecretpassword
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
pytest_ini = """[pytest]
|
|
135
|
+
log_cli = true
|
|
136
|
+
log_cli_level = INFO
|
|
137
|
+
log_cli_format = %%(asctime)s [%%(levelname)s] %%(message)s
|
|
138
|
+
log_cli_date_format = %H:%M:%S
|
|
139
|
+
addopts = --hardpy-pt
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
test_1_py = """import pytest
|
|
143
|
+
import hardpy
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
pytestmark = pytest.mark.module_name("HardPy template")
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
@pytest.mark.case_name("Test 1")
|
|
150
|
+
def test_one():
|
|
151
|
+
assert True
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
conftest_py = """import pytest
|
|
155
|
+
import hardpy
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def finish_executing():
|
|
159
|
+
print("Testing completed")
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
@pytest.fixture(scope="session", autouse=True)
|
|
163
|
+
def fill_actions_after_test(post_run_functions: list):
|
|
164
|
+
post_run_functions.append(finish_executing)
|
|
165
|
+
yield
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class TemplateGenerator:
|
|
170
|
+
"""HardPy template files generator."""
|
|
171
|
+
|
|
172
|
+
def __init__(self, config: HardpyConfig):
|
|
173
|
+
self._config = config
|
|
174
|
+
|
|
175
|
+
def create_file(self, file_path: Path, content: str):
|
|
176
|
+
"""Create HardPy template file.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
file_path (Path): file path
|
|
180
|
+
content (str): file content
|
|
181
|
+
"""
|
|
182
|
+
with open(file_path, "w") as file:
|
|
183
|
+
file.write(content)
|
|
184
|
+
|
|
185
|
+
@property
|
|
186
|
+
def docker_compose_yaml(self) -> str:
|
|
187
|
+
return docker_compose_yaml.format(
|
|
188
|
+
self._config.database.port,
|
|
189
|
+
self._config.database.user,
|
|
190
|
+
self._config.database.password,
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
@property
|
|
194
|
+
def couchdb_ini(self) -> str:
|
|
195
|
+
return couchdb_ini.format(
|
|
196
|
+
self._config.database.port,
|
|
197
|
+
self._config.database.host,
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
@property
|
|
201
|
+
def pytest_ini(self) -> str:
|
|
202
|
+
return pytest_ini
|
|
203
|
+
|
|
204
|
+
@property
|
|
205
|
+
def test_1_py(self) -> str: # noqa: WPS114
|
|
206
|
+
return test_1_py
|
|
207
|
+
|
|
208
|
+
@property
|
|
209
|
+
def conftest_py(self) -> str:
|
|
210
|
+
return conftest_py
|