Skip to content

Commit c06166b

Browse files
GioeleB00Copilot
andauthored
Features/event generator (#1)
* setting up the generator * poisson-poisson requests sampling * Delete docker_fs/.env.dev * Delete docker_fs/.env.test * changes * refactor for event generator * added gaussian truncated generator and unit tests for helpers * imprved documentantion and simulation time handling * simulation start with the vent generator * small refactor + tests for the generation of events * minor changes * Update src/app/schemas/simulation_input.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update tests/unit/sampler/test_sampler_helper.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update scripts/quality-check.sh Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update tests/integration/db_initialization/test_init_models.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * minor changes after PR review --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent ab6c48a commit c06166b

File tree

23 files changed

+1076
-138
lines changed

23 files changed

+1076
-138
lines changed

.github/workflows/ci-develop.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ jobs:
5555

5656
# Unit-tests only (exclude integration markers)
5757
- name: Run unit tests
58+
env:
59+
ENVIRONMENT: test
5860
run: poetry run pytest -m "not integration" --disable-warnings
5961

6062

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ pip-wheel-metadata/
3030
venv/
3131
ENV/
3232
env/
33+
docker_fs/.env
34+
docker_fs/.env.*
3335

3436
# Poetry-specific
3537
.cache/pypoetry/
Lines changed: 2 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# **Development Workflow & Architecture Guide**
22

3-
This document outlines the standardized development workflow, repository architecture, and branching strategy for this project. Adhering to these guidelines ensures consistency, maintainability, and a scalable development process.
3+
This document outlines the standardized development workflow, repository architecture, and branching strategy for the backend of the FastSim project. Adhering to these guidelines ensures consistency, maintainability, and a scalable development process.
44

55
## 1. Technology Stack
66

@@ -13,13 +13,7 @@ The project is built upon the following core technologies:
1313
- **Caching**: Redis
1414
- **Containerization**: Docker
1515

16-
## 2. Architectural Overview: A Multi-Repo Strategy
17-
18-
To promote scalability, team autonomy, and clear separation of concerns, this project adopts a **multi-repo architecture**. Each core component of the system resides in its own dedicated repository. This approach allows for independent development cycles, testing, and deployment.
19-
20-
Our architecture is composed of three main repositories:
21-
22-
### 2.1. Backend Service (`project-backend`)
16+
### 2.1. Backend Service (`FastSim-backend`)
2317

2418
This repository contains all code related to the FastAPI backend service. Its primary responsibility is to handle business logic, interact with the database, and expose a RESTful API.
2519

@@ -61,69 +55,6 @@ project-backend/
6155
* To be testable in isolation.
6256
* To produce a versioned Docker image (`backend:<tag>`) as its main artifact.
6357

64-
### 2.2. Frontend Service (`project-frontend`)
65-
66-
This repository contains all code for the React web application. Its responsibility is to provide the user interface and interact with the backend via its API.
67-
68-
**Folder Structure:**
69-
```
70-
project-frontend/
71-
├── .github/
72-
│ └── workflows/
73-
│ └── main.yml # CI: Tests and publishes the frontend Docker image
74-
├── public/ # Static assets (index.html, favicon, etc.)
75-
├── src/ # Application source code
76-
│ ├── api/ # Functions for backend API calls
77-
│ ├── components/ # Reusable UI components
78-
│ ├── hooks/ # Custom React hooks
79-
│ ├── mocks/ # Service worker mocks for API (for isolated testing)
80-
│ ├── pages/ # Page components
81-
│ └── index.js # React application entrypoint
82-
├── .env.example
83-
├── .gitignore
84-
├── docker-compose.yml # Base local development definition
85-
├── Dockerfile # Multi-stage build for a lean production image
86-
├── package.json
87-
├── package-lock.json
88-
└── README.md # Setup instructions for the frontend service
89-
```
90-
91-
**Key Responsibilities:**
92-
* To be testable in isolation (using a mocked API).
93-
* To produce a versioned, production-ready Docker image (`frontend:<tag>`), typically served by Nginx.
94-
95-
### 2.3. Infrastructure & E2E Tests (`project-master`)
96-
97-
This repository is the "glue" that holds the system together. It does not contain application code but rather the configuration to orchestrate, test, and deploy the entire system.
98-
99-
**Folder Structure:**
100-
```
101-
project-master/
102-
├── .github/
103-
│ └── workflows/
104-
│ ├── e2e-tests.yml # CI: Runs End-to-End tests on a complete stack
105-
│ └── deploy.yml # CD: Handles deployment to environments
106-
├── e2e-tests/ # End-to-End test suite (e.g., Cypress, Playwright)
107-
│ ├── cypress/ # Test code
108-
│ └── cypress.config.js
109-
├── environments/ # Environment-specific configurations
110-
│ ├── staging/
111-
│ │ ├── docker-compose.yml # Docker Compose file for the Staging environment
112-
│ │ └── .env.example
113-
│ └── production/
114-
│ ├── docker-compose.yml # Docker Compose file for the Production environment
115-
│ └── .env.example
116-
├── scripts/ # Deployment and utility scripts
117-
│ ├── deploy-staging.sh
118-
│ └── deploy-prod.sh
119-
└── README.md # Main project README: explains the overall architecture
120-
```
121-
122-
**Key Responsibilities:**
123-
* To define the composition of services for each environment (Staging, Production).
124-
* To run End-to-End tests that validate the integration between services.
125-
* To manage the Continuous Deployment (CD) process.
126-
12758
## 3. Branching Strategy: Git Flow
12859

12960
To manage code development and releases in a structured manner, we use the **Git Flow** branching model.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
Below is a guided walkthrough of **`tests/unit/simulation/test_sampler_helper.py`**, explaining core ideas and each test’s intent.
2+
3+
---
4+
5+
## File purpose
6+
7+
This file verifies that your three helper functions—
8+
9+
* `uniform_variable_generator`
10+
* `poisson_variable_generator`
11+
* `truncated_gaussian_generator`
12+
13+
—correctly delegate to whatever RNG you pass in, and fall back to NumPy’s default RNG when you don’t provide one.
14+
15+
---
16+
17+
## Key testing patterns
18+
19+
1. **Dependency injection via `rng`**
20+
Each helper takes an `rng` parameter. In production you’ll pass a `np.random.Generator`; in tests we inject a **`DummyRNG`** with predictable outputs to make our tests **deterministic**.
21+
22+
2. **Duck typing**
23+
Python doesn’t require `rng` to be a specific class—only that it implements the required methods (`random()`, `poisson(mean)`, `normal(mean, sigma)`). Our `DummyRNG` simply implements those three methods.
24+
25+
3. **`typing.cast` for static typing**
26+
We wrap `DummyRNG` instances in `cast("np.random.Generator", DummyRNG(...))` so mypy sees them as satisfying the generator type, but at runtime they remain our dummy.
27+
28+
---
29+
30+
## Test-by-test breakdown
31+
32+
| Test name | What it checks |
33+
| -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
34+
| **`test_uniform_variable_generator_with_dummy_rng`** | Passing a `DummyRNG(uniform_value=0.75)`, `rng.random()` returns 0.75 → helper must return exactly 0.75. |
35+
| **`test_uniform_variable_generator_default_rng_range`** | Without supplying `rng`, the helper uses `default_rng()`. We call it 100× to ensure it always returns a `float` in \[0.0, 1.0). |
36+
| **`test_poisson_variable_generator_with_dummy_rng`** | With `DummyRNG(poisson_value=3)`, `rng.poisson(mean)` yields 3 → helper returns 3. |
37+
| **`test_poisson_variable_generator_reproducible`** | Two NumPy generators created with the same seed (`12345`) must produce the same Poisson sample for `mean=10.0`. |
38+
| **`test_truncated_gaussian_generator_truncates_negative`** | `DummyRNG(normal_value=-2.7)` forces a negative draw: helper must clamp it to **0**. |
39+
| **`test_truncated_gaussian_generator_truncates_toward_zero`** | `DummyRNG(normal_value=3.9)` forces a positive draw: helper must cast/round toward zero (int(3.9) → **3**). |
40+
| **`test_truncated_gaussian_generator_default_rng_non_negative_int`** | With a real seeded RNG, helper must produce **some** non-negative `int` (verifies default fallback path is valid). |
41+
42+
---
43+
44+
## Why this matters
45+
46+
* **Deterministic behavior**: by forcing the RNG’s output via `DummyRNG`, we can assert exactly how our helpers transform that value (clamping, rounding, type conversion).
47+
* **Fallbacks work**: tests with **no** `rng` verify that calling `default_rng()` still gives valid outputs of the correct type and range.
48+
* **Type safety**: using `cast(...)` silences mypy errors while still executing our dummy logic at runtime—ensuring we meet both static‐typing and functional correctness goals.
49+
50+
With this suite, you have **full confidence** that your sampling helpers behave correctly under both controlled (dummy) and uncontrolled (default) RNG conditions.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
Below an explanation for the unit tests in the file `tests/unit/simulation/test_simulation_input.py`
2+
3+
### 1. `test_normal_sets_variance_to_mean`
4+
5+
**Purpose:**
6+
Checks that when you create an `RVConfig` with `distribution="normal"` and omit the `variance` field, the model automatically sets `variance = mean`.
7+
8+
* Verifies the “default variance” logic in the post‐init validator.
9+
10+
---
11+
12+
### 2. `test_poisson_keeps_variance_none`
13+
14+
**Purpose:**
15+
Ensures that if you choose the Poisson distribution (`distribution="poisson"`) and do **not** supply a variance, the model **does not** fill in any default variance (keeps it `None`).
16+
17+
* Confirms that defaulting only applies to “normal”/“gaussian,” not to Poisson.
18+
19+
---
20+
21+
### 3. `test_explicit_variance_is_preserved`
22+
23+
**Purpose:**
24+
Validates that if you explicitly pass a `variance` value—even for a distribution that would normally default—it remains exactly what you provided, and is coerced to float.
25+
26+
* Guards against accidental overwriting of user‐supplied variance.
27+
28+
---
29+
30+
### 4. `test_mean_must_be_numeric`
31+
32+
**Purpose:**
33+
Verifies that giving a non‐numeric `mean` (e.g. a string) raises a `ValidationError` with our custom message `"mean must be a number"`.
34+
35+
* Tests the “before” validator on the `mean` field for type checking and coercion.
36+
37+
---
38+
39+
### 5. `test_missing_mean_field`
40+
41+
**Purpose:**
42+
Ensures that completely omitting the `mean` key triggers a standard “field required” error.
43+
44+
* Confirms that `mean` is mandatory in the schema.
45+
46+
---
47+
48+
### 6. `test_gaussian_sets_variance_to_mean`
49+
50+
**Purpose:**
51+
Exactly like the “normal” test above, but for `distribution="gaussian"`.
52+
53+
* Demonstrates that “gaussian” is treated as an alias for “normal” in the default‐variance logic.
54+
55+
---
56+
57+
### 7. `test_default_distribution_is_poisson`
58+
59+
**Purpose:**
60+
Checks two things simultaneously:
61+
62+
1. When you omit `distribution`, it defaults to `"poisson"`.
63+
2. In that default‐poisson case, `variance` remains `None`.
64+
65+
* Validates both the default distribution and its variance behavior in one test.
66+
67+
---
68+
69+
### 8. `test_explicit_variance_kept_for_poisson`
70+
71+
**Purpose:**
72+
Confirms that even if you supply a `variance` when `distribution="poisson"`, the model preserves it rather than discarding it or forcing it back to `None`.
73+
74+
* Provides symmetry to the “explicit variance” test for non‐Poisson cases.
75+
76+
---
77+
78+
### 9. `test_invalid_distribution_raises`
79+
80+
**Purpose:**
81+
Ensures that passing a value for `distribution` outside of the allowed literals (`"poisson"`, `"normal"`, `"gaussian"`) results in a `ValidationError`.
82+
83+
* Confirms that the `Literal[...]` constraint on `distribution` is enforced.
84+
85+
---
86+
87+
With these nine tests you fully cover:
88+
89+
1. **Defaulting behavior** for both “normal” and “gaussian.”
90+
2. **No‐op behavior** for Poisson defaults.
91+
3. **Preservation** of explicit user input.
92+
4. **Type‐checking** on required fields.
93+
5. **Literal‐constraint** enforcement.

0 commit comments

Comments
 (0)