Skip to content

Commit e77ae92

Browse files
add unit testing to ci_cd
1 parent d6afe5e commit e77ae92

File tree

4 files changed

+128
-58
lines changed

4 files changed

+128
-58
lines changed

.github/workflows/ci_cd.yml

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ name: CI/CD
22
on:
33
pull_request:
44
push:
5-
tags:
6-
- "*"
7-
branches:
8-
- main
9-
5+
106
env:
117
MAIN_PYTHON_VERSION: '3.12'
128

@@ -26,6 +22,40 @@ jobs:
2622
- name: "Run PyAnsys code style checks"
2723
uses: ansys/actions/code-style@v6
2824

25+
tests:
26+
name: "Tests"
27+
runs-on: ${{ matrix.os }}
28+
needs: [code-style]
29+
strategy:
30+
matrix:
31+
os: [ubuntu-latest, windows-latest]
32+
python-version: ['3.9', '3.12']
33+
fail-fast: false
34+
steps:
35+
- name: Testing (Linux)
36+
uses: ansys/actions/tests-pytest@v6
37+
timeout-minutes: 12
38+
if: runner.os == 'Linux'
39+
with:
40+
checkout: false
41+
pytest-extra-args: "--cov=ansys.allie.flowkit.python --cov-report=term --cov-report=html:.cov/html --cov-report=xml:.cov/coverage.xml"
42+
43+
- name: Testing (Windows)
44+
uses: ansys/actions/tests-pytest@v6
45+
timeout-minutes: 12
46+
if: runner.os == 'Windows'
47+
with:
48+
checkout: false
49+
pytest-extra-args: "--cov=ansys.allie.flowkit.python --cov-report=term --cov-report=html:.cov/html --cov-report=xml:.cov/coverage.xml"
50+
51+
- name: Upload coverage results (HTML)
52+
uses: actions/upload-artifact@v4
53+
if: (matrix.python-version == env.MAIN_PYTHON_VERSION) && (runner.os == 'Linux')
54+
with:
55+
name: coverage-html
56+
path: .cov/html
57+
retention-days: 7
58+
2959
release:
3060
name: "Release project"
3161
if: github.event_name == 'push' && contains(github.ref, 'refs/tags')

tests/conftest.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
import pytest
21
from unittest.mock import patch
32

3+
import pytest
4+
45
# Mock API key for testing
56
MOCK_API_KEY = "test_api_key"
67

8+
79
@pytest.fixture(autouse=True)
810
def mock_api_key():
911
"""Mock the API key for testing."""
10-
with patch('app.config.CONFIG.flowkit_python_api_key', MOCK_API_KEY):
11-
yield
12+
with patch("app.config.CONFIG.flowkit_python_api_key", MOCK_API_KEY):
13+
yield

tests/test_endpoints_splitter.py

Lines changed: 24 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import base64
2-
from fastapi import HTTPException
3-
import pytest
4-
from fastapi.testclient import TestClient
2+
53
from app.app import app
64
from app.endpoints.splitter import validate_request
75
from app.models.splitter import SplitterRequest
6+
from fastapi import HTTPException
7+
from fastapi.testclient import TestClient
8+
import pytest
9+
810
from tests.conftest import MOCK_API_KEY
911

1012
# Create a test client
1113
client = TestClient(app)
1214

15+
1316
def encode_file_to_base64(file_path):
1417
"""Encode a file to base64 string."""
1518
with open(file_path, "rb") as file:
16-
return base64.b64encode(file.read()).decode('utf-8')
19+
return base64.b64encode(file.read()).decode("utf-8")
20+
1721

1822
@pytest.mark.asyncio
1923
async def test_split_ppt():
@@ -22,111 +26,81 @@ async def test_split_ppt():
2226
request_payload = {
2327
"document_content": ppt_content_base64,
2428
"chunk_size": 100,
25-
"chunk_overlap": 10
29+
"chunk_overlap": 10,
2630
}
27-
response = client.post(
28-
"/splitter/ppt",
29-
json=request_payload,
30-
headers={"api-key": MOCK_API_KEY}
31-
)
31+
response = client.post("/splitter/ppt", json=request_payload, headers={"api-key": MOCK_API_KEY})
3232
if response.status_code != 200:
3333
print(f"Response status code: {response.status_code}")
3434
print(f"Response content: {response.json()}")
3535
assert response.status_code == 200
3636
assert "chunks" in response.json()
3737

38+
3839
@pytest.mark.asyncio
3940
async def test_split_py():
4041
"""Test splitting Python code into chunks."""
4142
python_code = """
4243
def hello_world():
4344
print("Hello, world!")
4445
"""
45-
python_code_base64 = base64.b64encode(python_code.encode()).decode('utf-8')
46-
request_payload = {
47-
"document_content": python_code_base64,
48-
"chunk_size": 50,
49-
"chunk_overlap": 5
50-
}
51-
response = client.post(
52-
"/splitter/py",
53-
json=request_payload,
54-
headers={"api-key": MOCK_API_KEY}
55-
)
46+
python_code_base64 = base64.b64encode(python_code.encode()).decode("utf-8")
47+
request_payload = {"document_content": python_code_base64, "chunk_size": 50, "chunk_overlap": 5}
48+
response = client.post("/splitter/py", json=request_payload, headers={"api-key": MOCK_API_KEY})
5649
assert response.status_code == 200
5750
assert "chunks" in response.json()
5851

