Live vector backends
Podium’s live integration tests exercise the managed vector backends Pinecone, Weaviate Cloud, and Qdrant Cloud. This page lists the accounts, indexes, and collections to create and the environment variables to set so the tests run against real services.
Credentials live in test.env at the repository root, copied from test.env.example. The file is gitignored. The tests run on the live-external lane:
make test-live-external
Each backend self-skips when its variables are absent, so you can set up one backend at a time. The vector-backend tests do not need an embedding-provider key. Storage mode uses a synthetic embedder, and self-embedding uses the backend’s own hosted model. The OpenAI, Cohere, Voyage, and Ollama keys in test.env.example drive a separate set of embedding-provider tests.
For configuring a backend in a running deployment rather than for tests, see Vector backends.
Collections per backend
Each backend uses up to two objects.
- A storage collection at dimension 1536 with cosine distance. The conformance, storage-only, and managed semantic-search tests share it. The registry computes the vectors, so the dimension is the only fixed requirement, and 1536 matches the managed semantic-search e2e so one object serves every storage test.
- An optional self-embedding collection. The backend computes its vectors from text, so it is a separate object from the storage collection: Pinecone Integrated Inference is a different index type, and a Weaviate vectorizer class differs from a vectorizer-none class. Its dimension is fixed by the inference model and is generally not 1536.
You create these objects yourself. The backends do not create them on demand, except that Weaviate’s auto-schema creates the storage class on first write.
Pinecone
- Create an account at app.pinecone.io. The free Starter tier is sufficient for one small index.
- Create an API key in the console.
- Create the storage index as a Serverless index with dimension 1536 and metric Cosine. The example below names it
podium-test. - For self-embedding, create a second Serverless index with integrated embedding and select a hosted inference model such as
multilingual-e5-large. Pinecone fixes the dimension from the model. The example below names itpodium-test-selfembed. -
Set the variables in
test.env:PODIUM_PINECONE_API_KEY=pcsk_... PODIUM_PINECONE_INDEX=podium-test # self-embedding (optional): PODIUM_PINECONE_SELFEMBED_INDEX=podium-test-selfembed PODIUM_PINECONE_INFERENCE_MODEL=multilingual-e5-large
The host resolves from the index name, so leave PODIUM_PINECONE_HOST unset.
Weaviate Cloud
- Create a cluster at console.weaviate.cloud. A Sandbox cluster is free and expires after a set period; a Serverless cluster is steadier for a recurring lane.
- Copy the cluster’s REST endpoint and create an API key.
- The storage class uses the
nonevectorizer at dimension 1536 with cosine distance. Weaviate’s auto-schema creates it on first write, so the test can create it for you. The example below names itPodiumTest. - For self-embedding, create a second class configured with a vectorizer module. The
text2vec-weaviatemodule is hosted by Weaviate, needs no external key, and sets the dimension itself. The example below names itPodiumTestSelfEmbed. -
Set the variables in
test.env:PODIUM_WEAVIATE_URL=https://your-cluster.weaviate.cloud PODIUM_WEAVIATE_API_KEY=... PODIUM_WEAVIATE_COLLECTION=PodiumTest # self-embedding (optional): PODIUM_WEAVIATE_SELFEMBED_COLLECTION=PodiumTestSelfEmbed PODIUM_WEAVIATE_VECTORIZER=text2vec-weaviate
Weaviate title-cases class names, so use a capitalized name.
Qdrant Cloud
- Create a cluster at cloud.qdrant.io. The free 1 GB tier is sufficient.
- Copy the cluster URL, which uses REST port 6333, and create an API key.
-
Create the storage collection with vector size 1536 and Cosine distance:
curl -X PUT "$PODIUM_QDRANT_URL/collections/podium_test" \ -H "api-key: $PODIUM_QDRANT_API_KEY" -H 'content-type: application/json' \ -d '{"vectors": {"size": 1536, "distance": "Cosine"}}' -
For self-embedding, create a second collection sized to the inference model’s output dimension. The example uses
bge-small-en, which outputs 384:curl -X PUT "$PODIUM_QDRANT_URL/collections/podium_test_selfembed" \ -H "api-key: $PODIUM_QDRANT_API_KEY" -H 'content-type: application/json' \ -d '{"vectors": {"size": 384, "distance": "Cosine"}}' -
Set the variables in
test.env:PODIUM_QDRANT_URL=https://your-cluster.cloud.qdrant.io:6333 PODIUM_QDRANT_API_KEY=... PODIUM_QDRANT_COLLECTION=podium_test # self-embedding (optional): PODIUM_QDRANT_SELFEMBED_COLLECTION=podium_test_selfembed PODIUM_QDRANT_INFERENCE_MODEL=bge-small-en
Run
Set the master switch in test.env, then run the lane:
# in test.env:
PODIUM_LIVE_EXTERNAL=1
make test-live-external
For each configured backend, the run executes its storage suites and, when the self-embedding collection and inference model are set, its self-embedding test. A backend without credentials skips with a reason.
Running on GitHub Actions
The live-external workflow (.github/workflows/live-external.yml) runs the same make test-live-external lane in CI. It triggers on a published release and on a manual dispatch from the Actions tab, and never on a pull request, because the managed backends and paid providers cost money and consume per-account quotas.
The workflow supplies each credential from a repository secret whose name matches the test.env variable. Define the secrets under Settings, then Secrets and variables, then Actions. A secret that is absent leaves its sub-suite skipped, the same as an unset test.env variable, so a partial set runs the subset it can reach.
Managed vector backends:
- Pinecone:
PODIUM_PINECONE_API_KEYandPODIUM_PINECONE_INDEX, plusPODIUM_PINECONE_SELFEMBED_INDEXandPODIUM_PINECONE_INFERENCE_MODELfor self-embedding. - Weaviate Cloud:
PODIUM_WEAVIATE_URL,PODIUM_WEAVIATE_API_KEY, andPODIUM_WEAVIATE_COLLECTION, plusPODIUM_WEAVIATE_SELFEMBED_COLLECTIONandPODIUM_WEAVIATE_VECTORIZERfor self-embedding. - Qdrant Cloud:
PODIUM_QDRANT_URL,PODIUM_QDRANT_API_KEY, andPODIUM_QDRANT_COLLECTION, plusPODIUM_QDRANT_SELFEMBED_COLLECTIONandPODIUM_QDRANT_INFERENCE_MODELfor self-embedding.
Embedding providers: OPENAI_API_KEY, COHERE_API_KEY, and VOYAGE_API_KEY.
Postgres, the S3 object store, and Ollama need no configuration. The workflow starts Postgres and MinIO as job-local services with throwaway localhost credentials and installs Ollama on the runner with a local model, so PODIUM_POSTGRES_DSN, the PODIUM_S3_* variables, and the Ollama variables are set in the workflow itself.
The workflow reads every value through the secrets context, so define each one as a secret. The repository is public, which makes an Actions log world-readable, and storing a value as a secret keeps it masked in the log. To keep a non-sensitive identifier such as an index or model name visible in the log, define it as a repository variable instead and change its reference in the workflow from secrets.<NAME> to vars.<NAME>.
What each test exercises
- Conformance runs the
RegistrySearchProvidercontract: put, query, tenant-boundary isolation, upsert replacement, delete, dimension-mismatch rejection, and bounded top-k. - StorageOnly and TenantIsolation cover the precomputed-vector recall path and per-tenant query isolation.
- SelfEmbedding submits text, has the backend compute the vectors, and asserts nearest-neighbour recall.
The production-dimension round trip for the local backends is covered by the pgvector depth tests.