Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ tests/*.sh
*.phar
/.idea/

# pi-subagents run artifacts
.pi-subagents/

# Local CI testing
.act/

Expand Down
42 changes: 31 additions & 11 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,43 +76,62 @@ This calls `build_zvec_lib.sh` then `build_ffi.sh`.
### Run the integration test suite

```bash
php run-tests.php tests/
php run-tests.php -n tests/
```

> **Note:** Always run the suite with `-n` (no php.ini). Machines with the
> legacy `zvec` PHP extension (v0.4.10, `php-ext/`) installed in `php.ini`
> shadow the FFI classes: `src/ZVec.php` bails out early
> (`if (extension_loaded('zvec')) return;`) and FFI-only classes like
> `ZVecIndexParams` never load, causing widespread test failures (#188).
> The `-n` flag disables the extension in the child PHP processes.

### Run .phpt tests (standard PHP test format)

```bash
# Run all phpt tests
php run-tests.php tests/
php run-tests.php -n tests/

# Run single phpt test
php run-tests.php tests/test_error_handling.phpt
php run-tests.php -n tests/test_error_handling.phpt

# Run with verbose output
php run-tests.php -v tests/
php run-tests.php -n -v tests/
```

The `run-tests.php` script is bundled with this project (from php-src).
It parses `.phpt` files and executes the PHP code within `--FILE--` sections.

### Run legacy PHP test scripts

Legacy scripts must also be run with `-n` so they test the FFI bindings
instead of a pre-installed `zvec` extension (#188):

```bash
# Run a single test
php tests/test_error_handling.php
php -n tests/test_error_handling.php

# Run all tests (old format)
for f in tests/*.php; do php "$f"; done
for f in tests/*.php; do php -n "$f"; done
```

> **Warning:** `run-tests.php` derives the executable path from the `.phpt`
> basename in the same directory and **unlinks it unconditionally** — running
> the suite deletes legacy tracked `tests/<name>.php` files that share a
> basename with a `.phpt` file (#187). Back them up first, or restore with
> `git checkout -- tests/` after the run.

### Run all tests (both formats)

```bash
# Build first if needed
./build_zvec.sh

# Run all tests
php run-tests.php tests/
# Run all tests (phpt suite)
php run-tests.php -n tests/

# Run legacy scripts (restore deleted tests/*.php first, see warning above)
for f in tests/*.php; do php -n "$f"; done
```

## Testing Requirements
Expand All @@ -137,12 +156,13 @@ Before marking any task as DONE:

2. **Run all .phpt tests**:
```bash
php run-tests.php tests/
php run-tests.php -n tests/
```

3. **Run all tests**:
```bash
php run-tests.php tests/
php run-tests.php -n tests/
for f in tests/*.php; do php -n "$f"; done # legacy scripts (restore deleted files first, see #187)
```

4. **Verify test databases cleaned up:**
Expand Down Expand Up @@ -345,7 +365,7 @@ require_once __DIR__ . '/../src/ZVec.php';
**Current format (.phpt):**
- Test files use `.phpt` format in `tests/` directory
- Each test uses `--TEST--`, `--SKIPIF--`, `--FILE--`, `--EXPECT--` sections
- Run via `php run-tests.php tests/`
- Run via `php run-tests.php -n tests/` (the `-n` flag avoids a legacy pre-installed `zvec` extension shadowing the FFI classes — see "Run the integration test suite")
- Each test creates unique temp directory with `uniqid()` and cleans up with `try-finally`
- **Test naming:**
- `tests/bug_NNNN.php` (zero-padded 4-digit number) - bug reproduction scripts
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- **Deprecated index creation warnings** (#169)
- The FFI bindings’ `createHnswIndex()`, `createHnswRabitqIndex()`, `createFlatIndex()`, and `createIvfIndex()` now emit `E_USER_DEPRECATED` before delegating to the unified `createIndex()` API.
- **Regression gate against zvec v0.6.0** (#175)
- Full `.phpt` suite verified (FFI mode, `-n`): 0 failures, only expected XFAILs (VECTOR_FP64, upstream-blocked) and the expected RaBitQ platform SKIP (Linux x86_64 only)
- All 12 legacy `tests/bug_*.php` scripts pass against v0.6.0; cleaned-up statuses for `bug_0005_cleanup_after_failed_ops.php` and `bug_0006_rocksdb_lock.php` (no issues observed on v0.6.0)
- `test_buffer_retry.phpt` now actually runs (previously it always skipped: the SKIPIF checked `method_exists()` before loading the library — fixed by requiring `src/ZVec.php` first)
- Legacy `test_installer_platform.php` accepts the `macOS` label prefix on Darwin, matching its `.phpt` counterpart
- Documented the `-n` requirement (pre-installed legacy extension shadows FFI classes — #188) and the `run-tests.php` legacy-file deletion hazard (#187) in `AGENTS.md` / `README.md`

## [0.5.0] - 2026-07-30

Expand Down
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,12 @@ This will:
### 3. Verify installation (FFI mode)

```bash
php run-tests.php tests/
php run-tests.php -n tests/
```

> **Note:** The `-n` flag (no php.ini) is required to avoid a legacy
> pre-installed `zvec` PHP extension shadowing the FFI classes (#188).

### Alternative: Build the native PHP extension

The native extension provides the same API without FFI overhead. It links directly with the zvec C++ library.
Expand Down Expand Up @@ -727,14 +730,17 @@ $rerankedDoc->getSourceScores(): array // ['fieldName' => score, ...]

## Running Tests

### .phpt test suite (works with both FFI and native extension)
### .phpt test suite (FFI mode)
```bash
php run-tests.php tests/
php run-tests.php -n tests/
```

> **Note:** Run with `-n` (no php.ini). A legacy pre-installed `zvec` PHP
> extension (v0.4.10) shadows the FFI classes and breaks the suite (#188).

### Integration tests
```bash
php run-tests.php tests/
php run-tests.php -n tests/
```

## Project Structure
Expand Down
18 changes: 12 additions & 6 deletions docs/workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,22 @@ The FFI shared library must already exist. If not, run `./build_zvec.sh`.
### Run all tests:

```bash
# Run all .phpt tests
php run-tests.php tests/
# Run all .phpt tests (always with -n: a legacy pre-installed zvec PHP extension
# shadows the FFI classes and breaks the suite — see issue #188)
php run-tests.php -n tests/

# Run specific test file
php run-tests.php tests/test_<feature>.phpt
php run-tests.php -n tests/test_<feature>.phpt

# Run with verbose output
php run-tests.php -v tests/
php run-tests.php -n -v tests/
```

> **Warning:** `run-tests.php` unlinks legacy tracked `tests/<name>.php` files
> that share a basename with a `.phpt` file (issue #187). Back them up first
> or restore with `git checkout -- tests/` after a run. Conversely the same
> restore reverts any local edits to those files — keep fixes re-applied.

> **Note:** If you see database errors, clean up stale test directories:
> ```bash
> ls test_dbs/
Expand Down Expand Up @@ -247,7 +253,7 @@ gh run view --log --job <job-name>
# 3. Fix the issues locally
# 4. Run code review via subagent again (repeat steps 5-7)
# 5. Run tests locally
php run-tests.php tests/
php run-tests.php -n tests/

# 6. Commit the fixes
git add -A
Expand Down Expand Up @@ -311,7 +317,7 @@ git push origin feat/issue-<NUMBER>-<description>
# 6. Build and test locally
./build_zvec_lib.sh v0.6.0
./build_ffi.sh
php run-tests.php tests/
php run-tests.php -n tests/

# 7. Update CHANGELOG.md

Expand Down
5 changes: 3 additions & 2 deletions tests/bug_0005_cleanup_after_failed_ops.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
* Bug reproduction: Cleanup safety after failed operations
*
* Expected: Collection can be safely closed/destroyed after failed operations
* Actual: (To be determined - checking if issues exist)
* Actual: All scenarios (failed insert → close/destroy, failed insert + DDL → close, mixed failures) pass on zvec v0.6.0
*
* Status: Investigation in progress
* Status: No issue observed on zvec v0.6.0 (verified 2026-08-08) — close/destroy/DDL stay safe after failed ops
* Location: php/ZVec.php - cleanup logic
*/