52+
5953
@pytest.mark.asyncio
6054
async def test_split_pdf():
6155
"""Test splitting text in a PDF document into chunks."""
6256
pdf_content_base64 = encode_file_to_base64("./tests/test_files/test_document.pdf")
6357
request_payload = {
6458
"document_content": pdf_content_base64,
6559
"chunk_size": 200,
66-
"chunk_overlap": 20
60+
"chunk_overlap": 20,
6761
}
68-
response = client.post(
69-
"/splitter/pdf",
70-
json=request_payload,
71-
headers={"api-key": MOCK_API_KEY}
72-
)
62+
response = client.post("/splitter/pdf", json=request_payload, headers={"api-key": MOCK_API_KEY})
7363
assert response.status_code == 200
7464
assert "chunks" in response.json()
7565

66+
7667
# Define test cases for validate_request()
7768
validate_request_test_cases = [
7869
# Test case 1: valid request
7970
(
8071
SplitterRequest(
81-
document_content="dGVzdA==", # base64 for "test"
82-
chunk_size=100,
83-
chunk_overlap=10
72+
document_content="dGVzdA==", chunk_size=100, chunk_overlap=10 # base64 for "test"
8473
),
8574
MOCK_API_KEY,
8675
None,
8776
),
8877
# Test case: invalid API key
8978
(
90-
SplitterRequest(
91-
document_content="dGVzdA==",
92-
chunk_size=100,
93-
chunk_overlap=10
94-
),
79+
SplitterRequest(document_content="dGVzdA==", chunk_size=100, chunk_overlap=10),
9580
"invalid_api_key",
9681
HTTPException(status_code=401, detail="Invalid API key"),
9782
),
9883
# Test case 2: missing document content
9984
(
100-
SplitterRequest(
101-
document_content="",
102-
chunk_size=100,
103-
chunk_overlap=10
104-
),
85+
SplitterRequest(document_content="", chunk_size=100, chunk_overlap=10),
10586
MOCK_API_KEY,
10687
HTTPException(status_code=400, detail="No document content provided"),
10788
),
10889
# Test case 4: invalid chunk size
10990
(
110-
SplitterRequest(
111-
document_content="dGVzdA==",
112-
chunk_size=0,
113-
chunk_overlap=10
114-
),
91+
SplitterRequest(document_content="dGVzdA==", chunk_size=0, chunk_overlap=10),
11592
MOCK_API_KEY,
11693
HTTPException(status_code=400, detail="No chunk size provided"),
11794
),
11895
# Test case 5: invalid chunk overlap
11996
(
120-
SplitterRequest(
121-
document_content="dGVzdA==",
122-
chunk_size=100,
123-
chunk_overlap=-1
124-
),
97+
SplitterRequest(document_content="dGVzdA==", chunk_size=100, chunk_overlap=-1),
12598
MOCK_API_KEY,
12699
HTTPException(status_code=400, detail="Chunk overlap must be greater than or equal to 0"),
127100
),
128101
]
129102

103+
130104
@pytest.mark.parametrize("api_request, api_key, expected_exception", validate_request_test_cases)
131105
def test_validate_request(api_request, api_key, expected_exception):
132106
"""Test the validate_request function with various scenarios."""

tests/test_list_functions.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import pytest
2+
from fastapi.testclient import TestClient
3+
from app.app import app
4+
5+
# Initialize the test client
6+
client = TestClient(app)
7+
8+
@pytest.mark.asyncio
9+
async def test_list_functions():
10+
"""Test listing available functions."""
11+
# Test splitter results
12+
response = client.get("/", headers={"api-key": "test_api_key"})
13+
assert response.status_code == 200
14+
response_data = response.json()
15+
16+
expected_response_start = [
17+
{
18+
"name": "split_ppt",
19+
"path": "/splitter/ppt",
20+
"inputs": [
21+
{"name": "document_content", "type": "string(binary)"},
22+
{"name": "chunk_size", "type": "integer"},
23+
{"name": "chunk_overlap", "type": "integer"}
24+
],
25+
"outputs": [
26+
{"name": "chunks", "type": "array<string>"}
27+
],
28+
"definitions": {}
29+
},
30+
{
31+
"name": "split_py",
32+
"path": "/splitter/py",
33+
"inputs": [
34+
{"name": "document_content", "type": "string(binary)"},
35+
{"name": "chunk_size", "type": "integer"},
36+
{"name": "chunk_overlap", "type": "integer"}
37+
],
38+
"outputs": [
39+
{"name": "chunks", "type": "array<string>"}
40+
],
41+
"definitions": {}
42+
},
43+
{
44+
"name": "split_pdf",
45+
"path": "/splitter/pdf",
46+
"inputs": [
47+
{"name": "document_content", "type": "string(binary)"},
48+
{"name": "chunk_size", "type": "integer"},
49+
{"name": "chunk_overlap", "type": "integer"}
50+
],
51+
"outputs": [
52+
{"name": "chunks", "type": "array<string>"}
53+
],
54+
"definitions": {}
55+
}
56+
]
57+
58+
assert response_data[:3] == expected_response_start
59+
60+
# Test invalid API key
61+
response = client.get("/", headers={"api-key": "invalid_api_key"})
62+
assert response.status_code == 401
63+
assert response.json() == {"detail": "Invalid API key"}
64+

0 commit comments

Comments
 (0)