Skip to content

Commit 7e4056e

Browse files
2 parents 13af84f + 5b6f6fa commit 7e4056e

83 files changed

Lines changed: 13570 additions & 328 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test.yml

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ on:
99
- 'src/backend-api/**/*.py'
1010
- 'src/backend-api/pyproject.toml'
1111
- 'src/backend-api/pytest.ini'
12+
- 'src/processor/**/*.py'
13+
- 'src/processor/pyproject.toml'
1214
- '.github/workflows/test.yml'
1315
pull_request:
1416
types:
@@ -23,6 +25,8 @@ on:
2325
- 'src/backend-api/**/*.py'
2426
- 'src/backend-api/pyproject.toml'
2527
- 'src/backend-api/pytest.ini'
28+
- 'src/processor/**/*.py'
29+
- 'src/processor/pyproject.toml'
2630
- '.github/workflows/test.yml'
2731

2832
permissions:
@@ -36,10 +40,10 @@ jobs:
3640

3741
steps:
3842
- name: Checkout code
39-
uses: actions/checkout@v5
43+
uses: actions/checkout@v4
4044

4145
- name: Set up Python
42-
uses: actions/setup-python@v6
46+
uses: actions/setup-python@v5
4347
with:
4448
python-version: "3.12"
4549

@@ -48,7 +52,7 @@ jobs:
4852
python -m pip install --upgrade pip
4953
cd src/backend-api
5054
pip install -e .
51-
pip install pytest pytest-cov
55+
pip install pytest pytest-cov pytest-asyncio
5256
5357
- name: Check if Backend Test Files Exist
5458
id: check_backend_tests
@@ -71,9 +75,26 @@ jobs:
7175
--cov=src/app \
7276
--cov-report=term-missing \
7377
--cov-report=xml:reports/coverage.xml \
78+
--cov-fail-under=82 \
7479
--junitxml=pytest.xml \
7580
-v
7681
82+
- name: Prefix coverage XML filenames with repo-root path
83+
if: env.skip_backend_tests == 'false'
84+
run: |
85+
python <<'PY'
86+
import xml.etree.ElementTree as ET
87+
path = "src/backend-api/reports/coverage.xml"
88+
prefix = "src/backend-api/src/app/"
89+
tree = ET.parse(path)
90+
root = tree.getroot()
91+
for cls in root.iter("class"):
92+
fname = cls.attrib.get("filename", "")
93+
if fname and not fname.startswith(prefix):
94+
cls.attrib["filename"] = prefix + fname
95+
tree.write(path, xml_declaration=True, encoding="utf-8")
96+
PY
97+
7798
- name: Pytest Coverage Comment
7899
if: |
79100
always() &&
@@ -90,3 +111,80 @@ jobs:
90111
if: env.skip_backend_tests == 'true'
91112
run: |
92113
echo "Skipping backend tests because no test files were found."
114+
115+
processor_tests:
116+
runs-on: ubuntu-latest
117+
118+
steps:
119+
- name: Checkout code
120+
uses: actions/checkout@v4
121+
122+
- name: Set up Python
123+
uses: actions/setup-python@v5
124+
with:
125+
python-version: "3.12"
126+
127+
- name: Install Processor Dependencies
128+
run: |
129+
python -m pip install --upgrade pip
130+
cd src/processor
131+
pip install -e .
132+
pip install pytest pytest-cov pytest-asyncio
133+
134+
- name: Check if Processor Test Files Exist
135+
id: check_processor_tests
136+
run: |
137+
if [ -z "$(find src/processor/src/tests -type f -name 'test_*.py' 2>/dev/null)" ]; then
138+
echo "No processor test files found, skipping processor tests."
139+
echo "skip_processor_tests=true" >> $GITHUB_ENV
140+
else
141+
echo "Processor test files found, running tests."
142+
echo "skip_processor_tests=false" >> $GITHUB_ENV
143+
fi
144+
145+
- name: Run Processor Tests with Coverage
146+
if: env.skip_processor_tests == 'false'
147+
run: |
148+
cd src/processor
149+
pytest src/tests \
150+
--cov=src \
151+
--cov-report=term-missing \
152+
--cov-report=xml:reports/coverage.xml \
153+
--cov-fail-under=82 \
154+
--junitxml=pytest.xml \
155+
-v
156+
157+
- name: Prefix coverage XML filenames with repo-root path
158+
if: env.skip_processor_tests == 'false'
159+
run: |
160+
python <<'PY'
161+
import xml.etree.ElementTree as ET
162+
path = "src/processor/reports/coverage.xml"
163+
prefix = "src/processor/src/"
164+
tree = ET.parse(path)
165+
root = tree.getroot()
166+
for cls in root.iter("class"):
167+
fname = cls.attrib.get("filename", "")
168+
if fname and not fname.startswith(prefix):
169+
cls.attrib["filename"] = prefix + fname
170+
tree.write(path, xml_declaration=True, encoding="utf-8")
171+
PY
172+
173+
- name: Pytest Coverage Comment (Processor)
174+
if: |
175+
always() &&
176+
github.event_name == 'pull_request' &&
177+
github.event.pull_request.head.repo.fork == false &&
178+
env.skip_processor_tests == 'false'
179+
uses: MishaKav/pytest-coverage-comment@26f986d2599c288bb62f623d29c2da98609e9cd4 # v1.6.0
180+
with:
181+
pytest-xml-coverage-path: src/processor/reports/coverage.xml
182+
junitxml-path: src/processor/pytest.xml
183+
title: Processor Coverage Report
184+
unique-id-for-comment: processor
185+
report-only-changed-files: true
186+
187+
- name: Skip Processor Tests
188+
if: env.skip_processor_tests == 'true'
189+
run: |
190+
echo "Skipping processor tests because no test files were found."