Expand Down Expand Up @@ -96,6 +96,7 @@
echo " DDL after failed insert: OK\n";
} catch (Throwable $e) {
echo " DDL failed: " . $e->getMessage() . "\n";
$success = false;
}

try {
Expand Down
4 changes: 2 additions & 2 deletions tests/bug_0006_rocksdb_lock.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
* Bug reproduction: RocksDB lock handling after failures
*
* Expected: No locks remain after proper cleanup
* Actual: (To be determined - checking if lock issues exist)
* Actual: Destroy→recreate, rapid create/fail/destroy cycles, and close→reopen all succeed without lock-related errors on zvec v0.6.0
*
* Status: Investigation in progress
* Status: No issue observed on zvec v0.6.0 (verified 2026-08-08) — no lock-related errors on destroy/recreate or close/reopen
* Location: FFI layer - RocksDB lock management
*/

Expand Down
1 change: 1 addition & 0 deletions tests/test_buffer_retry.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Buffer retry logic: getArrayString, fieldNames, vectorNames, getArrayBool, schem
--SKIPIF--
<?php
if (!extension_loaded('zvec') && !extension_loaded('ffi')) die('skip Neither zvec extension nor FFI available');
require_once __DIR__ . '/../src/ZVec.php';
if (!method_exists('ZVecSchema', 'addArrayString')) die('skip addArrayString not available');
?>
--FILE--
Expand Down
4 changes: 3 additions & 1 deletion tests/test_installer_platform.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

$label = Installer::platformLabel();

if (str_contains($label, PHP_OS_FAMILY)) {
$osMatch = str_contains($label, PHP_OS_FAMILY)
|| (PHP_OS_FAMILY === 'Darwin' && str_contains($label, 'macOS'));
if ($osMatch) {
echo "Platform label contains OS family: PASS\n";
} else {
echo "FAIL: Platform label missing OS family\n";
Expand Down
Loading