Skip to content

Commit 54df76f

Browse files
committed
Extract integration tests to standalone script
Move the integration tests that require Falcon API credentials from main.yml to a standalone test-integration.sh script. This allows: - CI to run without secrets (unit tests only) - Developers to run integration tests locally with their own credentials - The script prompts for credentials if not set as environment variables The blog post can now reference the standalone script instead of the workflow file for demonstrating integration test automation.
1 parent c74afa0 commit 54df76f

File tree

2 files changed

+141
-105
lines changed

2 files changed

+141
-105
lines changed

.github/workflows/main.yml

Lines changed: 3 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ jobs:
1414
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
1515
with:
1616
fetch-depth: 0
17+
- name: Fetch base branch for PR
18+
if: github.event_name == 'pull_request'
19+
run: git fetch origin ${{ github.event.pull_request.base.ref }}
1720
- name: Check for path changes
1821
id: changes
1922
run: |
@@ -67,9 +70,6 @@ jobs:
6770
- name: Install Python dependencies
6871
run: pip install -r requirements.txt
6972
working-directory: ${{ matrix.function }}
70-
- name: Install HTTPie for API testing
71-
run: pip install httpie
72-
if: matrix.function == 'functions/csv-import'
7373
- name: Run tests if test_main.py exists
7474
run: |
7575
if [ -f "test_main.py" ]; then
@@ -79,108 +79,6 @@ jobs:
7979
echo "No test_main.py found, skipping tests"
8080
fi
8181
working-directory: ${{ matrix.function }}
82-
- name: Run Python function and verify output
83-
env:
84-
FALCON_CLIENT_ID: ${{ secrets.FALCON_CLIENT_ID }}
85-
FALCON_CLIENT_SECRET: ${{ secrets.FALCON_CLIENT_SECRET }}
86-
FALCON_BASE_URL: ${{ secrets.FALCON_BASE_URL }}
87-
APP_ID: ${{ secrets.APP_ID }}
88-
run: |
89-
# Start the function
90-
python main.py > output.log 2>&1 &
91-
PID=$!
92-
timeout=30
93-
elapsed=0
94-
while [ $elapsed -lt $timeout ]; do
95-
if grep -q "running at port 8081" output.log; then
96-
echo "✅ Application started successfully"
97-
break
98-
fi
99-
sleep 1
100-
elapsed=$((elapsed+1))
101-
done
102-
103-
if [ $elapsed -ge $timeout ]; then
104-
echo "❌ Application failed to start within $timeout seconds"
105-
cat output.log
106-
kill $PID 2>/dev/null || true
107-
exit 1
108-
fi
109-
110-
TEST_FAILURES=0
111-
112-
# Run CSV import tests
113-
if [[ "${{ matrix.function }}" == "functions/csv-import" ]]; then
114-
echo "Running CSV import tests..."
115-
sleep 2
116-
117-
# Create sample CSV if needed
118-
if [ ! -f "security_events.csv" ]; then
119-
echo "timestamp,event_type,severity,description,source_ip,destination_ip,user" > security_events.csv
120-
echo "2025-07-11T14:14:08Z,login_failure,medium,Failed login from IP 192.168.1.100,192.168.1.100,192.168.1.1,test.user" >> security_events.csv
121-
echo "2025-07-11T14:15:22Z,malware_detected,high,Malware detected on workstation,192.168.1.101,192.168.1.1,admin.user" >> security_events.csv
122-
fi
123-
124-
# Test 1: Import CSV with file path
125-
echo "=== Test 1: Import file path ==="
126-
set +e
127-
http --ignore-stdin POST :8081 method=POST url=/import-csv "body[csv_file_path]=security_events.csv" > import_file_output.log 2>&1
128-
IMPORT_FILE_EXIT_CODE=$?
129-
set -e
130-
131-
if [ $IMPORT_FILE_EXIT_CODE -eq 0 ] && grep -q '"success": true' import_file_output.log; then
132-
echo "✅ Import file path test passed"
133-
else
134-
echo "❌ Import file path test failed"
135-
cat import_file_output.log
136-
TEST_FAILURES=$((TEST_FAILURES + 1))
137-
fi
138-
139-
# Test 2: Import CSV with inline data
140-
echo "=== Test 2: Import inline data ==="
141-
CSV_DATA=$(cat security_events.csv)
142-
set +e
143-
http --ignore-stdin POST :8081 method=POST url=/import-csv "body[csv_data]=$CSV_DATA" > import_data_output.log 2>&1
144-
IMPORT_DATA_EXIT_CODE=$?
145-
set -e
146-
147-
if [ $IMPORT_DATA_EXIT_CODE -eq 0 ] && grep -q '"success": true' import_data_output.log; then
148-
echo "✅ Import inline data test passed"
149-
else
150-
echo "❌ Import inline data test failed"
151-
cat import_data_output.log
152-
TEST_FAILURES=$((TEST_FAILURES + 1))
153-
fi
154-
155-
# Test 3: Execute import.py script
156-
if [ -f "import.py" ]; then
157-
echo "=== Test 3: Import script ==="
158-
set +e
159-
python import.py > import_script_output.log 2>&1
160-
IMPORT_SCRIPT_EXIT_CODE=$?
161-
set -e
162-
163-
if [ $IMPORT_SCRIPT_EXIT_CODE -eq 0 ] && grep -q '"success": true' import_script_output.log; then
164-
echo "✅ Import script test passed"
165-
else
166-
echo "❌ Import script test failed"
167-
cat import_script_output.log
168-
TEST_FAILURES=$((TEST_FAILURES + 1))
169-
fi
170-
fi
171-
fi
172-
173-
# Cleanup
174-
kill $PID 2>/dev/null || true
175-
176-
# Final result
177-
if [ $TEST_FAILURES -gt 0 ]; then
178-
echo "❌ $TEST_FAILURES test(s) failed"
179-
exit 1
180-
else
181-
echo "✅ All tests passed"
182-
fi
183-
working-directory: ${{ matrix.function }}
18482

