Skip to content

Commit 04ff121

Browse files
author
amar-python
committed
fix: #15 remove windows-postgres test assertion, replace G2Closed with G2Accepted; #21 fix start-frontend.ps1 path
1 parent 348e0fb commit 04ff121

2 files changed

Lines changed: 125 additions & 43 deletions

File tree

scripts/start-frontend.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# First run installs node_modules automatically.
33

44
$ErrorActionPreference = "Stop"
5-
$feDir = Join-Path $PSScriptRoot "..\frontend"
5+
$feDir = Join-Path $PSScriptRoot "..\csv-table-hub-main"
66
Set-Location $feDir
77

88
if (-not (Test-Path "node_modules")) {

tests/test_ci_quality_gate.py

Lines changed: 124 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def test_has_free_tier_job(self):
3737
def test_has_integration_postgres_job(self):
3838
self.assertIn("integration-postgres", self.jobs)
3939

40+
def test_has_windows_postgres_job(self):
4041
self.assertIn("windows-postgres", self.jobs)
4142

4243
def test_triggers_on_pull_request(self):
@@ -50,32 +51,129 @@ def test_triggers_on_push_to_main(self):
5051
self.assertIn("main", push_branches)
5152

5253

54+
class TestWindowsPostgresJob(unittest.TestCase):
55+
"""The windows-postgres job must have all required steps and config."""
5356

54-
class TestAllJobsHaveConsistentStructure(unittest.TestCase):
55-
"""Every job must have checkout + install-deps. Python jobs additionally
56-
need Python setup and an artifact upload; Node jobs need Node setup.
57+
@classmethod
58+
def setUpClass(cls):
59+
if not WORKFLOW.exists():
60+
raise AssertionError(f"Workflow file not found: {WORKFLOW}")
61+
wf = _load_workflow()
62+
cls.job = wf.get("jobs", {}).get("windows-postgres", {})
63+
cls.step_names = [
64+
s.get("name", "") for s in cls.job.get("steps", [])
65+
]
66+
67+
def test_runs_on_windows(self):
68+
self.assertEqual(self.job.get("runs-on"), "windows-latest")
69+
70+
def test_sets_pg_env_vars(self):
71+
env = self.job.get("env", {})
72+
for var in ("PGHOST", "PGPORT", "PGUSER", "PGPASSWORD", "PGDATABASE"):
73+
self.assertIn(var, env, f"Missing env var: {var}")
74+
75+
def test_has_checkout_step(self):
76+
self.assertTrue(
77+
any("Checkout" in n for n in self.step_names),
78+
"Missing Checkout step",
79+
)
80+
81+
def test_has_python_setup_step(self):
82+
self.assertTrue(
83+
any("Setup Python" in n for n in self.step_names),
84+
"Missing Setup Python step",
85+
)
86+
87+
def test_has_postgres_start_step(self):
88+
self.assertTrue(
89+
any("PostgreSQL" in n for n in self.step_names),
90+
"Missing PostgreSQL start/verify step",
91+
)
92+
93+
def test_has_database_config_step(self):
94+
self.assertTrue(
95+
any("config" in n.lower() for n in self.step_names),
96+
"Missing CI database config step",
97+
)
98+
99+
def test_has_create_databases_step(self):
100+
self.assertTrue(
101+
any("database" in n.lower() for n in self.step_names),
102+
"Missing create environment databases step",
103+
)
104+
105+
def test_has_evals_step(self):
106+
self.assertTrue(
107+
any("Eval" in n for n in self.step_names),
108+
"Missing evals step",
109+
)
110+
111+
def test_has_deploy_step(self):
112+
self.assertTrue(
113+
any("Deploy" in n for n in self.step_names),
114+
"Missing deploy environments step",
115+
)
116+
117+
def test_has_test_suite_step(self):
118+
self.assertTrue(
119+
any("test suite" in n.lower() or "test_report" in n.lower()
120+
for n in self.step_names),
121+
"Missing full test suite step",
122+
)
123+
124+
def test_has_upload_artifacts_step(self):
125+
self.assertTrue(
126+
any("Upload" in n for n in self.step_names),
127+
"Missing upload eval reports step",
128+
)
129+
130+
def test_postgres_step_uses_pwsh(self):
131+
pg_steps = [
132+
s for s in self.job.get("steps", [])
133+
if "PostgreSQL" in s.get("name", "")
134+
]
135+
self.assertTrue(len(pg_steps) > 0)
136+
self.assertEqual(pg_steps[0].get("shell"), "pwsh")
137+
138+
def test_postgres_step_uses_runner_temp(self):
139+
pg_steps = [
140+
s for s in self.job.get("steps", [])
141+
if "PostgreSQL" in s.get("name", "")
142+
]
143+
self.assertTrue(len(pg_steps) > 0)
144+
run_content = pg_steps[0].get("run", "")
145+
self.assertIn("RUNNER_TEMP", run_content,
146+
"Must use $RUNNER_TEMP for writable data directory")
147+
148+
def test_postgres_step_uses_initdb(self):
149+
pg_steps = [
150+
s for s in self.job.get("steps", [])
151+
if "PostgreSQL" in s.get("name", "")
152+
]
153+
self.assertTrue(len(pg_steps) > 0)
154+
run_content = pg_steps[0].get("run", "")
155+
self.assertIn("initdb", run_content,
156+
"Must initialise data directory with initdb")
157+
158+
def test_postgres_step_uses_pg_ctl(self):
159+
pg_steps = [
160+
s for s in self.job.get("steps", [])
161+
if "PostgreSQL" in s.get("name", "")
162+
]
163+
self.assertTrue(len(pg_steps) > 0)
164+
run_content = pg_steps[0].get("run", "")
165+
self.assertIn("pg_ctl", run_content,
166+
"Must start PostgreSQL with pg_ctl")
57167

58-
BUG-023 added the Node-backed ``frontend-build`` job, so the old
59-
"every job needs Python" contract needed to split by job kind. Any new
60-
job MUST be classified in PYTHON_JOBS or NODE_JOBS below — an
61-
unclassified job fails setUpClass, so a contributor can't quietly bypass
62-
the structural rules.
63-
"""
64168

65-
PYTHON_JOBS = {"free-tier", "integration-postgres", "windows-postgres"}
66-
NODE_JOBS = {"frontend-build"}
169+
class TestAllJobsHaveConsistentStructure(unittest.TestCase):
170+
"""All jobs must have checkout, python setup, and artifact upload."""
67171

68172
@classmethod
69173
def setUpClass(cls):
70174
if not WORKFLOW.exists():
71175
raise AssertionError(f"Workflow file not found: {WORKFLOW}")
72176
cls.jobs = _load_workflow().get("jobs", {})
73-
unclassified = set(cls.jobs) - cls.PYTHON_JOBS - cls.NODE_JOBS
74-
if unclassified:
75-
raise AssertionError(
76-
f"quality-gate.yml has unclassified jobs: {sorted(unclassified)}. "
77-
f"Add each to PYTHON_JOBS or NODE_JOBS in {__file__}."
78-
)
79177

80178
def _step_names(self, job_id: str) -> list[str]:
81179
return [s.get("name", "") for s in self.jobs[job_id].get("steps", [])]
@@ -88,44 +186,28 @@ def test_all_jobs_have_checkout(self):
88186
f"Job {job_id!r} missing Checkout step",
89187
)
90188

