Perl API Tests
Complete guide to the Perl API test suite for hlquery.
Overview
The Perl client library is maintained in its own repository and includes its own test suite.
- hlquery server (main): https://github.com/hlquery/hlquery
- Perl client (canonical): https://github.com/hlquery/perl-api
- This repo: Perl client is vendored in
etc/api/perl/(examples + library code)
Quick Start
Running Individual Tests
git clone https://github.com/hlquery/perl-api
cd perl-api
# See the upstream repo for the current test runner / test paths
ls
Running All Tests
cd perl-api
# Follow the upstream repo instructions (README / Makefile.PL) for test execution
Test Structure
Common Test Pattern
All Perl tests follow this self-contained pattern:
#!/usr/bin/env perl
#
# Test Name
#
# WHAT THIS TEST DOES:
# 1. Step-by-step description
# 2. What it tests
# 3. What it verifies
#
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib";
use Hlquery::Client;
use JSON::PP;
my $BASE_URL = 'http://localhost:9200';
# Helper functions (assert_test, display_response)
# Main test function
# Cleanup logic
Key Features
- Self-Contained: Tests create their own data if needed
- Automatic Cleanup: Test data is removed after tests
- Clear Output: Uses indicators and detailed status
- Error Handling: Proper error handling with cleanup
- Exit Codes: Returns 0 on success, 1 on failure
Available Tests
Core CRUD Operations
test_create_collection.pl
Purpose: Tests creating collections with schemas
What it tests:
- Creating a collection with field definitions
- Verifying collection exists after creation
- Collection schema validation
Key Concepts:
- Schema defines what fields documents can have
- Field types:
string,int32,float,bool,string[],float[] - Collections must have unique names
Example Output:
----------------------------------------------------------------==============================
TEST: Create Collection (Perl API)
----------------------------------------------------------------------
1. Creating collection with schema
Collection name: test_create_1234567890
POST /collections (create)
Status: 200
✓ Collection created successfully
Collection creation returns 200/201
2. Verifying collection exists
✓ Verified collection exists
Collection response is hash
Collection has name or fields
3. Cleaning up test collection
✓ Cleaned up collection: test_create_1234567890
----------------------------------------------------------------==============================
Test Summary: 3 passed, 0 failed
----------------------------------------------------------------==============================
test_get_collection.pl
Purpose: Retrieves collection details and schema information
What it tests:
- Getting collection metadata
- Retrieving collection fields
- Handling non-existent collections
test_update_collection.pl
Purpose: Updates collection schemas
What it tests:
- Modifying collection field definitions
- Schema update validation
test_delete_collection.pl
Purpose: Deletes collections and verifies deletion
What it tests:
- Collection deletion
- Verification that collection no longer exists
- Error handling for already-deleted collections
Document Operations
test_docs_insert.pl
Purpose: Tests inserting documents into collections
What it tests:
- Creating collections with schemas
- Inserting documents with various field types
- Verifying documents were inserted correctly
Key Code Pattern:
# Create collection
my $schema = {
fields => [
{ name => 'title', type => 'string' },
{ name => 'content', type => 'string' },
{ name => 'tags', type => 'string[]' }
]
};
my $create_resp = $client->collections()->create($collection_name, $schema);
# Insert document
my $doc = {
id => 'doc_123',
title => 'Test Document',
content => 'Content here',
tags => ['tag1', 'tag2']
};
my $add_resp = $client->documents()->add($collection_name, $doc);
test_get_document.pl
Purpose: Retrieves individual documents by ID
What it tests:
- Getting documents by ID
- Document structure validation
- Error handling for non-existent documents
Key Features:
- Automatically finds or creates test data
- Tests both successful retrieval and error cases
- Verifies document content matches expectations
test_update_document.pl
Purpose: Updates existing documents
What it tests:
- Updating document fields
- Verifying updates were applied
- Partial updates (updating only some fields)
test_delete_document.pl
Purpose: Deletes documents from collections
What it tests:
- Document deletion
- Verification that document no longer exists
- Cleanup of test data
test_list_documents.pl
Purpose: Lists documents with pagination
What it tests:
- Listing all documents in a collection
- Pagination (offset/limit)
- Response structure validation
Search Operations
test_search.pl
Purpose: Basic search functionality
What it tests:
- Text search across fields
- Wildcard searches
- Search result structure
Key Concepts:
qparameter: search query stringquery_by: fields to search in (comma-separated)limit: maximum number of results
test_filter_search.pl
Purpose: Search with filter conditions
What it tests:
- Simple filters (
category:test) - Multiple filters with AND (
category:test && status:active) - Numeric filters (
price:>15) - OR filters (
category:test || category:premium) - Filters combined with sorting
Filter Syntax Examples:
# Simple filter
filter_by => 'category:test'
# AND filter
filter_by => 'category:test && status:active'
# OR filter
filter_by => 'category:test || category:premium'
# Numeric comparison
filter_by => 'price:>15'
filter_by => 'price:<=100'
test_sort_search.pl
Purpose: Search with sorting
What it tests:
- Ascending sort (
sort_by => 'price:asc') - Descending sort (
sort_by => 'price:desc') - Multiple field sorting
test_multi_search.pl
Purpose: Multi-collection search
What it tests:
- Searching across multiple collections simultaneously
- Handling multiple search results
- Result aggregation
Example:
my @searches = (
{ collection => 'products', q => 'laptop', query_by => 'title' },
{ collection => 'articles', q => 'laptop', query_by => 'content' }
);
my $results = $client->search_api()->multi_search(\@searches);
test_vector_search.pl
Purpose: Vector similarity search
What it tests:
- Creating collections with vector fields (
float[]) - Inserting documents with embedding vectors
- Performing vector similarity searches
- Vector query parameters (threshold, normalize)
Key Concepts:
- Vector fields store arrays of floating-point numbers
- Used for semantic similarity search
- Requires documents with matching vector dimensions
test_pagination.pl
Purpose: Pagination in searches and listings
What it tests:
- Offset/limit pagination
- Multiple pages of results
- Pagination in both search and list operations
test_facets.pl
Purpose: Faceted search results
What it tests:
- Facet counts by field
- Facet aggregation
- Facet response structure
Bulk Operations
test_import_documents.pl
Purpose: Bulk document import
What it tests:
- Importing multiple documents at once
- Bulk import response handling
- Verifying all documents were imported
Example:
my @docs = (
{ id => 'doc1', title => 'Doc 1' },
{ id => 'doc2', title => 'Doc 2' },
{ id => 'doc3', title => 'Doc 3' }
);
my $result = $client->documents()->import_documents($collection_name, \@docs);
test_bulk_operations.pl
Purpose: Various bulk operations
What it tests:
- Bulk document operations
- Batch processing
- Performance with large datasets
Advanced Features
test_aliases.pl
Purpose: Collection alias management
What it tests:
- Alias creation and management
- Using aliases in queries
- Alias endpoints (if available)
test_auth.pl
Purpose: Authentication functionality
What it tests:
- Health check without authentication
- Bearer token authentication
- API key authentication
- Token validation
Example:
# Set bearer token
$client->set_auth_token('your_token', 'bearer');
# Clear authentication
$client->clear_auth();
test_data_types.pl
Purpose: Various data types
What it tests:
- String fields
- Integer fields (
int32) - Float fields
- Boolean fields
- Array fields (
string[],float[])
test_edge_cases.pl
Purpose: Edge cases and special scenarios
What it tests:
- Empty queries
- Very long collection names
- Non-existent resources
- Special characters
test_error_handling.pl
Purpose: Error handling
What it tests:
- Invalid collection names
- Invalid document IDs
- Error response detection
- Exception handling
test_export.pl
Purpose: Document export
What it tests:
- Exporting collections
- Export formats
- Export endpoints (if available)
test_overrides.pl
Purpose: Search override management
What it tests:
- Creating search overrides
- Override endpoints (if available)
- Override functionality
test_stopwords.pl
Purpose: Stopword management
What it tests:
- Stopword configuration
- Stopword endpoints (if available)
- Stopword functionality
test_synonyms.pl
Purpose: Synonym management
What it tests:
- Synonym configuration
- Synonym endpoints (if available)
- Synonym functionality
System Tests
test_health.pl
Purpose: Health and status endpoints
What it tests:
/healthendpoint/statusendpoint/metricsendpoint- Response consistency
test_stats.pl
Purpose: Server statistics
What it tests:
- Basic stats endpoint
- Detailed statistics
- Cache statistics
- Connection statistics
- RocksDB Statistics
test_list_all_cols.pl
Purpose: List all collections
What it tests:
- Listing collections with pagination
- Collection metadata
- Collection counts
Understanding Test Output
Success Indicators
- Green checkmark: Test assertion passed
- Red X: Test assertion failed
- Chart icon: API response display
- ✓ Checkmark: Operation completed successfully
- Warning: Non-critical issue or information
Test Summary
Each test ends with a summary:
----------------------------------------------------------------==============================
Test Summary: 5 passed, 0 failed
----------------------------------------------------------------==============================
- Exit code 0: All tests passed
- Exit code 1: One or more tests failed
Common Patterns
Pattern 1: Self-Contained Test Data
# Find or create test collection
my $collection_name = undef;
my $collections_resp = $client->list_collections(0, 10);
if (!$collection_name) {
# Create test collection
$collection_name = 'test_' . time();
my $schema = { fields => [...] };
$client->collections()->create($collection_name, $schema);
$created_test_collection = 1;
}
# Run tests...
# Cleanup
if ($created_test_collection) {
$client->collections()->delete($collection_name);
}
Pattern 2: Error Handling
eval {
# Test code here
};
if ($@) {
print "\nFatal error: $@\n";
$tests_failed++;
# Cleanup on error
if ($created_test_collection && $collection_name) {
eval {
$client->collections()->delete($collection_name);
};
}
}
Pattern 3: Response Validation
my $response = $client->get_document($collection_name, $doc_id);
# Check status code
if ($response->get_status_code() == 200) {
my $body = $response->get_body();
# Validate structure
if (ref($body) eq 'HASH' && exists $body->{id}) {
# Test passed
}
}
Helper Functions
All tests include these helper functions:
assert_test($condition, $message)
Asserts a condition and prints pass/fail.
if (assert_test($response->get_status_code() == 200, "Request successful")) {
$tests_passed++;
} else {
$tests_failed++;
}
display_response($test_name, $response, $show_body)
Displays API response in readable format.
display_response("GET /collections/my_col", $response);
# Shows:
# GET /collections/my_col
# Status: 200
# Response: { ... formatted JSON ... }
Troubleshooting
Test Fails with Connection Error
Problem: Cannot connect to server
Solution:
- Check if server is running:
curl http://localhost:9200/health - Verify
$BASE_URLin test file matches your server - Check firewall/network settings
Test Creates Data But Doesn't Clean Up
Problem: Test data remains after test
Solution:
- Tests should clean up automatically
- If cleanup fails, manually delete test collections:
$client->collections()->delete('test_collection_name');
"Test not yet implemented" Message
Problem: Test file shows placeholder message
Solution:
- All Perl tests are now fully implemented
- If you see this, the file may be outdated
- Check git status for uncommitted changes
Best Practices
When Writing New Tests
- Use self-contained pattern: Create test data if needed
- Always cleanup: Delete test collections/documents
- Handle errors: Use
evalblocks with cleanup - Clear output: Use helper functions for consistent formatting
- Exit codes: Return 0 on success, 1 on failure
- Add comments: Explain what the test does and why
Test Data Naming
Use timestamp-based names to avoid conflicts:
my $collection_name = 'test_feature_' . time();
Error Messages
Provide helpful error messages:
if (!$collection_name) {
print " No collections available - cannot run tests\n";
print " Create a collection first\n";
}
Related Documentation
- Perl Client Documentation - Complete Perl client API reference
- Testing Guide - General testing documentation
- Testing Examples - Detailed test examples
- API Overview - API endpoint documentation
Contributing
When adding new tests:
- Follow the existing test pattern
- Add comprehensive comments
- Include cleanup logic
- Test error cases
- Update this documentation
Support
For issues with Perl tests:
- Check server is running and accessible
- Verify Perl dependencies are installed
- Review test output for specific error messages
- Check server logs for detailed errors