infra/main.bicep

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,12 @@ module containerAppsEnvironment 'br/public:avm/res/app/managed-environment:0.11.
11101110
params: {
11111111
name: 'cae-${solutionSuffix}'
11121112
location: location
1113+
tags: {
1114+
...resourceGroup().tags
1115+
...existingTags
1116+
...allTags
1117+
...tags
1118+
}
11131119
managedIdentities: { systemAssigned: true }
11141120
appLogsConfiguration: enableMonitoring
11151121
? {

infra/main.json

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
"metadata": {
66
"_generator": {
77
"name": "bicep",
8-
"version": "0.43.1.21952",
9-
"templateHash": "1278209883407272359"
8+
"version": "0.43.8.12551",
9+
"templateHash": "13087590133917597872"
1010
}
1111
},
1212
"parameters": {
@@ -4715,8 +4715,8 @@
47154715
"metadata": {
47164716
"_generator": {
47174717
"name": "bicep",
4718-
"version": "0.43.1.21952",
4719-
"templateHash": "4488065934246762087"
4718+
"version": "0.43.8.12551",
4719+
"templateHash": "4604761290796021104"
47204720
}
47214721
},
47224722
"definitions": {
@@ -26135,8 +26135,8 @@
2613526135
},
2613626136
"dependsOn": [
2613726137
"appIdentity",
26138-
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageQueue)]",
2613926138
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageBlob)]",
26139+
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageQueue)]",
2614026140
"virtualNetwork"
2614126141
]
2614226142
},
@@ -30103,8 +30103,8 @@
3010330103
"metadata": {
3010430104
"_generator": {
3010530105
"name": "bicep",
30106-
"version": "0.43.1.21952",
30107-
"templateHash": "17526785557845507677"
30106+
"version": "0.43.8.12551",
30107+
"templateHash": "13516349791985095953"
3010830108
}
3010930109
},
3011030110
"definitions": {
@@ -33853,8 +33853,8 @@
3385333853
},
3385433854
"dependsOn": [
3385533855
"aiFoundryAiServices",
33856-
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').openAI)]",
3385733856
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)]",
33857+
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').openAI)]",
3385833858
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').aiServices)]",
3385933859
"virtualNetwork"
3386033860
]
@@ -33892,8 +33892,8 @@
3389233892
"metadata": {
3389333893
"_generator": {
3389433894
"name": "bicep",
33895-
"version": "0.43.1.21952",
33896-
"templateHash": "8251376928798842081"
33895+
"version": "0.43.8.12551",
33896+
"templateHash": "17583277036649944863"
3389733897
}
3389833898
},
3389933899
"parameters": {
@@ -38362,6 +38362,9 @@
3836238362
"location": {
3836338363
"value": "[parameters('location')]"
3836438364
},
38365+
"tags": {
38366+
"value": "[shallowMerge(createArray(resourceGroup().tags, variables('existingTags'), variables('allTags'), parameters('tags')))]"
38367+
},
3836538368
"managedIdentities": {
3836638369
"value": {
3836738370
"systemAssigned": true

infra/main.parameters.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
},
4141
"imageTag": {
4242
"value": "${AZURE_ENV_IMAGE_TAG}"
43+
},
44+
"tags": {
45+
"value": "${AZURE_ENV_TAGS}"
4346
}
4447
}
4548
}

