Merge ~vultaire/charm-sudo-pair:focal into charm-sudo-pair:master

Proposed by Paul Goins
Status: Merged
Approved by: Paul Goins
Approved revision: dd7e04f18d182066d08b1a532513b202c246eda2
Merged at revision: dd7e04f18d182066d08b1a532513b202c246eda2
Proposed branch: ~vultaire/charm-sudo-pair:focal
Merge into: charm-sudo-pair:master
Diff against target: 188 lines (+51/-65)
1 file modified
tests/functional/test_deploy.py (+51/-65)
Reviewer Review Type Date Requested Status
Alvaro Uria (community) Approve
Review via email: mp+384398@code.launchpad.net

Description of the change

This is a resubmit of Wouter's MR (https://code.launchpad.net/~woutervb/charm-sudo-pair/+git/sudo-pair-charm/+merge/378781), updated to apply on top of the current top-level launchpad project's trunk.

To post a comment you must log in.
Revision history for this message
Paul Goins (vultaire) wrote :

Note: the first commit is the real change, the second commit is purely black's work.

Revision history for this message
Alvaro Uria (aluria) wrote :

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/tests/functional/test_deploy.py b/tests/functional/test_deploy.py
2index cdb5ae4..2f0f272 100644
3--- a/tests/functional/test_deploy.py
4+++ b/tests/functional/test_deploy.py
5@@ -6,14 +6,16 @@ import pytest
6
7 pytestmark = pytest.mark.asyncio
8
9-charm_build_dir = os.getenv('CHARM_BUILD_DIR', '..').rstrip('/')
10+charm_build_dir = os.getenv("CHARM_BUILD_DIR", "..").rstrip("/")
11
12
13-sources = [('local', '{}/builds/sudo-pair'.format(charm_build_dir))]
14+sources = [("local", "{}/builds/sudo-pair".format(charm_build_dir))]
15
16-series = ['xenial',
17- 'bionic',
18- ]
19+series = [
20+ "xenial",
21+ "bionic",
22+ "focal",
23+]
24
25
26 ############
27@@ -36,8 +38,8 @@ def source(request):
28 @pytest.fixture
29 async def app(model, series, source):
30 """Return application of the charm under test."""
31- app_name = 'sudo-pair-{}'.format(series)
32- return await model._wait_for_new('application', app_name)
33+ app_name = "sudo-pair-{}".format(series)
34+ return await model._wait_for_new("application", app_name)
35
36
37 @pytest.fixture
38@@ -50,108 +52,92 @@ async def unit(app):
39 # TESTS #
40 #########
41
42+
43 async def test_deploy_app(model, series, source):
44 """Deploy the sudo_pair app as a subordinate of ubuntu."""
45 await model.deploy(
46- 'ubuntu',
47- application_name='ubuntu-' + series,
48- series=series,
49- channel='stable'
50+ "ubuntu", application_name="ubuntu-" + series, series=series, channel="stable"
51 )
52 sudo_pair_app = await model.deploy(
53 source[1],
54- application_name='sudo-pair-' + series,
55+ application_name="sudo-pair-" + series,
56 series=series,
57 num_units=0,
58 config={
59- 'bypass_cmds': '/bin/ls',
60- 'groups_enforced': 'ubuntu',
61- 'bypass_group': 'warthogs',
62- }
63+ "bypass_cmds": "/bin/ls",
64+ "groups_enforced": "ubuntu",
65+ "bypass_group": "warthogs",
66+ },
67 )
68 await model.add_relation(
69- 'ubuntu-{}:juju-info'.format(series),
70- 'sudo-pair-{}:juju-info'.format(series))
71+ "ubuntu-{}:juju-info".format(series), "sudo-pair-{}:juju-info".format(series)
72+ )
73
74- await model.block_until(lambda: sudo_pair_app.status == 'active')
75+ await model.block_until(lambda: sudo_pair_app.status == "active")
76 # no need to cleanup since the model will be be torn down at the end of the
77 # testing
78
79
80 async def test_status(app):
81 """Check that the app is in active state."""
82- assert app.status == 'active'
83-
84-
85-@pytest.mark.parametrize("path,expected_stat", [
86- ('/usr/lib/sudo/sudo_pair.so', {
87- 'gid': 0,
88- 'uid': 0,
89- 'mode': '0o100644'}),
90- ('/usr/bin/sudo_approve', {
91- 'gid': 0,
92- 'uid': 0,
93- 'mode': '0o100755'}),
94- ('/etc/sudo_pair.prompt.user', {
95- 'gid': 0,
96- 'uid': 0,
97- 'mode': '0o100644'}),
98- ('/etc/sudo_pair.prompt.pair', {
99- 'gid': 0,
100- 'uid': 0,
101- 'mode': '0o100644'}),
102- ('/var/run/sudo_pair', {
103- 'gid': 0,
104- 'uid': 0,
105- 'mode': '0o40644'})])
106+ assert app.status == "active"
107+
108+
109+@pytest.mark.parametrize(
110+ "path,expected_stat",
111+ [
112+ ("/usr/lib/sudo/sudo_pair.so", {"gid": 0, "uid": 0, "mode": "0o100644"}),
113+ ("/usr/bin/sudo_approve", {"gid": 0, "uid": 0, "mode": "0o100755"}),
114+ ("/etc/sudo_pair.prompt.user", {"gid": 0, "uid": 0, "mode": "0o100644"}),
115+ ("/etc/sudo_pair.prompt.pair", {"gid": 0, "uid": 0, "mode": "0o100644"}),
116+ ("/var/run/sudo_pair", {"gid": 0, "uid": 0, "mode": "0o40644"}),
117+ ],
118+)
119 async def test_stats(path, expected_stat, unit, file_stat):
120 """Check that created files have the correct permissions."""
121 test_stat = await file_stat(path, unit)
122- assert test_stat['size'] > 0
123- assert test_stat['gid'] == expected_stat['gid']
124- assert test_stat['uid'] == expected_stat['uid']
125- assert test_stat['mode'] == expected_stat['mode']
126+ assert test_stat["size"] > 0
127+ assert test_stat["gid"] == expected_stat["gid"]
128+ assert test_stat["uid"] == expected_stat["uid"]
129+ assert test_stat["mode"] == expected_stat["mode"]
130
131
132 async def test_sudoers(file_contents, unit):
133 """Check the content of sudoers file."""
134 sudoers_content = await file_contents("/etc/sudoers", unit)
135- assert 'Defaults log_output' in sudoers_content
136+ assert "Defaults log_output" in sudoers_content
137
138
139 async def test_sudoers_bypass_conf(file_contents, unit):
140 """Check the content of sudoers bypass command file."""
141 path = "/etc/sudoers.d/91-bypass-sudopair-cmds"
142- sudoers_bypass_content = await file_contents(path=path,
143- target=unit)
144- content = '%warthogs ALL = (ALL) NOLOG_OUTPUT: /bin/ls'
145+ sudoers_bypass_content = await file_contents(path=path, target=unit)
146+ content = "%warthogs ALL = (ALL) NOLOG_OUTPUT: /bin/ls"
147 assert content in sudoers_bypass_content
148
149
150 async def test_reconfigure(reconfigure_app, file_contents, unit, app):
151 """Change a charm config parameter and verify that it has been propagated to the unit."""
152- sudo_approve_path = '/usr/bin/sudo_approve'
153- await reconfigure_app(cfg={'auto_approve': 'false'},
154- target=app)
155- sudo_approve_content = await file_contents(path=sudo_approve_path,
156- target=unit)
157+ sudo_approve_path = "/usr/bin/sudo_approve"
158+ await reconfigure_app(cfg={"auto_approve": "false"}, target=app)
159+ sudo_approve_content = await file_contents(path=sudo_approve_path, target=unit)
160 new_content = 'echo "You can\'t approve your own session."'
161 assert new_content in sudo_approve_content
162
163
164 async def test_remove_relation(app, model, run_command):
165 """Check that the relation is removed."""
166- series = app.units[0].data['series']
167- app_name = 'sudo-pair-{}'.format(series)
168- principalname = 'ubuntu-{}'.format(series)
169+ series = app.units[0].data["series"]
170+ app_name = "sudo-pair-{}".format(series)
171+ principalname = "ubuntu-{}".format(series)
172 await app.remove_relation(
173- '{}:juju-info'.format(app_name),
174- '{}:juju-info'.format(principalname))
175+ "{}:juju-info".format(app_name), "{}:juju-info".format(principalname)
176+ )
177 await model.block_until(lambda: not app.relations)
178 principal = model.applications[principalname].units[0]
179- res = await run_command('test -f /etc/sudo.conf || echo gone', target=principal)
180- assert res['Stdout'].strip() == 'gone'
181+ res = await run_command("test -f /etc/sudo.conf || echo gone", target=principal)
182+ assert res["Stdout"].strip() == "gone"
183 await model.add_relation(
184- '{}:juju-info'.format(principalname),
185- '{}:juju-info'.format(app_name))
186+ "{}:juju-info".format(principalname), "{}:juju-info".format(app_name)
187+ )
188 await model.block_until(lambda: app.relations)

Subscribers

People subscribed via source and target branches