Skip to content

Commit 596a082

Browse files
Merge issue #97 deployment smoke parity
2 parents 3391276 + dd02a3c commit 596a082

3 files changed

Lines changed: 47 additions & 6 deletions

File tree

_docs/compatibility/development-terminology-allowlist.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@
180180
},
181181
{
182182
"path": "core/tests/test_deployment_release.py",
183-
"sha256": "294d3a34c17bfa6c9eb15f1383d5cab43771e2b0fefdd04e23a278f4e57d22f3",
183+
"sha256": "155633580c16bca93c8021b06ba65e8a28760597c45eddb157d134e3f73cf533",
184184
"class": "legacy_contract_test",
185185
"reason": "Release tests exercise exact physical task, secret, repository, and tag values.",
186186
"follow_up": "#94",

core/tests/test_deployment_release.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,6 +1746,7 @@ def test_http_smoke_checks_safe_404_and_writes_only_redacted_evidence(self) -> N
17461746
200,
17471747
noindex,
17481748
b"Learn data skills. For free. Together."
1749+
b'<link rel="canonical" href="https://datatalks.club/courses/">'
17491750
b'<link rel="stylesheet" href="/static/courses.fixture.css">',
17501751
),
17511752
Response(
@@ -1795,12 +1796,18 @@ def test_http_smoke_checks_safe_404_and_writes_only_redacted_evidence(self) -> N
17951796
)
17961797
persisted = path.read_text()
17971798
self.assertEqual(__import__("json").loads(persisted), evidence)
1799+
courses_check = next(
1800+
check for check in evidence["checks"] if check.get("path") == "/courses/"
1801+
)
1802+
self.assertTrue(courses_check["exact_canonical"])
1803+
self.assertNotIn("canonical_absent", courses_check)
17981804
self.assertEqual(evidence["checks"][-1]["runtime_group"], "analytics")
17991805
for forbidden in ("cookie", "authorization", "set-cookie", "response_body"):
18001806
self.assertNotIn(forbidden, persisted.lower())
18011807

18021808
invalid_surface_responses = (
18031809
(
1810+
"home identity",
18041811
2,
18051812
Response(
18061813
200,
@@ -1811,6 +1818,7 @@ def test_http_smoke_checks_safe_404_and_writes_only_redacted_evidence(self) -> N
18111818
"home page lacks expected content",
18121819
),
18131820
(
1821+
"course identity",
18141822
4,
18151823
Response(
18161824
200,
@@ -1821,8 +1829,8 @@ def test_http_smoke_checks_safe_404_and_writes_only_redacted_evidence(self) -> N
18211829
"course discovery lacks expected content",
18221830
),
18231831
)
1824-
for response_index, invalid_response, error_message in invalid_surface_responses:
1825-
with self.subTest(error_message=error_message):
1832+
for case, response_index, invalid_response, error_message in invalid_surface_responses:
1833+
with self.subTest(case=case):
18261834
invalid_responses = [*responses]
18271835
invalid_responses[response_index] = invalid_response
18281836
with (
@@ -1831,6 +1839,38 @@ def test_http_smoke_checks_safe_404_and_writes_only_redacted_evidence(self) -> N
18311839
):
18321840
run_http_smoke("https://web.dtcdev.click", SHA_A)
18331841

1842+
exact_courses_canonical = b'<link rel="canonical" href="https://datatalks.club/courses/">'
1843+
invalid_courses_canonicals = (
1844+
("missing", b""),
1845+
("duplicate", exact_courses_canonical * 2),
1846+
(
1847+
"wrong path",
1848+
b'<link rel="canonical" href="https://datatalks.club/courses/wrong/">',
1849+
),
1850+
(
1851+
"external",
1852+
b'<link rel="canonical" href="https://example.com/courses/">',
1853+
),
1854+
)
1855+
for case, rendered_canonical in invalid_courses_canonicals:
1856+
invalid_responses = [*responses]
1857+
invalid_responses[4] = Response(
1858+
200,
1859+
noindex,
1860+
b"Learn data skills. For free. Together."
1861+
+ rendered_canonical
1862+
+ b'<link rel="stylesheet" href="/static/courses.fixture.css">',
1863+
)
1864+
with (
1865+
self.subTest(case=case),
1866+
patch("deploy.smoke._request", side_effect=invalid_responses),
1867+
self.assertRaisesMessage(
1868+
ReleaseContractError,
1869+
"course discovery production canonical differs",
1870+
),
1871+
):
1872+
run_http_smoke("https://web.dtcdev.click", SHA_A)
1873+
18341874
invalid_admin_responses = (
18351875
(
18361876
Response(

deploy/smoke.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,9 @@ def run_http_smoke(
165165
raise ReleaseContractError("course discovery lacks expected content")
166166
if "The place to talk about data" in courses_html:
167167
raise ReleaseContractError("course discovery regressed to the main-site home")
168-
if 'rel="canonical"' in courses_html:
169-
raise ReleaseContractError("adopted course discovery has a guessed canonical")
168+
courses_canonical = '<link rel="canonical" href="https://datatalks.club/courses/">'
169+
if courses_html.count(courses_canonical) != 1 or courses_html.count('rel="canonical"') != 1:
170+
raise ReleaseContractError("course discovery production canonical differs")
170171

171172
studio = _request(origin, "/studio/")
172173
if studio.status not in {301, 302, 303, 307, 308}:
@@ -269,7 +270,7 @@ def run_http_smoke(
269270
"status": 200,
270271
"noindex": True,
271272
"course_discovery": True,
272-
"canonical_absent": True,
273+
"exact_canonical": True,
273274
},
274275
{
275276
"path": "/studio/",

0 commit comments

Comments
 (0)