Skip to content

Commit 3c5d269

Browse files
committed
DVX-182: Run integration tests in parallel
1 parent 08cde1f commit 3c5d269

File tree

5 files changed

+105
-0
lines changed

5 files changed

+105
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Run tests parallel
2+
3+
on:
4+
pull_request:
5+
workflow_dispatch:
6+
7+
jobs:
8+
test:
9+
runs-on: ubuntu-latest
10+
strategy:
11+
fail-fast: false
12+
matrix:
13+
job_id: ["job1", "job2"]
14+
steps:
15+
- uses: actions/checkout@v4
16+
- name: Set up Python 3.9
17+
uses: actions/setup-python@v4
18+
with:
19+
python-version: 3.9
20+
21+
- name: Install dependencies
22+
run: |
23+
sudo apt-get install -y jq
24+
python -m pip install --upgrade pip
25+
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
26+
if [ -f requirements-dev.txt ]; then pip install -r requirements-dev.txt; fi
27+
28+
- name: Run pytest in parallel
29+
env: # Test tenant environment variables
30+
ATLAN_API_KEY: ${{ secrets.ATLAN_API_KEY }}
31+
ATLAN_BASE_URL: ${{ secrets.ATLAN_BASE_URL }}
32+
MARK_API_KEY: ${{ secrets.MARK_ATLAN_API_KEY }}
33+
MARK_BASE_URL: https://mark.atlan.com
34+
run: |
35+
DISTRIBUTED_TESTS=$(python3 st.py)
36+
TEST_FILES=$(echo "${DISTRIBUTED_TESTS}" | jq -r --arg targetJob "${{ matrix.job_id }}" '.[$targetJob].test_files[]' | tr '\n' ' ')
37+
pytest ${TEST_FILES}

.sample

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"tests/integration/connection_test.py::test_invalid_connection": 0.0010759579999999325,
3+
"tests/integration/connection_test.py::test_invalid_connection_admin_group": 1.8205267080000018,
4+
"tests/integration/connection_test.py::test_invalid_connection_admin_role": 3.566417791,
5+
"tests/integration/connection_test.py::test_invalid_connection_admin_user": 13.501227625000002,
6+
"tests/integration/purpose_test.py::test_add_policies_to_purpose": 6.234852457000002,
7+
"tests/integration/purpose_test.py::test_find_purpose_by_name": 8.90930079200001,
8+
"tests/integration/purpose_test.py::test_purpose": 51.40183633299999,
9+
"tests/integration/purpose_test.py::test_retrieve_purpose": 49.65388283300001,
10+
"tests/integration/purpose_test.py::test_update_purpose": 7.971122498999989,
11+
"tests/integration/s3_asset_test.py::test_bucket": 83.91328645800002,
12+
"tests/integration/s3_asset_test.py::test_bucket_with_name": 2.5233026249999853,
13+
"tests/integration/s3_asset_test.py::test_delete_object": 21.078623375000006,
14+
"tests/integration/s3_asset_test.py::test_delete_object_with_name": 15.819571706999966,
15+
"tests/integration/s3_asset_test.py::test_object": 3.6064143319999573,
16+
"tests/integration/s3_asset_test.py::test_object_with_name": 8.101769499,
17+
"tests/integration/s3_asset_test.py::test_read_deleted_object": 1.4334719589999736,
18+
"tests/integration/s3_asset_test.py::test_read_deleted_object_with_name": 15.56822116699999,
19+
"tests/integration/s3_asset_test.py::test_restore_object": 9.909107290999998,
20+
"tests/integration/s3_asset_test.py::test_restore_object_with_name": 50.608775542000046,
21+
"tests/integration/s3_asset_test.py::test_retrieve_bucket": 1.5732482919999597,
22+
"tests/integration/s3_asset_test.py::test_retrieve_bucket_with_name": 3.184895584000003,
23+
"tests/integration/s3_asset_test.py::test_update_bucket": 25.88223066699996,
24+
"tests/integration/s3_asset_test.py::test_update_bucket_again": 20.06530891600005,
25+
"tests/integration/s3_asset_test.py::test_update_bucket_with_name": 16.880974166999977,
26+
"tests/integration/s3_asset_test.py::test_update_bucket_with_name_again": 29.425950040999908
27+
}

.sample-test

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash
2+
3+
# Read the distributed test files from the JSON file
4+
DISTRIBUTED_TESTS=$(python3 st.py)
5+
6+
TEST_FILES=$(echo $DISTRIBUTED_TESTS | jq -r --arg targetJob "job2" '.[$targetJob].test_files[]' | tr '\n' ' ')
7+
8+
echo "pytest $TEST_FILES"

requirements-dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ black==23.7.0
44
types-requests==2.31.0.2
55
pytest==7.4.0
66
pytest-order==1.1.0
7+
pytest-split==0.8.1
78
retry==0.9.2
89
pre-commit==2.20.0
910
deepdiff==6.2.1

st.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import json
2+
3+
# Read the test execution times from the JSON file
4+
with open('.sample', 'r') as f:
5+
test_durations = json.load(f)
6+
7+
# Accumulate durations for each test file
8+
accumulated_durations = {}
9+
for test, duration in test_durations.items():
10+
test_file = test.split('::')[0]
11+
accumulated_durations[test_file] = accumulated_durations.get(test_file, 0) + duration
12+
13+
# Sort test files by accumulated duration in descending order
14+
sorted_test_files = sorted(accumulated_durations.items(), key=lambda x: x[1], reverse=True)
15+
16+
# Distribute test files across multiple parallel jobs while balancing execution time
17+
num_jobs = 2 # Adjust the number of parallel jobs as needed
18+
jobs = {f'job{i+1}': {'test_files': [], 'total_time': 0} for i in range(num_jobs)}
19+
20+
for test_file, duration in sorted_test_files:
21+
# Find the job with the least total execution time
22+
min_job = min(jobs, key=lambda j: jobs[j]['total_time'])
23+
24+
# Add the test file to the selected job
25+
jobs[min_job]['test_files'].append(test_file)
26+
27+
# Update the total execution time for the selected job
28+
jobs[min_job]['total_time'] += duration
29+
30+
# Output the distributed test files for each job with total time in seconds and minutes
31+
result = {f'{job}': {'test_files': jobs[job]['test_files'], 'total_time_seconds': jobs[job]['total_time'], 'total_time_minutes': jobs[job]['total_time'] / 60} for job in jobs}
32+
print(json.dumps(result, indent=2))

0 commit comments

Comments
 (0)