infra/main.waf.parameters.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@
5555
},
5656
"vmSize": {
5757
"value": "${AZURE_ENV_VM_SIZE}"
58+
},
59+
"tags": {
60+
"value": "${AZURE_ENV_TAGS}"
5861
}
5962
}
6063
}

infra/main_custom.bicep

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,6 +1063,12 @@ module containerAppsEnvironment 'br/public:avm/res/app/managed-environment:0.11.
10631063
params: {
10641064
name: 'cae-${solutionSuffix}'
10651065
location: location
1066+
tags: {
1067+
...resourceGroup().tags
1068+
...existingTags
1069+
...allTags
1070+
...tags
1071+
}
10661072
managedIdentities: { systemAssigned: true }
10671073
appLogsConfiguration: enableMonitoring
10681074
? {

infra/modules/cosmosDb.bicep

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ module cosmosAccount 'br/public:avm/res/document-db/database-account:0.15.1' = {
4949
name: take('avm.res.document-db.account.${name}', 64)
5050
params: {
5151
name: name
52-
enableAnalyticalStorage: true
5352
location: location
5453
minimumTlsVersion: 'Tls12'
5554
defaultConsistencyLevel: 'Session'

src/backend-api/pyproject.toml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,26 @@ dependencies = [
1616
"httpx==0.28.1",
1717
"pydantic-settings==2.10.1",
1818
"python-dotenv==1.2.2",
19-
"python-multipart==0.0.26",
19+
"python-multipart==0.0.27",
2020
"protobuf==7.34.0",
2121
"sas-cosmosdb==0.1.4",
2222
"semantic-kernel==1.40.0",
2323
"uvicorn==0.35.0",
2424
]
2525

2626
[dependency-groups]
27-
dev = ["pytest>=9.0.3", "pytest-cov>=6.2.1"]
27+
dev = ["pytest>=9.0.3", "pytest-cov>=6.2.1", "pytest-asyncio>=0.23.0"]
28+
29+
[tool.coverage.run]
30+
omit = ["src/tests/*"]
2831

2932
[tool.uv]
3033
override-dependencies = [
3134
"av==16.0.0",
3235
"starlette==0.49.1",
3336
"aiohttp==3.13.4",
3437
"azure-core==1.38.0",
35-
"urllib3==2.6.3",
38+
"urllib3==2.7.0",
3639
"requests==2.33.0",
3740
"werkzeug==3.1.4",
3841
"pygments==2.20.0",
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""Tests for application.Application bootstrap."""
2+
3+
from application import Application
4+
from libs.base.typed_fastapi import TypedFastAPI
5+
from libs.services.interfaces import IDataService, IHttpService, ILoggerService
6+
from libs.services.process_services import ProcessService
7+
8+
9+
def test_application_initializes_typed_fastapi():
10+
app = Application()
11+
assert isinstance(app.app, TypedFastAPI)
12+
assert app.app.title == "FastAPI Application"
13+
assert app.app.version == "1.0.0"
14+
15+
16+
def test_application_sets_app_context_on_app():
17+
app = Application()
18+
assert app.app.app_context is app.application_context
19+
20+
21+
def test_application_registers_core_services():
22+
app = Application()
23+
ctx = app.application_context
24+
assert ctx.get_service(ILoggerService) is not None
25+
assert ctx.get_service(IHttpService) is not None
26+
assert ctx.get_service(IDataService) is not None
27+
assert ctx.get_service(ProcessService) is not None
28+
29+
30+
def test_application_includes_routers():
31+
app = Application()
32+
paths = {route.path for route in app.app.routes}
33+
# router_files
34+
assert "/api/file/upload" in paths
35+
# router_process
36+
assert "/api/process/create" in paths
37+
# http_probes
38+
assert "/health" in paths

0 commit comments

Comments
 (0)