-
Notifications
You must be signed in to change notification settings - Fork 18
429 lines (344 loc) · 16.8 KB
/
test-mcp-server.yml
File metadata and controls
429 lines (344 loc) · 16.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
name: Test API Endpoints and CLI
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4.2.2
- name: Install Python and dependencies
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Install jq and curl
run: sudo apt-get install -y jq curl
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Set up env
run: |
echo "LLM_API_BASE=${{ env.LLM_API_BASE }}" > .env.temp
echo "LLM_API_KEY=${{ secrets.LLM_API_KEY }}" >> .env.temp
echo "LLM_MODEL=${{ env.LLM_MODEL }}" >> .env.temp
echo "LLM_EMBED_MODEL=${{ env.LLM_EMBED_MODEL }}" >> .env.temp
echo "LLM_EMBED_SIZE=${{ env.LLM_EMBED_SIZE }}" >> .env.temp
- name: Run docker compose
uses: hoverkraft-tech/compose-action@v2.0.1
with:
compose-file: ./docker-compose.yml
compose-flags: "--env-file .env.temp"
up-flags: "-d --build"
- name: Wait for services to be ready
run: |
echo "Waiting for services to be ready..."
sleep 60
docker ps
- name: Verify container readiness
run: |
docker ps
# Only check for API and qdrant since MCP services are commented out
for container in api qdrant; do
if ! docker ps | grep -q "$container"; then
echo "ERROR: $container is not running!"
docker compose logs --tail=100 "$container" || echo "Could not get logs for $container"
exit 1
fi
done
echo "All containers are running."
- name: Test /compile endpoint
run: |
echo "Testing /compile endpoint..."
RESPONSE=$(curl -s -S -f -X POST http://localhost:8000/compile \
-H "Content-Type: application/json" \
-d '{
"code": "[filename: Cargo.toml]\n[package]\nname = \"hello_world\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n[dependencies]\n\n[filename: src/main.rs]\nfn main() {\n println!(\"Hello, World!\");\n}"
}' || echo "CURL_FAILED")
if [ "$RESPONSE" = "CURL_FAILED" ]; then
echo "Failed to connect to API service"
docker ps
docker logs $(docker ps -q --filter name=api)
exit 1
fi
# Check for success in response
if ! echo "$RESPONSE" | jq -e '.success == true' > /dev/null; then
echo "Compilation failed:"
echo "$RESPONSE" | jq || echo "$RESPONSE"
exit 1
fi
echo "Compilation successful!"
echo "$RESPONSE" | jq || echo "$RESPONSE"
- name: Test /compile-and-fix endpoint
run: |
echo "Testing /compile-and-fix endpoint..."
RESPONSE=$(curl -s -S -f -X POST http://localhost:8000/compile-and-fix \
-H "Content-Type: application/json" \
-d '{
"code": "[filename: Cargo.toml]\n[package]\nname = \"hello_world\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n[dependencies]\n\n[filename: src/main.rs]\nfn main() {\n println!(\"Hello, World!\" // Missing closing parenthesis\n}",
"description": "A simple hello world program",
"max_attempts": 3
}' || echo "CURL_FAILED")
if [ "$RESPONSE" = "CURL_FAILED" ]; then
echo "Failed to connect to API service"
docker ps
docker logs $(docker ps -q --filter name=api)
exit 1
fi
# Check for success in response
if ! echo "$RESPONSE" | jq -e '.success == true' > /dev/null; then
echo "Compilation failed:"
echo "$RESPONSE" | jq || echo "$RESPONSE"
exit 1
fi
echo "Compilation successful!"
echo "$RESPONSE" | jq || echo "$RESPONSE"
- name: Test /generate endpoint
run: |
echo "Testing /generate endpoint..."
# Generate the project
RESPONSE=$(curl -s -S -f -X POST http://localhost:8000/generate \
-H "Content-Type: application/json" \
-d '{
"description": "A simple command-line calculator in Rust",
"requirements": "Should support addition, subtraction, multiplication, and division"
}' || echo "CURL_FAILED")
if [ "$RESPONSE" = "CURL_FAILED" ]; then
echo "Failed to connect to API service"
docker ps
docker logs $(docker ps -q --filter name=api)
exit 1
fi
# Extract project_id from response
PROJECT_ID=$(echo "$RESPONSE" | jq -r '.project_id')
echo "Project ID: $PROJECT_ID"
# Poll for project completion (maximum 10 attempts, 15 seconds apart)
echo "Polling for project completion..."
for i in {1..10}; do
echo "Checking project status (attempt $i)..."
STATUS_RESPONSE=$(curl -s -S -f "http://localhost:8000/project/$PROJECT_ID" || echo "CURL_FAILED")
if [ "$STATUS_RESPONSE" = "CURL_FAILED" ]; then
echo "Failed to get project status"
exit 1
fi
STATUS=$(echo "$STATUS_RESPONSE" | jq -r '.status')
echo "Current status: $STATUS"
if [ "$STATUS" = "completed" ]; then
echo "Project generation successful!"
echo "$STATUS_RESPONSE" | jq
break
elif [ "$STATUS" = "failed" ]; then
echo "Project generation failed:"
echo "$STATUS_RESPONSE" | jq
exit 1
fi
# If still processing, wait and try again
if [ $i -eq 10 ]; then
echo "Project generation taking too long, exiting"
exit 1
fi
echo "Waiting 15 seconds before next check..."
sleep 15
done
# Get a file from the project to verify file access works
echo "Retrieving main.rs file..."
FILE_RESPONSE=$(curl -s -S -f "http://localhost:8000/project/$PROJECT_ID/files/src/main.rs" || echo "CURL_FAILED")
if [ "$FILE_RESPONSE" = "CURL_FAILED" ]; then
echo "Failed to retrieve file"
exit 1
fi
echo "Successfully retrieved file content:"
echo "$FILE_RESPONSE" | head -10
# Test downloading the project
echo "Testing project download..."
DOWNLOAD_RESPONSE=$(curl -s -S -f -o "project-$PROJECT_ID.zip" "http://localhost:8000/project/$PROJECT_ID/download" || echo "CURL_FAILED")
if [ "$DOWNLOAD_RESPONSE" = "CURL_FAILED" ]; then
echo "Failed to download project"
exit 1
fi
# Verify zip file was created
if [ ! -f "project-$PROJECT_ID.zip" ]; then
echo "Project zip file not created"
exit 1
fi
echo "Project download successful!"
ls -la "project-$PROJECT_ID.zip"
- name: Test /generate-sync endpoint
continue-on-error: true # Allow this step to fail without failing the workflow
id: test-generate-sync
run: |
echo "Testing /generate-sync endpoint..."
RESPONSE=$(curl -X POST http://localhost:8000/generate-sync \
-H "Content-Type: application/json" \
-d '{"description": "A command-line calculator in Rust", "requirements": "Should support addition, subtraction, multiplication, and division"}')
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST http://localhost:8000/generate-sync \
-H "Content-Type: application/json" \
-d '{"description": "A command-line calculator in Rust", "requirements": "Should support addition, subtraction, multiplication, and division"}')
echo "HTTP response code: $HTTP_CODE"
if [[ "$HTTP_CODE" == "500" ]] && ([[ "$RESPONSE" == *"Invalid API Key"* ]] || [[ "$RESPONSE" == *"local variable"* ]] || [[ "$RESPONSE" == *"Connection error"* ]]); then
echo "LLM service error detected - this is expected with invalid API keys or connection issues"
echo "status=auth_error" >> $GITHUB_OUTPUT
exit 0
elif [[ "$HTTP_CODE" != "200" ]]; then
echo "Failed to connect to API service with unexpected error"
echo "Response: $RESPONSE"
docker ps
docker logs $(docker ps -q --filter name=api)
echo "status=error" >> $GITHUB_OUTPUT
exit 1
fi
# Save response to file for later use
echo "$RESPONSE" > generate_output.txt
# Check for success in response
if ! echo "$RESPONSE" | jq -e '.success == true' > /dev/null; then
echo "Generation failed:"
echo "status=error" >> $GITHUB_OUTPUT
echo "$RESPONSE" | jq || echo "$RESPONSE"
exit 1
fi
echo "Generate-sync successful! Response contains code files in text format."
echo "status=success" >> $GITHUB_OUTPUT
echo "$RESPONSE" | jq || echo "$RESPONSE"
- name: "Test workflow: /generate-sync → /compile"
run: |
echo "Testing workflow: /generate-sync → /compile..."
# Check if response contains fallback template
if grep -q "FALLBACK TEMPLATE" generate_output.txt; then
echo "WARNING: Testing with fallback template code - LLM generation failed but continuing with tests"
fi
# Get the output from the previous step and remove the build status comment
# GENERATE_OUTPUT=$(cat generate_output.txt | sed '/^# Build/,$d')
# COMPILE_RESPONSE=$(curl -s -S -f -X POST http://localhost:8000/compile \
# -H "Content-Type: application/json" \
# -d "{
# \"code\": $(python3 -c "import json, sys; print(json.dumps(sys.stdin.read()))" < <(echo "$GENERATE_OUTPUT"))
# }" || echo "CURL_FAILED")
# Replace with:
COMPILE_RESPONSE=$(curl -s -S -f -X POST http://localhost:8000/compile \
-H "Content-Type: application/json" \
-d "{
\"code\": $(python3 -c "import json, sys; print(json.dumps(sys.stdin.read()))" < <(echo "$GENERATE_OUTPUT"))
}" || echo "CURL_FAILED")
if [ "$COMPILE_RESPONSE" = "CURL_FAILED" ]; then
echo "Failed to connect to API service"
docker ps
exit 1
fi
# Check for success in response
if ! echo "$COMPILE_RESPONSE" | jq -e '.success == true' > /dev/null; then
echo "Compilation failed:"
echo "$COMPILE_RESPONSE" | jq || echo "$COMPILE_RESPONSE"
exit 1
fi
echo "Workflow test successful! Generated code compiles correctly."
echo "$COMPILE_RESPONSE" | jq || echo "$COMPILE_RESPONSE"
test-cli:
runs-on: ubuntu-latest
needs: test # Wait for API tests to complete first
steps:
- name: Checkout code
uses: actions/checkout@v4.2.2
- name: Install Python and dependencies
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Install Python dependencies
run: pip install -r requirements.txt
- name: Test CLI help and version
run: |
echo "Testing CLI basic functionality..."
# Test help
python -m cli.main --help
# Test version command
python -m cli.main version
python -m cli.main version --json
# Test completions command
python -m cli.main completions
echo "CLI basic commands working ✅"
- name: Test CLI with mock server
run: |
echo "Testing CLI commands with mock server..."
# Start mock server from separate file
python .github/mock_server.py &
MOCK_PID=$!
sleep 3
# Verify mock server is running
echo "Checking if mock server is running..."
if ! curl -s http://localhost:8001/project/test-123 > /dev/null; then
echo "Mock server not responding, starting again..."
kill $MOCK_PID 2>/dev/null || true
sleep 2
python .github/mock_server.py &
MOCK_PID=$!
sleep 3
fi
# Test CLI commands against mock server
echo "Testing CLI commands..."
# Test compile from file
echo "[filename: Cargo.toml]\n[package]\nname = \"test\"\nversion = \"0.1.0\"\n\n[filename: src/main.rs]\nfn main() { println!(\"Hello\"); }" > test_project.txt
echo "Testing compile from file..."
python -m cli.main --server http://localhost:8001 compile --code test_project.txt
# Test compile from project ID
echo "Testing compile from project ID..."
python -m cli.main --server http://localhost:8001 compile --project test-123
# Test fix from file
echo "Testing fix from file..."
python -m cli.main --server http://localhost:8001 fix --code test_project.txt --description "test project" --max-attempts 2
# Test fix from project ID
echo "Testing fix from project ID..."
python -m cli.main --server http://localhost:8001 fix --project test-123 --description "test project" --max-attempts 2
# Test status command
echo "Testing status command..."
python -m cli.main --server http://localhost:8001 status --project test-123
# Test cat command
echo "Testing cat command..."
python -m cli.main --server http://localhost:8001 cat --project test-123 --file src/main.rs
# Test download command (should fail gracefully with mock server)
echo "Testing download command..."
python -m cli.main --server http://localhost:8001 download --project test-123 || echo "Download failed as expected with mock server"
# Clean up
kill $MOCK_PID 2>/dev/null || true
rm -f test_project.txt
echo "CLI command tests completed ✅"
- name: Test CLI error handling
run: |
echo "Testing CLI error handling..."
# Test missing required arguments
python -m cli.main compile 2>&1 | grep -q "Error: Must specify either --code or --project" && echo "Missing args error handled ✅" || exit 1
# Test conflicting arguments
python -m cli.main compile --code test.txt --project test-123 2>&1 | grep -q "Error: Cannot specify both --code and --project" && echo "Conflicting args error handled ✅" || exit 1
# Test non-existent file
python -m cli.main compile --code nonexistent.txt 2>&1 | grep -q "File not found" && echo "File not found error handled ✅" || exit 1
# Test non-existent project
python -m cli.main --server http://localhost:8001 compile --project nonexistent 2>&1 | grep -q "Project not found" && echo "Project not found error handled ✅" || exit 1
echo "CLI error handling tests completed ✅"
- name: Test CLI JSON output
run: |
echo "Testing CLI JSON output..."
# Start mock server again for JSON tests
python .github/mock_server.py &
MOCK_PID=$!
sleep 3
# Create test project file for JSON tests
echo "[filename: Cargo.toml]\n[package]\nname = \"test\"\nversion = \"0.1.0\"\n\n[filename: src/main.rs]\nfn main() { println!(\"Hello\"); }" > test_project.txt
# Test JSON output with error checking
echo "Testing version --json..."
VERSION_OUTPUT=$(python -m cli.main --server http://localhost:8001 version --json 2>/dev/null || echo "")
if [ -n "$VERSION_OUTPUT" ]; then
echo "$VERSION_OUTPUT" | python -c "import json, sys; json.load(sys.stdin); print('Version JSON output valid ✅')"
else
echo "Version command failed, skipping JSON validation"
fi
echo "Testing compile --json..."
COMPILE_OUTPUT=$(python -m cli.main --server http://localhost:8001 compile --code test_project.txt --json 2>/dev/null || echo "")
if [ -n "$COMPILE_OUTPUT" ]; then
echo "$COMPILE_OUTPUT" | python -c "import json, sys; json.load(sys.stdin); print('Compile JSON output valid ✅')"
else
echo "Compile command failed, skipping JSON validation"
fi
# Clean up
kill $MOCK_PID 2>/dev/null || true
rm -f test_project.txt
echo "CLI JSON output tests completed ✅"