pytest-jubilant 0.1.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.
@@ -0,0 +1,18 @@
1
+ Metadata-Version: 2.4
2
+ Name: pytest-jubilant
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/canonical/pytest-jubilant
7
+ Project-URL: Issues, https://github.com/canonical/pytest-jubilant/issues
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: jubilant>=0.5.0
13
+ Requires-Dist: pytest>=8.3.5
14
+
15
+ # Pytest plugin for jubilant.
16
+
17
+ Eases the transition from pytest-operator to jubilant.
18
+ And some cool stuff on top.
@@ -0,0 +1,4 @@
1
+ # Pytest plugin for jubilant.
2
+
3
+ Eases the transition from pytest-operator to jubilant.
4
+ And some cool stuff on top.
@@ -0,0 +1,28 @@
1
+ [build-system]
2
+ requires = ["setuptools >= 77.0.3"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pytest-jubilant"
7
+ version = "0.1.0"
8
+ description = "Add your description here"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8" # lower bound set by jubilant
11
+ dependencies = [
12
+ "jubilant>=0.5.0",
13
+ "pytest>=8.3.5",
14
+ ]
15
+
16
+ classifiers = [
17
+ "Programming Language :: Python :: 3",
18
+ "Operating System :: OS Independent",
19
+ ]
20
+ license = "MIT"
21
+
22
+ [project.urls]
23
+ Homepage = "https://github.com/canonical/pytest-jubilant"
24
+ Issues = "https://github.com/canonical/pytest-jubilant/issues"
25
+
26
+ [project.entry-points.pytest11]
27
+ pytest-jubilant = "pytest_jubilant.main"
28
+
@@ -0,0 +1,122 @@
1
+ import dataclasses
2
+ import logging
3
+ import shlex
4
+ import subprocess
5
+ from pathlib import Path
6
+ from typing import Union, Optional, Dict
7
+
8
+ import yaml
9
+ import pytest
10
+ import jubilant
11
+
12
+
13
+ def pytest_addoption(parser):
14
+ group = parser.getgroup("jubilant")
15
+ group.addoption(
16
+ "--model",
17
+ action="store",
18
+ default=None,
19
+ help="Juju model name to target.",
20
+ )
21
+ group.addoption(
22
+ "--keep-models",
23
+ action="store_true",
24
+ default=False,
25
+ help="Skip model teardown.",
26
+ )
27
+ group.addoption(
28
+ "--no-setup",
29
+ action="store_true",
30
+ default=False,
31
+ help='Skip tests marked with "setup".',
32
+ )
33
+ group.addoption(
34
+ "--no-teardown",
35
+ action="store_true",
36
+ default=False,
37
+ help='Skip tests marked with "teardown".',
38
+ )
39
+ group.addoption(
40
+ "--switch",
41
+ action="store_true",
42
+ default=False,
43
+ help='Switch to the temporary model that is currently being worked on.',
44
+ )
45
+
46
+
47
+ def pytest_configure(config):
48
+ config.addinivalue_line(
49
+ "markers", "setup: tests that setup some parts of the environment."
50
+ )
51
+ config.addinivalue_line(
52
+ "markers", "teardown: tests that tear down some parts of the environment."
53
+ )
54
+
55
+
56
+ def pytest_collection_modifyitems(config, items):
57
+ if config.getoption("--no-teardown"):
58
+ skipper = pytest.mark.skip(reason="--no-teardown provided.")
59
+ for item in items:
60
+ if "teardown" in item.keywords:
61
+ item.add_marker(skipper)
62
+
63
+ if config.getoption("--no-setup"):
64
+ skipper = pytest.mark.skip(reason="--no-setup provided.")
65
+ for item in items:
66
+ if "setup" in item.keywords:
67
+ item.add_marker(skipper)
68
+
69
+
70
+ @pytest.fixture(scope="module")
71
+ def juju(request):
72
+ switch = request.config.getoption("--switch")
73
+ def _maybe_switch(juju):
74
+ if switch:
75
+ juju.cli("switch", model, include_model=False)
76
+ return juju
77
+
78
+ if model := request.config.getoption("--model"):
79
+ juju = jubilant.Juju(model=model)
80
+ yield _maybe_switch(juju)
81
+
82
+ else:
83
+ with jubilant.temp_model(
84
+ keep=request.config.getoption("--keep-models")
85
+ ) as juju:
86
+ yield _maybe_switch(juju)
87
+
88
+
89
+ @dataclasses.dataclass
90
+ class _Result:
91
+ charm: Path
92
+ resources: Optional[Dict[str, str]]
93
+
94
+
95
+ def pack_charm(root: Union[Path, str] = "./") -> _Result:
96
+ """Pack a local charm and return it along with its resources."""
97
+ proc = subprocess.run(
98
+ shlex.split(f"charmcraft pack -p {root}"),
99
+ check=True,
100
+ capture_output=True,
101
+ text=True,
102
+ )
103
+
104
+ # Don't ask me why this goes to stderr.
105
+ charm = proc.stderr.strip().splitlines()[-1].split()[-1]
106
+
107
+ for meta_name in ("metadata.yaml", "charmcraft.yaml"):
108
+ if (meta_yaml := root / meta_name).exists():
109
+ logging.debug(f"found metadata file: {meta_yaml}")
110
+ meta = yaml.safe_load(meta_yaml.read_text())
111
+ resources = {
112
+ resource: res_meta["upstream-source"]
113
+ for resource, res_meta in meta["resources"].items()
114
+ }
115
+ break
116
+ else:
117
+ resources = None
118
+ logging.error(
119
+ f"metadata/charmcraft.yaml not found at {root}; unable to load resources"
120
+ )
121
+
122
+ return _Result(charm=charm, resources=resources)
@@ -0,0 +1,18 @@
1
+ Metadata-Version: 2.4
2
+ Name: pytest-jubilant
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/canonical/pytest-jubilant
7
+ Project-URL: Issues, https://github.com/canonical/pytest-jubilant/issues
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: jubilant>=0.5.0
13
+ Requires-Dist: pytest>=8.3.5
14
+
15
+ # Pytest plugin for jubilant.
16
+
17
+ Eases the transition from pytest-operator to jubilant.
18
+ And some cool stuff on top.
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ pytest_jubilant/main.py
4
+ pytest_jubilant.egg-info/PKG-INFO
5
+ pytest_jubilant.egg-info/SOURCES.txt
6
+ pytest_jubilant.egg-info/dependency_links.txt
7
+ pytest_jubilant.egg-info/entry_points.txt
8
+ pytest_jubilant.egg-info/requires.txt
9
+ pytest_jubilant.egg-info/top_level.txt
10
+ tests/test_foo.py
@@ -0,0 +1,2 @@
1
+ [pytest11]
2
+ pytest-jubilant = pytest_jubilant.main
@@ -0,0 +1,2 @@
1
+ jubilant>=0.5.0
2
+ pytest>=8.3.5
@@ -0,0 +1 @@
1
+ pytest_jubilant
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,2 @@
1
+ def test_foo():
2
+ pass