fix: add cache-busting ARG to force HuggingFace rebuild
Browse filesAdd ARG CACHEBUST=1 after FROM nginx:alpine to invalidate stale build cache.
HuggingFace was executing old Dockerfile instructions despite correct commit.
This forces a complete rebuild without cached layers.
- Dockerfile +3 -0
- tests/integration/test_simulation_api.py +10 -4
- tests/unit/test_parsers.py +2 -2
Dockerfile
CHANGED
|
@@ -18,6 +18,9 @@ RUN npm run build
|
|
| 18 |
# Stage 2: Final image with nginx and Python
|
| 19 |
FROM nginx:alpine
|
| 20 |
|
|
|
|
|
|
|
|
|
|
| 21 |
# Install Python, pip, supervisor, and curl for healthcheck
|
| 22 |
RUN apk add --no-cache \
|
| 23 |
python3 \
|
|
|
|
| 18 |
# Stage 2: Final image with nginx and Python
|
| 19 |
FROM nginx:alpine
|
| 20 |
|
| 21 |
+
# Cache buster to force rebuild on HuggingFace (increment when needed)
|
| 22 |
+
ARG CACHEBUST=1
|
| 23 |
+
|
| 24 |
# Install Python, pip, supervisor, and curl for healthcheck
|
| 25 |
RUN apk add --no-cache \
|
| 26 |
python3 \
|
tests/integration/test_simulation_api.py
CHANGED
|
@@ -63,7 +63,7 @@ class TestSimulationAPI:
|
|
| 63 |
|
| 64 |
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
| 65 |
assert "config" in response.data
|
| 66 |
-
assert "Invalid
|
| 67 |
|
| 68 |
def test_simulate_endpoint_requires_config(
|
| 69 |
self,
|
|
@@ -94,7 +94,7 @@ class TestSimulationAPI:
|
|
| 94 |
|
| 95 |
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
| 96 |
assert "num_teams" in response.data
|
| 97 |
-
assert "
|
| 98 |
|
| 99 |
def test_days_endpoint_returns_ice_usage(
|
| 100 |
self,
|
|
@@ -181,7 +181,11 @@ class TestSimulationAPI:
|
|
| 181 |
self,
|
| 182 |
api_client: APIClient,
|
| 183 |
) -> None:
|
| 184 |
-
"""Test GET /profiles/overview/ endpoint.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 185 |
config_data = {
|
| 186 |
"config": "28 29",
|
| 187 |
"num_teams": 2,
|
|
@@ -195,7 +199,9 @@ class TestSimulationAPI:
|
|
| 195 |
assert response.status_code == status.HTTP_200_OK
|
| 196 |
assert "day" in response.data
|
| 197 |
assert "cost" in response.data
|
| 198 |
-
|
|
|
|
|
|
|
| 199 |
|
| 200 |
def test_spec_example_simulation(
|
| 201 |
self,
|
|
|
|
| 63 |
|
| 64 |
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
| 65 |
assert "config" in response.data
|
| 66 |
+
assert "Invalid number format" in str(response.data["config"])
|
| 67 |
|
| 68 |
def test_simulate_endpoint_requires_config(
|
| 69 |
self,
|
|
|
|
| 94 |
|
| 95 |
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
| 96 |
assert "num_teams" in response.data
|
| 97 |
+
assert "must be at least" in str(response.data["num_teams"])
|
| 98 |
|
| 99 |
def test_days_endpoint_returns_ice_usage(
|
| 100 |
self,
|
|
|
|
| 181 |
self,
|
| 182 |
api_client: APIClient,
|
| 183 |
) -> None:
|
| 184 |
+
"""Test GET /profiles/overview/ endpoint returns total days.
|
| 185 |
+
|
| 186 |
+
The endpoint now calculates and returns the actual number of
|
| 187 |
+
construction days from DailyProgress records instead of None.
|
| 188 |
+
"""
|
| 189 |
config_data = {
|
| 190 |
"config": "28 29",
|
| 191 |
"num_teams": 2,
|
|
|
|
| 199 |
assert response.status_code == status.HTTP_200_OK
|
| 200 |
assert "day" in response.data
|
| 201 |
assert "cost" in response.data
|
| 202 |
+
# Verify day is now calculated from simulation data
|
| 203 |
+
assert response.data["day"] > 0
|
| 204 |
+
assert isinstance(response.data["day"], int)
|
| 205 |
|
| 206 |
def test_spec_example_simulation(
|
| 207 |
self,
|
tests/unit/test_parsers.py
CHANGED
|
@@ -85,7 +85,7 @@ class TestConfigParser:
|
|
| 85 |
config_text = "21 -5 28"
|
| 86 |
parser = ConfigParser()
|
| 87 |
|
| 88 |
-
with pytest.raises(ValueError, match="out of range"):
|
| 89 |
parser.parse_config(config_text)
|
| 90 |
|
| 91 |
def test_parse_height_above_30_fails(self) -> None:
|
|
@@ -93,7 +93,7 @@ class TestConfigParser:
|
|
| 93 |
config_text = "21 35 28"
|
| 94 |
parser = ConfigParser()
|
| 95 |
|
| 96 |
-
with pytest.raises(ValueError, match="out of range"):
|
| 97 |
parser.parse_config(config_text)
|
| 98 |
|
| 99 |
def test_parse_too_many_sections_fails(self) -> None:
|
|
|
|
| 85 |
config_text = "21 -5 28"
|
| 86 |
parser = ConfigParser()
|
| 87 |
|
| 88 |
+
with pytest.raises(ValueError, match="out of valid range"):
|
| 89 |
parser.parse_config(config_text)
|
| 90 |
|
| 91 |
def test_parse_height_above_30_fails(self) -> None:
|
|
|
|
| 93 |
config_text = "21 35 28"
|
| 94 |
parser = ConfigParser()
|
| 95 |
|
| 96 |
+
with pytest.raises(ValueError, match="out of valid range"):
|
| 97 |
parser.parse_config(config_text)
|
| 98 |
|
| 99 |
def test_parse_too_many_sections_fails(self) -> None:
|