18583
test-ui:
18684
needs: check-changes
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#!/bin/bash
2+
#
3+
# Integration test script for the CSV import function.
4+
# This script starts the function server and tests the import endpoints.
5+
#
6+
# Prerequisites:
7+
# - Python 3.x with dependencies installed (pip install -r requirements.txt)
8+
# - HTTPie installed (pip install httpie)
9+
# - Falcon API credentials configured
10+
#
11+
# Usage:
12+
# ./test-integration.sh
13+
#
14+
# Environment variables (will prompt if not set):
15+
# FALCON_CLIENT_ID - Your Falcon API client ID
16+
# FALCON_CLIENT_SECRET - Your Falcon API client secret
17+
# FALCON_BASE_URL - Falcon API base URL (e.g., https://api.crowdstrike.com)
18+
# APP_ID - Your Foundry app ID
19+
20+
set -e
21+
22+
# Prompt for credentials if not set
23+
if [ -z "$FALCON_CLIENT_ID" ]; then
24+
read -p "Enter FALCON_CLIENT_ID: " FALCON_CLIENT_ID
25+
export FALCON_CLIENT_ID
26+
fi
27+
28+
if [ -z "$FALCON_CLIENT_SECRET" ]; then
29+
read -s -p "Enter FALCON_CLIENT_SECRET: " FALCON_CLIENT_SECRET
30+
echo
31+
export FALCON_CLIENT_SECRET
32+
fi
33+
34+
if [ -z "$FALCON_BASE_URL" ]; then
35+
read -p "Enter FALCON_BASE_URL (e.g., https://api.crowdstrike.com): " FALCON_BASE_URL
36+
export FALCON_BASE_URL
37+
fi
38+
39+
if [ -z "$APP_ID" ]; then
40+
read -p "Enter APP_ID: " APP_ID
41+
export APP_ID
42+
fi
43+
44+
echo "Starting integration tests..."
45+
46+
# Start the function
47+
python main.py > output.log 2>&1 &
48+
PID=$!
49+
50+
# Wait for server to start
51+
timeout=30
52+
elapsed=0
53+
while [ $elapsed -lt $timeout ]; do
54+
if grep -q "running at port 8081" output.log; then
55+
echo "Application started successfully"
56+
break
57+
fi
58+
sleep 1
59+
elapsed=$((elapsed+1))
60+
done
61+
62+
if [ $elapsed -ge $timeout ]; then
63+
echo "Application failed to start within $timeout seconds"
64+
cat output.log
65+
kill $PID 2>/dev/null || true
66+
exit 1
67+
fi
68+
69+
TEST_FAILURES=0
70+
71+
echo "Running CSV import tests..."
72+
sleep 2
73+
74+
# Create sample CSV if needed
75+
if [ ! -f "security_events.csv" ]; then
76+
echo "timestamp,event_type,severity,description,source_ip,destination_ip,user" > security_events.csv
77+
echo "2025-07-11T14:14:08Z,login_failure,medium,Failed login from IP 192.168.1.100,192.168.1.100,192.168.1.1,test.user" >> security_events.csv
78+
echo "2025-07-11T14:15:22Z,malware_detected,high,Malware detected on workstation,192.168.1.101,192.168.1.1,admin.user" >> security_events.csv
79+
fi
80+
81+
# Test 1: Import CSV with file path
82+
echo "=== Test 1: Import file path ==="
83+
set +e
84+
http --ignore-stdin POST :8081 method=POST url=/import-csv "body[csv_file_path]=security_events.csv" > import_file_output.log 2>&1
85+
IMPORT_FILE_EXIT_CODE=$?
86+
set -e
87+
88+
if [ $IMPORT_FILE_EXIT_CODE -eq 0 ] && grep -q '"success": true' import_file_output.log; then
89+
echo "Import file path test passed"
90+
else
91+
echo "Import file path test failed"
92+
cat import_file_output.log
93+
TEST_FAILURES=$((TEST_FAILURES + 1))
94+
fi
95+
96+
# Test 2: Import CSV with inline data
97+
echo "=== Test 2: Import inline data ==="
98+
CSV_DATA=$(cat security_events.csv)
99+
set +e
100+
http --ignore-stdin POST :8081 method=POST url=/import-csv "body[csv_data]=$CSV_DATA" > import_data_output.log 2>&1
101+
IMPORT_DATA_EXIT_CODE=$?
102+
set -e
103+
104+
if [ $IMPORT_DATA_EXIT_CODE -eq 0 ] && grep -q '"success": true' import_data_output.log; then
105+
echo "Import inline data test passed"
106+
else
107+
echo "Import inline data test failed"
108+
cat import_data_output.log
109+
TEST_FAILURES=$((TEST_FAILURES + 1))
110+
fi
111+
112+
# Test 3: Execute import.py script
113+
if [ -f "import.py" ]; then
114+
echo "=== Test 3: Import script ==="
115+
set +e
116+
python import.py > import_script_output.log 2>&1
117+
IMPORT_SCRIPT_EXIT_CODE=$?
118+
set -e
119+
120+
if [ $IMPORT_SCRIPT_EXIT_CODE -eq 0 ] && grep -q '"success": true' import_script_output.log; then
121+
echo "Import script test passed"
122+
else
123+
echo "Import script test failed"
124+
cat import_script_output.log
125+
TEST_FAILURES=$((TEST_FAILURES + 1))
126+
fi
127+
fi
128+
129+
# Cleanup
130+
kill $PID 2>/dev/null || true
131+
132+
# Final result
133+
if [ $TEST_FAILURES -gt 0 ]; then
134+
echo "$TEST_FAILURES test(s) failed"
135+
exit 1
136+
else
137+
echo "All tests passed"
138+
fi

0 commit comments

Comments
 (0)