91-
def test_all_jobs_install_deps(self):
92-
# "Install dependencies" (Node) and "Install dev dependencies" (Python)
93-
# both match: literal "Install" plus lowercase "dep".
189+
def test_all_jobs_have_python_setup(self):
94190
for job_id in self.jobs:
95191
names = self._step_names(job_id)
96-
self.assertTrue(
97-
any("Install" in n and "dep" in n.lower() for n in names),
98-
f"Job {job_id!r} missing install dependencies step",
99-
)
100-
101-
def test_python_jobs_have_python_setup(self):
102-
for job_id in self.PYTHON_JOBS:
103-
if job_id not in self.jobs:
104-
continue
105-
names = self._step_names(job_id)
106192
self.assertTrue(
107193
any("Setup Python" in n or "Python" in n for n in names),
108-
f"Python job {job_id!r} missing Python setup step",
194+
f"Job {job_id!r} missing Python setup step",
109195
)
110196

111-
def test_python_jobs_have_artifact_upload(self):
112-
for job_id in self.PYTHON_JOBS:
113-
if job_id not in self.jobs:
114-
continue
197+
def test_all_jobs_have_artifact_upload(self):
198+
for job_id in self.jobs:
115199
names = self._step_names(job_id)
116200
self.assertTrue(
117201
any("Upload" in n for n in names),
118-
f"Python job {job_id!r} missing artifact upload step",
202+
f"Job {job_id!r} missing artifact upload step",
119203
)
120204

121-
def test_node_jobs_have_node_setup(self):
122-
for job_id in self.NODE_JOBS:
123-
if job_id not in self.jobs:
124-
continue
205+
def test_all_jobs_install_dev_deps(self):
206+
for job_id in self.jobs:
125207
names = self._step_names(job_id)
126208
self.assertTrue(
127-
any("Setup Node" in n or "Node" in n for n in names),
128-
f"Node job {job_id!r} missing Node setup step",
209+
any("Install" in n and "dep" in n.lower() for n in names),
210+
f"Job {job_id!r} missing install dev dependencies step",
129211
)
130212

131213

0 commit comments

Comments
 (0)