1- import { AdminClient , ChromaClient } from "chromadb" ;
2- import { ChromaDBContainer } from "./chromadb-container" ;
1+ import { AdminClient , ChromaClient , OllamaEmbeddingFunction } from "chromadb" ;
2+ import fs from "node:fs" ;
3+ import os from "node:os" ;
4+ import path from "node:path" ;
5+ import { GenericContainer } from "testcontainers" ;
6+ import { ChromaDBContainer , StartedChromaDBContainer } from "./chromadb-container" ;
37
48describe ( "ChromaDB" , { timeout : 360_000 } , ( ) => {
5- // docs {
6- it ( "should connect and return a query result " , async ( ) => {
9+ // startContainer {
10+ it ( "should connect" , async ( ) => {
711 const container = await new ChromaDBContainer ( ) . start ( ) ;
12+ const client = await connectTo ( container ) ;
13+ expect ( await client . heartbeat ( ) ) . toBeDefined ( ) ;
14+ // Do something with the client
15+ await container . stop ( ) ;
16+ } ) ;
17+ // }
18+
19+ // simpleConnect {
20+ async function connectTo ( container : StartedChromaDBContainer ) {
21+ const client = new ChromaClient ( {
22+ path : container . getHttpUrl ( ) ,
23+ } ) ;
24+ const hb = await client . heartbeat ( ) ;
25+ expect ( hb ) . toBeDefined ( ) ;
26+ return client ;
27+ }
28+ // }
29+
30+ // createCollection {
31+ it ( "should create collection and get data" , async ( ) => {
32+ const container = await new ChromaDBContainer ( ) . start ( ) ;
33+ const client = await connectTo ( container ) ;
34+ const collection = await client . createCollection ( { name : "test" , metadata : { "hnsw:space" : "cosine" } } ) ;
35+ expect ( collection . name ) . toBe ( "test" ) ;
36+ expect ( collection . metadata ) . toBeDefined ( ) ;
37+ expect ( collection . metadata ?. [ "hnsw:space" ] ) . toBe ( "cosine" ) ;
38+ await collection . add ( { ids : [ "1" ] , embeddings : [ [ 1 , 2 , 3 ] ] , documents : [ "my doc" ] , metadatas : [ { key : "value" } ] } ) ;
39+ const getResults = await collection . get ( { ids : [ "1" ] } ) ;
40+ expect ( getResults . ids [ 0 ] ) . toBe ( "1" ) ;
41+ expect ( getResults . documents [ 0 ] ) . toStrictEqual ( "my doc" ) ;
42+ expect ( getResults . metadatas ) . toBeDefined ( ) ;
43+ expect ( getResults . metadatas ?. [ 0 ] ?. key ) . toStrictEqual ( "value" ) ;
44+ await container . stop ( ) ;
45+ } ) ;
46+ // }
47+
48+ // queryCollectionWithEmbeddingFunction {
49+ it ( "should create collection and query" , async ( ) => {
50+ const container = await new ChromaDBContainer ( ) . start ( ) ;
51+ const ollama = await new GenericContainer ( "ollama/ollama" ) . withExposedPorts ( 11434 ) . start ( ) ;
52+ await ollama . exec ( [ "ollama" , "pull" , "nomic-embed-text" ] ) ;
53+ const client = await connectTo ( container ) ;
54+ const embedder = new OllamaEmbeddingFunction ( {
55+ url : `http://${ ollama . getHost ( ) } :${ ollama . getMappedPort ( 11434 ) } /api/embeddings` ,
56+ model : "nomic-embed-text" ,
57+ } ) ;
58+ const collection = await client . createCollection ( {
59+ name : "test" ,
60+ metadata : { "hnsw:space" : "cosine" } ,
61+ embeddingFunction : embedder ,
62+ } ) ;
63+ expect ( collection . name ) . toBe ( "test" ) ;
64+ await collection . add ( {
65+ ids : [ "1" , "2" ] ,
66+ documents : [
67+ "This is a document about dogs. Dogs are awesome." ,
68+ "This is a document about cats. Cats are awesome." ,
69+ ] ,
70+ } ) ;
71+ const results = await collection . query ( { queryTexts : [ "Tell me about dogs" ] , nResults : 1 } ) ;
72+ expect ( results ) . toBeDefined ( ) ;
73+ expect ( results . ids [ 0 ] ) . toEqual ( [ "1" ] ) ;
74+ expect ( results . ids [ 0 ] [ 0 ] ) . toBe ( "1" ) ;
75+ await container . stop ( ) ;
76+ } ) ;
77+
78+ // persistentData {
79+ it ( "should reconnect with volume and persistence data" , async ( ) => {
80+ const sourcePath = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , "chroma-temp" ) ) ;
81+ const container = await new ChromaDBContainer ( )
82+ . withBindMounts ( [ { source : sourcePath , target : "/chroma/chroma" } ] )
83+ . start ( ) ;
84+ const client = await connectTo ( container ) ;
85+ const collection = await client . createCollection ( { name : "test" , metadata : { "hnsw:space" : "cosine" } } ) ;
86+ expect ( collection . name ) . toBe ( "test" ) ;
87+ expect ( collection . metadata ) . toBeDefined ( ) ;
88+ expect ( collection . metadata ?. [ "hnsw:space" ] ) . toBe ( "cosine" ) ;
89+ await collection . add ( { ids : [ "1" ] , embeddings : [ [ 1 , 2 , 3 ] ] , documents : [ "my doc" ] } ) ;
90+ const getResults = await collection . get ( { ids : [ "1" ] } ) ;
91+ expect ( getResults . ids [ 0 ] ) . toBe ( "1" ) ;
92+ expect ( getResults . documents [ 0 ] ) . toStrictEqual ( "my doc" ) ;
93+ await container . stop ( ) ;
94+ expect ( fs . existsSync ( `${ sourcePath } /chroma.sqlite3` ) ) . toBe ( true ) ;
95+ try {
96+ fs . rmSync ( sourcePath , { force : true , recursive : true } ) ;
97+ } catch ( e ) {
98+ // Ignore clean up, when have no access on fs.
99+ console . log ( e ) ;
100+ }
101+ } ) ;
102+ // }
103+
104+ // auth {
105+ it ( "should use auth" , async ( ) => {
8106 const tenant = "test-tenant" ;
9107 const key = "test-key" ;
10108 const database = "test-db" ;
109+ const container = await new ChromaDBContainer ( )
110+ . withEnvironment ( {
111+ CHROMA_SERVER_AUTHN_CREDENTIALS : key ,
112+ CHROMA_SERVER_AUTHN_PROVIDER : "chromadb.auth.token_authn.TokenAuthenticationServerProvider" ,
113+ CHROMA_AUTH_TOKEN_TRANSPORT_HEADER : "X-Chroma-Token" ,
114+ } )
115+ . start ( ) ;
116+
11117 const adminClient = new AdminClient ( {
12118 tenant : tenant ,
13119 auth : {
14120 provider : "token" ,
15121 credentials : key ,
16- providerOptions : {
17- headerType : "X_CHROMA_TOKEN" ,
18- } ,
122+ tokenHeaderType : "X_CHROMA_TOKEN" ,
19123 } ,
20124 path : container . getHttpUrl ( ) ,
21125 } ) ;
@@ -28,52 +132,14 @@ describe("ChromaDB", { timeout: 360_000 }, () => {
28132 auth : {
29133 provider : "token" ,
30134 credentials : key ,
31- providerOptions : {
32- headerType : "X_CHROMA_TOKEN" ,
33- } ,
135+ tokenHeaderType : "X_CHROMA_TOKEN" ,
34136 } ,
35137 path : container . getHttpUrl ( ) ,
36138 database,
37139 } ) ;
38140
39141 const collection = await dbClient . createCollection ( { name : "test-collection" } ) ;
40-
41- await collection . add ( {
42- ids : [ "1" , "2" , "3" ] ,
43- documents : [ "apple" , "oranges" , "pineapple" ] ,
44- embeddings : [
45- [ 1 , 2 , 3 ] ,
46- [ 4 , 5 , 6 ] ,
47- [ 7 , 8 , 9 ] ,
48- ] ,
49- } ) ;
50-
51- const result = await collection . get ( { ids : [ "1" , "2" , "3" ] } ) ;
52-
53- expect ( result ) . toMatchInlineSnapshot ( `
54- {
55- "data": null,
56- "documents": [
57- "apple",
58- "oranges",
59- "pineapple",
60- ],
61- "embeddings": null,
62- "ids": [
63- "1",
64- "2",
65- "3",
66- ],
67- "metadatas": [
68- null,
69- null,
70- null,
71- ],
72- "uris": null,
73- }
74- ` ) ;
75-
76- await container . stop ( ) ;
142+ expect ( collection . name ) . toBe ( "test-collection" ) ;
77143 } ) ;
78144 // }
79145} ) ;
0 commit comments