flakytest 2023.0b0__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.
@@ -0,0 +1,35 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ deploy:
12
+
13
+ runs-on: ubuntu-latest
14
+
15
+ environment: release
16
+ permissions:
17
+ id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
18
+
19
+ steps:
20
+ - uses: actions/checkout@v3
21
+ - name: Set up Python
22
+ uses: actions/setup-python@v4
23
+ with:
24
+ python-version: '3.11'
25
+ cache: 'pip'
26
+ - name: Install dependencies
27
+ run: |
28
+ python -m pip install --upgrade pip
29
+ pip install hatch
30
+ - name: Build package
31
+ run: hatch build
32
+ # - name: Test package
33
+ # run: hatch run test
34
+ - name: Publish package distributions to PyPI
35
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1 @@
1
+ dist
@@ -0,0 +1,16 @@
1
+ # See https://pre-commit.com for more information
2
+ # See https://pre-commit.com/hooks.html for more hooks
3
+ repos:
4
+ - repo: https://github.com/pre-commit/pre-commit-hooks
5
+ rev: v3.2.0
6
+ hooks:
7
+ - id: trailing-whitespace
8
+ - id: end-of-file-fixer
9
+ - id: check-yaml
10
+ - id: check-added-large-files
11
+ - repo: https://github.com/astral-sh/ruff-pre-commit
12
+ # Ruff version.
13
+ rev: v0.0.290
14
+ hooks:
15
+ - id: ruff
16
+ - id: ruff-format
@@ -0,0 +1,10 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Calendar Versioning](https://calver.org).
7
+
8
+ ## [2023.0b0] - 2023-09-24
9
+
10
+ Initial release
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023-present Anže Pečar <anze@pecar.me>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,65 @@
1
+ Metadata-Version: 2.1
2
+ Name: flakytest
3
+ Version: 2023.0b0
4
+ Summary: Pytest plugin for flakytest.dev
5
+ Project-URL: Documentation, https://github.com/anze3db/flakytest-python#readme
6
+ Project-URL: Changelog, https://github.com/anze3db/flakytest-python/blob/main/CHANGELOG.md
7
+ Project-URL: Issues, https://github.com/anze3db/flakytest-python/issues
8
+ Project-URL: Source, https://github.com/anze3db/flakytest-python
9
+ Project-URL: Mastodon, https://fosstodon.org/@anze3db
10
+ Project-URL: Twitter, https://twitter.com/anze3db
11
+ Author-email: Anže Pečar <anze@pecar.me>
12
+ License-Expression: MIT
13
+ License-File: LICENSE.txt
14
+ Keywords: flaky,pytest,test
15
+ Classifier: Development Status :: 4 - Beta
16
+ Classifier: Framework :: Pytest
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Natural Language :: English
20
+ Classifier: Programming Language :: Python
21
+ Classifier: Programming Language :: Python :: 3.8
22
+ Classifier: Programming Language :: Python :: 3.9
23
+ Classifier: Programming Language :: Python :: 3.10
24
+ Classifier: Programming Language :: Python :: 3.11
25
+ Classifier: Programming Language :: Python :: Implementation :: CPython
26
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
27
+ Requires-Python: >=3.8
28
+ Description-Content-Type: text/markdown
29
+
30
+ # flakytest-python
31
+
32
+ [![PyPI - Version](https://img.shields.io/pypi/v/flakytest.svg)](https://pypi.org/project/flakytest)
33
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/flakytest.svg)](https://pypi.org/project/flakytest)
34
+
35
+ -----
36
+
37
+ **Table of Contents**
38
+
39
+ - [Installation](#installation)
40
+ - [License](#license)
41
+
42
+ ## Installation
43
+
44
+ > [!WARNING]
45
+ > flakytest is currently in beta. It is not recommended to use it in production.
46
+
47
+ ```console
48
+ pip install flakytest --pre
49
+ ```
50
+
51
+ Obtain the `FLAKYTEST_SECRET_TOKEN` from [flakytest.dev](https://flakytest.dev/) and set it as an environment variable (e.g. your secrets store in your CI/CD pipeline)
52
+
53
+ ```console
54
+ export FLAKYTEST_SECRET_TOKEN=****************************
55
+ ```
56
+
57
+ Run your tests with `pytest` normally
58
+
59
+ ```console
60
+ pytest
61
+ ```
62
+
63
+ ## License
64
+
65
+ `flakytest` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
@@ -0,0 +1,36 @@
1
+ # flakytest-python
2
+
3
+ [![PyPI - Version](https://img.shields.io/pypi/v/flakytest.svg)](https://pypi.org/project/flakytest)
4
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/flakytest.svg)](https://pypi.org/project/flakytest)
5
+
6
+ -----
7
+
8
+ **Table of Contents**
9
+
10
+ - [Installation](#installation)
11
+ - [License](#license)
12
+
13
+ ## Installation
14
+
15
+ > [!WARNING]
16
+ > flakytest is currently in beta. It is not recommended to use it in production.
17
+
18
+ ```console
19
+ pip install flakytest --pre
20
+ ```
21
+
22
+ Obtain the `FLAKYTEST_SECRET_TOKEN` from [flakytest.dev](https://flakytest.dev/) and set it as an environment variable (e.g. your secrets store in your CI/CD pipeline)
23
+
24
+ ```console
25
+ export FLAKYTEST_SECRET_TOKEN=****************************
26
+ ```
27
+
28
+ Run your tests with `pytest` normally
29
+
30
+ ```console
31
+ pytest
32
+ ```
33
+
34
+ ## License
35
+
36
+ `flakytest` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
@@ -0,0 +1,168 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "flakytest"
7
+ dynamic = ["version"]
8
+ description = 'Pytest plugin for flakytest.dev'
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = "MIT"
12
+ keywords = [
13
+ "test",
14
+ "flaky",
15
+ "pytest"
16
+ ]
17
+ authors = [
18
+ { name = "Anže Pečar", email = "anze@pecar.me" },
19
+ ]
20
+ classifiers = [
21
+ "Development Status :: 4 - Beta",
22
+ "Programming Language :: Python",
23
+ "Programming Language :: Python :: 3.8",
24
+ "Programming Language :: Python :: 3.9",
25
+ "Programming Language :: Python :: 3.10",
26
+ "Programming Language :: Python :: 3.11",
27
+ "Programming Language :: Python :: Implementation :: CPython",
28
+ "Programming Language :: Python :: Implementation :: PyPy",
29
+ "Intended Audience :: Developers",
30
+ "License :: OSI Approved :: MIT License",
31
+ "Natural Language :: English",
32
+ "Framework :: Pytest",
33
+ ]
34
+ dependencies = []
35
+
36
+ [project.urls]
37
+ Documentation = "https://github.com/anze3db/flakytest-python#readme"
38
+ Changelog = "https://github.com/anze3db/flakytest-python/blob/main/CHANGELOG.md"
39
+ Issues = "https://github.com/anze3db/flakytest-python/issues"
40
+ Source = "https://github.com/anze3db/flakytest-python"
41
+ Mastodon = "https://fosstodon.org/@anze3db"
42
+ Twitter = "https://twitter.com/anze3db"
43
+
44
+ [project.entry-points.pytest11]
45
+ flakytest = "flakytest.hook"
46
+
47
+
48
+ [tool.hatch.version]
49
+ path = "src/flakytest/__about__.py"
50
+
51
+ [tool.hatch.envs.default]
52
+ dependencies = [
53
+ "coverage[toml]>=6.5",
54
+ "pytest",
55
+ ]
56
+ [tool.hatch.envs.default.scripts]
57
+ test = "pytest {args:tests}"
58
+ test-cov = "coverage run -m pytest {args:tests}"
59
+ cov-report = [
60
+ "- coverage combine",
61
+ "coverage report",
62
+ ]
63
+ cov = [
64
+ "test-cov",
65
+ "cov-report",
66
+ ]
67
+
68
+ [[tool.hatch.envs.all.matrix]]
69
+ python = ["3.8", "3.9", "3.10", "3.11"]
70
+
71
+ [tool.hatch.envs.lint]
72
+ detached = true
73
+ dependencies = [
74
+ "mypy>=1.0.0",
75
+ "ruff>=0.0.290",
76
+ ]
77
+ [tool.hatch.envs.lint.scripts]
78
+ typing = "mypy --install-types --non-interactive {args:src/flakytest tests}"
79
+ style = [
80
+ "ruff {args:.}",
81
+ "ruff format --check --diff {args:.}",
82
+ ]
83
+ fmt = [
84
+ "ruff format {args:.}",
85
+ "ruff --fix {args:.}",
86
+ "style",
87
+ ]
88
+ all = [
89
+ "style",
90
+ "typing",
91
+ ]
92
+
93
+ [tool.ruff]
94
+ target-version = "py37"
95
+ line-length = 120
96
+ select = [
97
+ "A",
98
+ "ARG",
99
+ "B",
100
+ "C",
101
+ "DTZ",
102
+ "E",
103
+ "EM",
104
+ "F",
105
+ "FBT",
106
+ "I",
107
+ "ICN",
108
+ "ISC",
109
+ "N",
110
+ "PLC",
111
+ "PLE",
112
+ "PLR",
113
+ "PLW",
114
+ "Q",
115
+ "RUF",
116
+ "S",
117
+ "T",
118
+ "TID",
119
+ "UP",
120
+ "W",
121
+ "YTT",
122
+ ]
123
+ ignore = [
124
+ # Allow non-abstract empty methods in abstract base classes
125
+ "B027",
126
+ # Allow boolean positional values in function calls, like `dict.get(... True)`
127
+ "FBT003",
128
+ # Ignore checks for possible passwords
129
+ "S105", "S106", "S107",
130
+ # Ignore complexity
131
+ "C901", "PLR0911", "PLR0912", "PLR0913", "PLR0915",
132
+ # Ignore assert False
133
+ "B011",
134
+ "S311",
135
+ ]
136
+ unfixable = [
137
+ # Don't touch unused imports
138
+ "F401",
139
+ ]
140
+
141
+ [tool.ruff.isort]
142
+ known-first-party = ["flakytest"]
143
+
144
+ [tool.ruff.flake8-tidy-imports]
145
+ ban-relative-imports = "all"
146
+
147
+ [tool.ruff.per-file-ignores]
148
+ # Tests can use magic values, assertions, and relative imports
149
+ "tests/**/*" = ["PLR2004", "S101", "TID252"]
150
+
151
+ [tool.coverage.run]
152
+ source_pkgs = ["flakytest", "tests"]
153
+ branch = true
154
+ parallel = true
155
+ omit = [
156
+ "src/flakytest/__about__.py",
157
+ ]
158
+
159
+ [tool.coverage.paths]
160
+ flakytest = ["src/flakytest", "*/flakytest/src/flakytest"]
161
+ tests = ["tests", "*/flakytest/tests"]
162
+
163
+ [tool.coverage.report]
164
+ exclude_lines = [
165
+ "no cov",
166
+ "if __name__ == .__main__.:",
167
+ "if TYPE_CHECKING:",
168
+ ]
@@ -0,0 +1,4 @@
1
+ # SPDX-FileCopyrightText: 2023-present Anže Pečar <anze@pecar.me>
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ __version__ = "2023.0b0"
@@ -0,0 +1,3 @@
1
+ # SPDX-FileCopyrightText: 2023-present Anže Pečar <anze@pecar.me>
2
+ #
3
+ # SPDX-License-Identifier: MIT
@@ -0,0 +1,109 @@
1
+ # SPDX-FileCopyrightText: 2023-present Anže Pečar <anze@pecar.me>
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ # root
6
+ # └── pytest_cmdline_main
7
+ # ├── pytest_plugin_registered
8
+ # ├── pytest_configure
9
+ # │ └── pytest_plugin_registered
10
+ # ├── pytest_sessionstart
11
+ # │ ├── pytest_plugin_registered
12
+ # │ └── pytest_report_header
13
+ # ├── pytest_collection
14
+ # │ ├── pytest_collectstart
15
+ # │ ├── pytest_make_collect_report
16
+ # │ │ ├── pytest_collect_file
17
+ # │ │ │ └── pytest_pycollect_makemodule
18
+ # │ │ └── pytest_pycollect_makeitem
19
+ # │ │ └── pytest_generate_tests
20
+ # │ │ └── pytest_make_parametrize_id
21
+ # │ ├── pytest_collectreport
22
+ # │ ├── pytest_itemcollected
23
+ # │ ├── pytest_collection_modifyitems
24
+ # │ └── pytest_collection_finish
25
+ # │ └── pytest_report_collectionfinish
26
+ # ├── pytest_runtestloop
27
+ # │ └── pytest_runtest_protocol
28
+ # │ ├── pytest_runtest_logstart
29
+ # │ ├── pytest_runtest_setup
30
+ # │ │ └── pytest_fixture_setup
31
+ # │ ├── pytest_runtest_makereport
32
+ # │ ├── pytest_runtest_logreport
33
+ # │ │ └── pytest_report_teststatus
34
+ # │ ├── pytest_runtest_call
35
+ # │ │ └── pytest_pyfunc_call
36
+ # │ ├── pytest_runtest_teardown
37
+ # │ │ └── pytest_fixture_post_finalizer
38
+ # │ └── pytest_runtest_logfinish
39
+ # ├── pytest_sessionfinish
40
+ # │ └── pytest_terminal_summary
41
+ # └── pytest_unconfigure
42
+
43
+ # def pytest_terminal_summary(terminalreporter, exitstatus, config):
44
+ # # Add a section?
45
+ # ...
46
+ import http.client
47
+ import json
48
+ import os
49
+ import traceback
50
+
51
+ token = os.environ.get("FLAKYTEST_SECRET_TOKEN")
52
+ host = os.environ.get("FLAKYTEST_HOST", "flakytest.dev")
53
+
54
+ muted_tests = []
55
+ tests = []
56
+
57
+
58
+ def pytest_collection_modifyitems(items):
59
+ if not token:
60
+ return
61
+
62
+ headers = {"Content-type": "application/json", "Accept": "text/plain", "Authorization": token}
63
+ conn = http.client.HTTPConnection("localhost", 8001)
64
+ conn.request("GET", "/muted_tests/", headers=headers)
65
+ muted_tests[:] = json.loads(conn.getresponse().read().decode())["result"]
66
+ muted_test_set = {test["name"] for test in muted_tests}
67
+ items[:] = [item for item in items if item.nodeid not in muted_test_set]
68
+
69
+
70
+ def pytest_collection_finish(session):
71
+ if not token:
72
+ return
73
+
74
+ headers = {"Content-type": "application/json", "Accept": "text/plain", "Authorization": token}
75
+ conn = http.client.HTTPConnection(host)
76
+ conn.request("POST", "/sessions/", headers=headers)
77
+ session.stash["session_id"] = conn.getresponse().read().decode()
78
+
79
+
80
+ def pytest_sessionfinish(session, exitstatus):
81
+ # Send report end here?
82
+ if not token:
83
+ return
84
+ json_data = json.dumps(
85
+ {"tests": tests + muted_tests, "exit_status": exitstatus.name if exitstatus != 0 else "OK"}
86
+ ).encode()
87
+ headers = {"Content-type": "application/json", "Accept": "text/plain", "Authorization": token}
88
+ conn = http.client.HTTPConnection(host)
89
+ conn.request("POST", f"/sessions/{session.stash['session_id']}/finish", json_data, headers)
90
+
91
+
92
+ def pytest_runtest_makereport(item, call):
93
+ if call.when == "call":
94
+ # Get the test status
95
+ if call.excinfo is None:
96
+ status = "PASS"
97
+ elif call.excinfo.type == AssertionError:
98
+ status = "FAIL"
99
+ else:
100
+ status = "ERROR"
101
+
102
+ tests.append(
103
+ {
104
+ "name": item.nodeid,
105
+ "status": status,
106
+ "duration": call.duration,
107
+ "output": "\n".join(traceback.format_tb(call.excinfo.tb)) if call.excinfo else "",
108
+ }
109
+ )
@@ -0,0 +1,3 @@
1
+ # SPDX-FileCopyrightText: 2023-present Anže Pečar <anze@pecar.me>
2
+ #
3
+ # SPDX-License-Identifier: MIT
@@ -0,0 +1,13 @@
1
+ import random
2
+
3
+
4
+ def test_always_pass():
5
+ assert True
6
+
7
+
8
+ def test_always_fail():
9
+ assert False
10
+
11
+
12
+ def test_flaky():
13
+ assert random.randint(0, 1) < 0.5