-
Notifications
You must be signed in to change notification settings - Fork 52
456 lines (386 loc) · 15.3 KB
/
integration-test.yml
File metadata and controls
456 lines (386 loc) · 15.3 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
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
name: Integration Tests
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
actionlint:
name: Lint GitHub Actions workflows
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download actionlint
id: get_actionlint
run: |
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
echo "executable=./actionlint" >> "$GITHUB_OUTPUT"
shell: bash
- name: Check workflow files
run: ${{ steps.get_actionlint.outputs.executable }} -color
shell: bash
integration-test:
name: Test npm installation on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [20]
fail-fast: false
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@1.92.0
with:
components: rustfmt, clippy
- name: Setup Rust cache
uses: actions/cache@v4
timeout-minutes: 5
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-${{ hashFiles('rust-toolchain', 'rust-toolchain.toml') || 'stable' }}
restore-keys: |
${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-
${{ runner.os }}-cargo-
- name: Build Rust binary (debug mode for CI speed)
run: cargo build
- name: Prepare npm package with local binary
shell: bash
run: |
# Create bin directory in npm package
mkdir -p npm/bin
# Copy the built binary to npm package bin directory with correct naming
# On Unix, we need to preserve the Node.js wrapper script (probe) and put the binary as probe-binary
if [[ "${{ runner.os }}" == "Windows" ]]; then
cp target/debug/probe.exe npm/bin/probe.exe
else
cp target/debug/probe npm/bin/probe-binary
chmod +x npm/bin/probe-binary
fi
# Debug: Check what files are actually in npm/bin before npm link
echo "Debug: Files in npm/bin before npm link:"
ls -la npm/bin/
# Install npm package dependencies and build all packages
# Skip postinstall script since we're providing the binary manually
cd npm && npm install --ignore-scripts && npm run build
# Debug: Check what files are in npm/bin after npm install/build
echo "Debug: Files in npm/bin after build:"
ls -la bin/
- name: Link Probe package locally
run: |
cd npm && npm link --ignore-scripts
- name: Verify Probe installation
run: probe --version
- name: Test search functionality
shell: bash
run: |
echo "Current directory: $(pwd)"
echo "Probe version:"
echo "Debugging npm link setup:"
which probe || echo "probe command not found in PATH"
ls -la "$(which probe)" || echo "probe symlink not found"
if [[ "${{ runner.os }}" == "Windows" ]]; then
echo "Windows-specific checks:"
npm list -g @probelabs/probe || echo "Package listing failed"
else
echo "Unix-specific checks:"
readlink -f "$(which probe)" || echo "Cannot resolve probe symlink"
fi
echo "Checking package structure:"
if [[ "${{ runner.os }}" == "Windows" ]]; then
ls -la "$(npm root -g)/@probelabs/probe/bin/" || echo "npm package bin directory not found"
else
# For npm link, the package might be in a different location
npm list -g @probelabs/probe --depth=0 || echo "Linked package not found"
fi
echo "Testing probe command (using npm link):"
npm --version
probe --version
echo "Running search command..."
# Use the probe command from npm global installation (this uses our shim)
probe search "context engine" README.md --format json > search_results.json
echo "Search command completed, checking file size:"
if [[ "${{ runner.os }}" == "Windows" ]]; then
powershell -Command "Get-ChildItem search_results.json | Select-Object Name,Length"
echo "File contents (first 10 lines):"
powershell -Command "Get-Content search_results.json | Select-Object -First 10"
else
ls -la search_results.json
echo "File contents (first 10 lines):"
head -10 search_results.json
fi
- name: Verify search results (Unix)
if: runner.os != 'Windows'
run: |
# Check that the JSON output contains expected fields
if ! grep -q '"file"' search_results.json; then
echo "Error: JSON output missing 'file' field"
cat search_results.json
exit 1
fi
if ! grep -q '"code"' search_results.json; then
echo "Error: JSON output missing 'code' field"
cat search_results.json
exit 1
fi
if ! grep -q 'README.md' search_results.json; then
echo "Error: Search results don't contain README.md"
cat search_results.json
exit 1
fi
if ! grep -q 'context engine' search_results.json; then
echo "Error: Search results don't contain the search term"
cat search_results.json
exit 1
fi
echo "✅ Search results validation passed"
- name: Verify search results (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
# shellcheck disable=SC1009,SC1073,SC1065,SC1064,SC1072
# Check that the JSON output contains expected fields
if (-not (Test-Path search_results.json)) {
Write-Host "Error: search_results.json file not found"
exit 1
}
$content = Get-Content search_results.json -Raw
if (-not $content) {
Write-Host "Error: search_results.json file is empty"
exit 1
}
# Extract JSON part by finding the first '{' character (skip debug output)
$jsonStart = $content.IndexOf('{')
if ($jsonStart -eq -1) {
Write-Host "Error: No JSON found in output"
Get-Content search_results.json
exit 1
}
$jsonContent = $content.Substring($jsonStart)
if (-not ($jsonContent -match '"file"')) {
Write-Host "Error: JSON output missing 'file' field"
Get-Content search_results.json
exit 1
}
if (-not ($jsonContent -match '"code"')) {
Write-Host "Error: JSON output missing 'code' field"
Get-Content search_results.json
exit 1
}
if (-not ($jsonContent -match 'README.md')) {
Write-Host "Error: Search results don't contain README.md"
Get-Content search_results.json
exit 1
}
if (-not ($jsonContent -match 'context engine')) {
Write-Host "Error: Search results don't contain the search term"
Get-Content search_results.json
exit 1
}
Write-Host "✅ Search results validation passed"
- name: Test extract functionality
shell: bash
run: |
echo "Running extract command..."
# Use the probe command from npm global installation (this uses our shim)
probe extract README.md:1 --format json > extract_results.json
- name: Verify extract results (Unix)
if: runner.os != 'Windows'
run: |
# Check that the extract output contains expected fields
if ! grep -q '"file"' extract_results.json; then
echo "Error: Extract JSON output missing 'file' field"
cat extract_results.json
exit 1
fi
if ! grep -q 'README.md' extract_results.json; then
echo "Error: Extract results don't contain README.md"
cat extract_results.json
exit 1
fi
echo "✅ Extract results validation passed"
- name: Verify extract results (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
# shellcheck disable=SC1009,SC1073,SC1065,SC1064,SC1072
# Check that the extract output contains expected fields
if (-not (Test-Path extract_results.json)) {
Write-Host "Error: extract_results.json file not found"
exit 1
}
$content = Get-Content extract_results.json -Raw
if (-not $content) {
Write-Host "Error: extract_results.json file is empty"
exit 1
}
# Extract JSON part by finding the first '{' character (skip debug output)
$jsonStart = $content.IndexOf('{')
if ($jsonStart -eq -1) {
Write-Host "Error: No JSON found in output"
Get-Content extract_results.json
exit 1
}
$jsonContent = $content.Substring($jsonStart)
if (-not ($jsonContent -match '"file"')) {
Write-Host "Error: Extract JSON output missing 'file' field"
Get-Content extract_results.json
exit 1
}
if (-not ($jsonContent -match 'README.md')) {
Write-Host "Error: Extract results don't contain README.md"
Get-Content extract_results.json
exit 1
}
Write-Host "✅ Extract results validation passed"
- name: Test MCP server functionality
shell: bash
run: |
echo "Testing MCP server functionality using npm link..."
# Debug: Check what probe command is actually being executed
echo "Debugging probe command resolution:"
which probe
ls -la "$(which probe)" || echo "Cannot stat probe command"
# Check if it's our Node.js shim
echo "Checking if probe command is our Node.js shim:"
head -3 "$(readlink -f "$(which probe)" 2>/dev/null || which probe)" || echo "Cannot read probe file content"
# Test that probe mcp --help works (this tests our shim routing)
echo "Testing MCP help command:"
probe mcp --help > mcp_help.txt 2>&1
mcp_exit_code=$?
if [ $mcp_exit_code -ne 0 ]; then
echo "MCP help command completed with exit code: $mcp_exit_code"
fi
echo "Debug - Command that was actually executed for 'probe mcp --help':"
echo "Exit code: $mcp_exit_code"
# Verify the help output contains MCP-specific content
if grep -q "Probe MCP Server" mcp_help.txt; then
echo "✅ MCP server help shows correct content - shim routing works!"
echo "MCP help output preview:"
head -5 mcp_help.txt
else
echo "❌ MCP help output doesn't contain expected content"
echo "Expected: 'Probe MCP Server'"
echo "Full output:"
cat mcp_help.txt
echo "--- End of output ---"
# Debug: Let's check if the MCP build files exist
echo "Checking MCP build files:"
ls -la npm/build/mcp/ || echo "MCP build directory not found"
# Check if we can run the MCP server directly
echo "Testing direct MCP server execution:"
node npm/build/mcp/index.js --help 2>&1 | head -5 || echo "Direct MCP execution failed"
exit 1
fi
# Test basic MCP functionality with timeout handling
if [[ "${{ runner.os }}" == "Windows" ]]; then
echo "Testing basic MCP server startup on Windows..."
# On Windows, just verify the command starts (we already tested help above)
echo "✅ MCP server routing verified on Windows"
else
echo "Testing MCP server JSON-RPC on Unix..."
# Test MCP server with tools/list request via echo and timeout
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | timeout 3s probe mcp > mcp_tools.json 2>/dev/null || echo "MCP tools test completed"
# Check if MCP server produced any output (means it started successfully)
if [ -f mcp_tools.json ] && [ -s mcp_tools.json ]; then
echo "✅ MCP server responded to JSON-RPC successfully"
echo "MCP response preview:"
head -3 mcp_tools.json
else
echo "✅ MCP server started successfully (no JSON response expected for basic test)"
fi
fi
# Note: npm agent tests are handled by the dedicated rust-tests.yml workflow
# This integration test focuses on npm package installation and functionality verification
- name: Upload test artifacts on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: test-results-${{ matrix.os }}-node${{ matrix.node-version }}
path: |
search_results.json
extract_results.json
npm/coverage/
retention-days: 7
chat-integration-test:
name: Test chat example on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [20]
fail-fast: false
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@1.92.0
with:
components: rustfmt, clippy
- name: Setup Rust cache
uses: actions/cache@v4
timeout-minutes: 5
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-${{ hashFiles('rust-toolchain', 'rust-toolchain.toml') || 'stable' }}
restore-keys: |
${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-
${{ runner.os }}-cargo-
- name: Build Rust binary (debug mode for CI speed)
run: cargo build
- name: Build npm package
run: |
cd npm
npm install
npm run build
- name: Install chat example dependencies
run: |
cd examples/chat
npm install
- name: Register mock backend
run: |
cd examples/chat
# The mock backend is automatically available in the implement/backends directory
echo "Mock backend is available at: implement/backends/MockBackend.js"
- name: Run chat flow integration tests
run: |
cd examples/chat
npm run test:chat
- name: Run tool calling integration tests
run: |
cd examples/chat
npm run test:tools
- name: Run all chat tests
run: |
cd examples/chat
npm test
- name: Upload test artifacts on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: chat-test-results-${{ matrix.os }}-node${{ matrix.node-version }}
path: |
examples/chat/test-results/
examples/chat/npm-debug.log
retention-days: 7