This directory contains contract tests for lightstack's OpenStack API compliance. Contract tests verify that Lightstack implements the OpenStack API specification correctly by using real OpenStack client libraries (gophercloud).
Contract tests ensure 100% API compatibility with OpenStack:
- Use official OpenStack SDKs (gophercloud for Go)
- Test actual API contracts (request/response format, error codes, behavior)
- Validate against OpenStack specifications, not internal implementation details
MANDATORY: All new endpoints MUST follow this test-first workflow:
- Write contract test using gophercloud SDK (see
template_test.go) - Run test → Confirm RED (fails)
- Get approval from reviewer on test strategy
- Implement endpoint in
internal/{service}/handlers.go - Run test → Confirm GREEN (passes)
- Run full suite → All tests still pass
- Update GAP_ANALYSIS.md → Mark endpoint as ✅
Lightstack must be running:
# Start lightstack with Docker Compose
docker compose up -d
# Or run directly
make runSet environment variables:
# Source the environment file
source ~/.lightstack-env
# Or set manually
export OS_AUTH_URL=http://localhost:35357/v3
export OS_USERNAME=admin
export OS_PASSWORD=secret
export OS_PROJECT_NAME=default
export OS_USER_DOMAIN_NAME=default
# The database of the Lightstack under test, for the few fixtures the API cannot
# create (contract.Seed). Tests that need it skip when it is unset.
export LIGHTSTACK_DB_URL='postgres://lightstack:secret@localhost:5432/lightstack?sslmode=disable'
# or, for a server running on SQLite: sqlite:///var/lib/lightstack/db/lightstack.db# Run all contract tests
go test ./test/contract/... -v
# Run specific service tests
go test ./test/contract/keystone/... -v
go test ./test/contract/nova/... -v
go test ./test/contract/neutron/... -v
go test ./test/contract/cinder/... -v
go test ./test/contract/glance/... -v
# Run specific endpoint test
go test ./test/contract/keystone -run TestKeystoneCreateUser_Contract -vContract tests are part of the CI pipeline:
# .github/workflows/contract-tests.yml
- name: Run Contract Tests
run: |
docker compose up -d
sleep 5 # Wait for lightstack to start
go test ./test/contract/... -vCopy template_test.go and replace placeholders:
package contract_test
import (
"testing"
"github.com/gophercloud/gophercloud/openstack/identity/v3/users"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestKeystoneCreateUser_Contract(t *testing.T) {
SkipIfLightstackNotRunning(t)
client := SetupIdentityV3Client(t)
// Test: Create user using gophercloud SDK
user, err := users.Create(client, users.CreateOpts{
Name: "test-user-123",
Password: "secret123",
}).Extract()
// Assertions: Verify OpenStack API contract
require.NoError(t, err)
assert.NotEmpty(t, user.ID)
assert.Equal(t, "test-user-123", user.Name)
// Cleanup
defer users.Delete(client, user.ID)
}- Use gophercloud SDK - Never use raw HTTP calls. Use
gophercloud/gophercloud/openstack/*packages. - Test OpenStack contract - Verify response format, fields, error codes match OpenStack spec.
- Cleanup resources - Use
deferto delete created resources, even on test failure. - Skip if not running - Use
SkipIfLightstackNotRunning(t)to avoid false CI failures. - Descriptive names - Use
Test{Service}{Action}_Contractnaming (e.g.,TestKeystoneCreateUser_Contract).
- Keystone:
github.com/gophercloud/gophercloud/openstack/identity/v3/{users,projects,roles} - Nova:
github.com/gophercloud/gophercloud/openstack/compute/v2/{servers,flavors} - Neutron:
github.com/gophercloud/gophercloud/openstack/networking/v2/{networks,subnets,ports} - Cinder:
github.com/gophercloud/gophercloud/openstack/blockstorage/v3/{volumes,snapshots} - Glance:
github.com/gophercloud/gophercloud/openstack/imageservice/v2/{images,members}
- Phase 1 (Weeks 1-8): 60+ contract tests (33% → 52% endpoint coverage)
- Phase 2 (Weeks 9-16): 75+ contract tests (52% → 70% endpoint coverage)
- Phase 3 (Weeks 17-24): 80+ contract tests (70% → 85% endpoint coverage)
- Phase 4 (Weeks 25-32): 30+ contract tests (85% → 95%+ endpoint coverage)
Total: 245+ contract tests for 95%+ OpenStack API compliance.
Every PR that adds/modifies an endpoint must:
- ✅ Include contract test using gophercloud
- ✅ Confirm RED (test fails before implementation)
- ✅ Confirm GREEN (test passes after implementation)
- ✅ Pass schema validation
- ✅ Pass integration tests (no regressions)
Contract tests are Tier 1 validation (per Implementation Plan):
- Tier 1: Contract tests (gophercloud) - mandatory per endpoint
- Tier 2: Integration tests (bash scripts) - batch validation per wave
- Tier 3: Schema validation (automated) - runs on all tests
Timeline per endpoint: ~2 hours (write test 30min, confirm RED 2min, review 10min, implement 60-90min, confirm GREEN 2min).
Test fails with "connection refused":
- Check Lightstack is running:
curl http://localhost:35357/v3 - Check environment variables:
echo $OS_AUTH_URL
Test fails with "401 Unauthorized":
- Check credentials:
openstack token issue - Verify JWT secret matches in config
Test fails with "404 Not Found":
- Expected for new endpoints (RED state)
- Implement endpoint, then re-run test (should turn GREEN)
Test passes but real OpenStack SDK fails:
- This indicates an API compatibility bug
- File an issue and add contract test to reproduce
- OpenStack API Reference: https://docs.openstack.org/api-ref/
- Gophercloud Documentation: https://github.com/gophercloud/gophercloud
- SPEC-000 Compliance:
/Users/I761222/git/lightstack/specs/000-compliance/SPEC.md - Implementation Plan:
/Users/I761222/git/lightstack/DEVELOPMENT_PLAN_SUMMARY.md