Optimize Testcontainers config for VectorStores

* Unify image definition for vector stores in vector-store modules

* Unify image definition for vector stores in spring-ai-testcontainers module

Signed-off-by: Thomas Vitale <ThomasVitale@users.noreply.github.com>
This commit is contained in:
Thomas Vitale
2024-10-06 18:17:44 +02:00
committed by Christian Tzolov
parent eb2deba9cb
commit 012f07c97b
42 changed files with 304 additions and 59 deletions

View File

@@ -46,7 +46,7 @@ class ChromaContainerConnectionDetailsFactoryTest {
@Container
@ServiceConnection
static ChromaDBContainer chroma = new ChromaDBContainer("ghcr.io/chroma-core/chroma:0.5.0");
static ChromaDBContainer chroma = new ChromaDBContainer(ChromaImage.DEFAULT_IMAGE);
@Autowired
private VectorStore vectorStore;

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.testcontainers.service.connection.chroma;
import org.testcontainers.utility.DockerImageName;
/**
* @author Thomas Vitale
*/
public class ChromaImage {
public static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse("ghcr.io/chroma-core/chroma:0.5.11");
}

View File

@@ -46,7 +46,7 @@ class ChromaWithToken2ContainerConnectionDetailsFactoryTest {
@Container
@ServiceConnection
static ChromaDBContainer chroma = new ChromaDBContainer("ghcr.io/chroma-core/chroma:0.4.24")
static ChromaDBContainer chroma = new ChromaDBContainer(ChromaImage.DEFAULT_IMAGE)
.withEnv("CHROMA_SERVER_AUTH_CREDENTIALS", "token")
.withEnv("CHROMA_SERVER_AUTH_CREDENTIALS_PROVIDER",
"chromadb.auth.token.TokenConfigServerAuthCredentialsProvider")

View File

@@ -46,7 +46,7 @@ class ChromaWithTokenContainerConnectionDetailsFactoryTest {
@Container
@ServiceConnection
static ChromaDBContainer chroma = new ChromaDBContainer("ghcr.io/chroma-core/chroma:0.5.0")
static ChromaDBContainer chroma = new ChromaDBContainer(ChromaImage.DEFAULT_IMAGE)
.withEnv("CHROMA_SERVER_AUTHN_CREDENTIALS", "token")
.withEnv("CHROMA_SERVER_AUTHN_PROVIDER", "chromadb.auth.token_authn.TokenAuthenticationServerProvider");

View File

@@ -24,9 +24,7 @@ import org.springframework.ai.transformers.TransformersEmbeddingModel;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -51,7 +49,7 @@ class MilvusContainerConnectionDetailsFactoryTest {
@Container
@ServiceConnection
static MilvusContainer milvusContainer = new MilvusContainer("milvusdb/milvus:v2.3.8");
static MilvusContainer milvusContainer = new MilvusContainer(MilvusImage.DEFAULT_IMAGE);
List<Document> documents = List.of(
new Document(ResourceUtils.getText("classpath:/test/data/spring.ai.txt"), Map.of("spring", "great")),

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.testcontainers.service.connection.milvus;
import org.testcontainers.utility.DockerImageName;
/**
* @author Thomas Vitale
*/
public class MilvusImage {
public static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse("milvusdb/milvus:v2.4.9");
}

View File

@@ -52,8 +52,7 @@ class MongoDbAtlasLocalContainerConnectionDetailsFactoryTest {
@Container
@ServiceConnection
private static MongoDBAtlasLocalContainer container = new MongoDBAtlasLocalContainer(
"mongodb/mongodb-atlas-local:7.0.9");
private static MongoDBAtlasLocalContainer container = new MongoDBAtlasLocalContainer(MongoDbImage.DEFAULT_IMAGE);
@Autowired
private VectorStore vectorStore;

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.testcontainers.service.connection.mongo;
import org.testcontainers.utility.DockerImageName;
/**
* @author Thomas Vitale
*/
public class MongoDbImage {
public static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse("mongodb/mongodb-atlas-local:8.0.0");
}

View File

@@ -41,6 +41,7 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Eddú Meléndez
* @author Thomas Vitale
*/
@SpringJUnitConfig
@Disabled("requires more memory than is often available on dev machines")
@@ -55,7 +56,7 @@ class OllamaContainerConnectionDetailsFactoryTest {
@Container
@ServiceConnection
static OllamaContainer ollama = new OllamaContainer("ollama/ollama:0.3.9");
static OllamaContainer ollama = new OllamaContainer(OllamaImage.DEFAULT_IMAGE);
@Autowired
private OllamaEmbeddingModel embeddingModel;

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.testcontainers.service.connection.ollama;
import org.testcontainers.utility.DockerImageName;
/**
* @author Thomas Vitale
*/
public class OllamaImage {
public static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse("ollama/ollama:0.3.9");
}

View File

@@ -52,8 +52,7 @@ class OpenSearchContainerConnectionDetailsFactoryTest {
@Container
@ServiceConnection
private static final OpensearchContainer<?> opensearch = new OpensearchContainer<>(
"opensearchproject/opensearch:2.13.0");
private static final OpensearchContainer<?> opensearch = new OpensearchContainer<>(OpenSearchImage.DEFAULT_IMAGE);
static final String DOCUMENT_INDEX = "auto-spring-ai-document-index";

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.testcontainers.service.connection.opensearch;
import org.testcontainers.utility.DockerImageName;
/**
* @author Thomas Vitale
*/
public class OpenSearchImage {
public static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse("opensearchproject/opensearch:2.17.1");
}

View File

@@ -49,7 +49,7 @@ public class QdrantContainerConnectionDetailsFactoryTest {
@Container
@ServiceConnection
static QdrantContainer qdrantContainer = new QdrantContainer("qdrant/qdrant:v1.9.2");
static QdrantContainer qdrantContainer = new QdrantContainer(QdrantImage.DEFAULT_IMAGE);
List<Document> documents = List.of(
new Document(getText("classpath:/test/data/spring.ai.txt"), Map.of("spring", "great")),

View File

@@ -49,7 +49,7 @@ public class QdrantContainerWithApiKeyConnectionDetailsFactoryTest {
@Container
@ServiceConnection
static QdrantContainer qdrantContainer = new QdrantContainer("qdrant/qdrant:v1.9.2").withApiKey("test_api_key");
static QdrantContainer qdrantContainer = new QdrantContainer(QdrantImage.DEFAULT_IMAGE).withApiKey("test_api_key");
List<Document> documents = List.of(
new Document(getText("classpath:/test/data/spring.ai.txt"), Map.of("spring", "great")),

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.testcontainers.service.connection.qdrant;
import org.testcontainers.utility.DockerImageName;
/**
* @author Thomas Vitale
*/
public class QdrantImage {
public static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse("qdrant/qdrant:v1.9.7");
}

View File

@@ -9,9 +9,7 @@ import org.springframework.ai.transformers.TransformersEmbeddingModel;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -36,7 +34,7 @@ class TypesenseContainerConnectionDetailsFactoryTest {
@Container
@ServiceConnection
private static final GenericContainer<?> typesense = new GenericContainer<>("typesense/typesense:26.0")
private static final GenericContainer<?> typesense = new GenericContainer<>(TypesenseImage.DEFAULT_IMAGE)
.withExposedPorts(8108)
.withCommand("--data-dir", "/tmp", "--enable-cors")
.withEnv("TYPESENSE_API_KEY", "secret")

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.testcontainers.service.connection.typesense;
import org.testcontainers.utility.DockerImageName;
/**
* @author Thomas Vitale
*/
public class TypesenseImage {
public static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse("typesense/typesense:27.1");
}

View File

@@ -52,7 +52,7 @@ class WeaviateContainerConnectionDetailsFactoryTest {
@Container
@ServiceConnection
static WeaviateContainer weaviateContainer = new WeaviateContainer("semitechnologies/weaviate:1.25.4")
static WeaviateContainer weaviateContainer = new WeaviateContainer(WeaviateImage.DEFAULT_IMAGE)
.waitingFor(Wait.forHttp("/v1/.well-known/ready").forPort(8080));
@Autowired

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai.testcontainers.service.connection.weaviate;
import org.testcontainers.utility.DockerImageName;
/**
* @author Thomas Vitale
*/
public class WeaviateImage {
public static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse("semitechnologies/weaviate:1.25.9");
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ai;
import org.testcontainers.utility.DockerImageName;
/**
* @author Thomas Vitale
*/
public class CassandraImage {
public static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse("cassandra:5.0");
}

View File

@@ -21,10 +21,10 @@ import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.CqlSessionBuilder;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.ai.CassandraImage;
import org.testcontainers.containers.CassandraContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -36,15 +36,14 @@ import org.springframework.context.annotation.Bean;
* Use `mvn failsafe:integration-test -Dit.test=CassandraChatMemoryIT`
*
* @author Mick Semb Wever
* @author Thomas Vitale
* @since 1.0.0
*/
@Testcontainers
class CassandraChatMemoryIT {
static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("cassandra");
@Container
static CassandraContainer cassandraContainer = new CassandraContainer(DEFAULT_IMAGE_NAME.withTag("5.0"));
static CassandraContainer<?> cassandraContainer = new CassandraContainer<>(CassandraImage.DEFAULT_IMAGE);
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withUserConfiguration(CassandraChatMemoryIT.TestApplication.class);

View File

@@ -36,11 +36,11 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.CassandraImage;
import org.testcontainers.containers.CassandraContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils;
import org.testcontainers.utility.DockerImageName;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingModel;
@@ -61,13 +61,12 @@ import static org.assertj.core.api.Assertions.assertThat;
* Use `mvn failsafe:integration-test -Dit.test=CassandraRichSchemaVectorStoreIT`
*
* @author Mick Semb Wever
* @author Thomas Vitale
* @since 1.0.0
*/
@Testcontainers
class CassandraRichSchemaVectorStoreIT {
static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("cassandra");
private static final Logger logger = LoggerFactory.getLogger(CassandraRichSchemaVectorStoreIT.class);
private static final List<Document> documents = List.of(
@@ -87,7 +86,7 @@ class CassandraRichSchemaVectorStoreIT {
private static final String URANUS_ORBIT_QUERY = "It was the first planet to be discovered using mathematics. In 1821, astronomers saw that Uranus orbit was different from what they expected. Another nearby planets mass was changing Uranus orbit.";
@Container
static CassandraContainer cassandraContainer = new CassandraContainer(DEFAULT_IMAGE_NAME.withTag("5.0"));
static CassandraContainer<?> cassandraContainer = new CassandraContainer<>(CassandraImage.DEFAULT_IMAGE);
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withUserConfiguration(TestApplication.class);

View File

@@ -29,10 +29,10 @@ import com.datastax.oss.driver.api.core.servererrors.SyntaxError;
import com.datastax.oss.driver.api.core.type.DataTypes;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.ai.CassandraImage;
import org.testcontainers.containers.CassandraContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingModel;
@@ -55,15 +55,14 @@ import static org.assertj.core.api.Assertions.assertThat;
* Use `mvn failsafe:integration-test -Dit.test=CassandraVectorStoreIT`
*
* @author Mick Semb Wever
* @author Thomas Vitale
* @since 1.0.0
*/
@Testcontainers
class CassandraVectorStoreIT {
static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("cassandra");
@Container
static CassandraContainer cassandraContainer = new CassandraContainer(DEFAULT_IMAGE_NAME.withTag("5.0"));
static CassandraContainer<?> cassandraContainer = new CassandraContainer<>(CassandraImage.DEFAULT_IMAGE);
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withUserConfiguration(TestApplication.class);

View File

@@ -23,6 +23,7 @@ import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.ai.CassandraImage;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.embedding.TokenCountBatchingStrategy;
@@ -42,7 +43,6 @@ import org.springframework.core.io.DefaultResourceLoader;
import org.testcontainers.containers.CassandraContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.CqlSessionBuilder;
@@ -59,10 +59,8 @@ import io.micrometer.observation.tck.TestObservationRegistryAssert;
@Testcontainers
public class CassandraVectorStoreObservationIT {
static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("cassandra");
@Container
static CassandraContainer cassandraContainer = new CassandraContainer(DEFAULT_IMAGE_NAME.withTag("5.0"));
static CassandraContainer<?> cassandraContainer = new CassandraContainer<>(CassandraImage.DEFAULT_IMAGE);
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withUserConfiguration(Config.class);

View File

@@ -22,6 +22,7 @@ import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.ai.ChromaImage;
import org.springframework.ai.chroma.ChromaApi.AddEmbeddingsRequest;
import org.springframework.ai.chroma.ChromaApi.Collection;
import org.springframework.ai.chroma.ChromaApi.GetEmbeddingsRequest;
@@ -37,13 +38,14 @@ import org.testcontainers.junit.jupiter.Testcontainers;
/**
* @author Christian Tzolov
* @author Eddú Meléndez
* @author Thomas Vitale
*/
@SpringBootTest
@Testcontainers
public class ChromaApiIT {
@Container
static ChromaDBContainer chromaContainer = new ChromaDBContainer("ghcr.io/chroma-core/chroma:0.5.0");
static ChromaDBContainer chromaContainer = new ChromaDBContainer(ChromaImage.DEFAULT_IMAGE);
@Autowired
ChromaApi chroma;

View File

@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.ai.ChromaImage;
import org.springframework.ai.chroma.ChromaApi;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingModel;
@@ -45,6 +46,7 @@ import org.testcontainers.utility.MountableFile;
*
* @author Christian Tzolov
* @author Eddú Meléndez
* @author Thomas Vitale
*/
@Testcontainers
public class BasicAuthChromaWhereIT {
@@ -54,7 +56,7 @@ public class BasicAuthChromaWhereIT {
* https://docs.trychroma.com/usage-guide#basic-authentication
*/
@Container
static ChromaDBContainer chromaContainer = new ChromaDBContainer("ghcr.io/chroma-core/chroma:0.5.0")
static ChromaDBContainer chromaContainer = new ChromaDBContainer(ChromaImage.DEFAULT_IMAGE)
.withEnv("CHROMA_SERVER_AUTHN_CREDENTIALS_FILE", "/chroma/server.htpasswd")
.withEnv("CHROMA_SERVER_AUTHN_PROVIDER", "chromadb.auth.basic_authn.BasicAuthenticationServerProvider")
.withCopyToContainer(MountableFile.forClasspathResource("server.htpasswd"), "/chroma/server.htpasswd");

View File

@@ -23,6 +23,7 @@ import java.util.Map;
import java.util.UUID;
import org.junit.jupiter.api.Test;
import org.springframework.ai.ChromaImage;
import org.springframework.ai.chroma.ChromaApi;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingModel;
@@ -40,12 +41,13 @@ import org.testcontainers.junit.jupiter.Testcontainers;
/**
* @author Christian Tzolov
* @author Eddú Meléndez
* @author Thomas Vitale
*/
@Testcontainers
public class ChromaVectorStoreIT {
@Container
static ChromaDBContainer chromaContainer = new ChromaDBContainer("ghcr.io/chroma-core/chroma:0.5.0");
static ChromaDBContainer chromaContainer = new ChromaDBContainer(ChromaImage.DEFAULT_IMAGE);
List<Document> documents = List.of(
new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!",

View File

@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.ai.ChromaImage;
import org.springframework.ai.chroma.ChromaApi;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingModel;
@@ -45,6 +46,7 @@ import org.testcontainers.junit.jupiter.Testcontainers;
*
* @author Christian Tzolov
* @author Eddú Meléndez
* @author Thomas Vitale
*/
@Testcontainers
public class TokenSecuredChromaWhereIT {
@@ -56,7 +58,7 @@ public class TokenSecuredChromaWhereIT {
* https://docs.trychroma.com/deployment/auth
*/
@Container
static ChromaDBContainer chromaContainer = new ChromaDBContainer("ghcr.io/chroma-core/chroma:0.5.0")
static ChromaDBContainer chromaContainer = new ChromaDBContainer(ChromaImage.DEFAULT_IMAGE)
.withEnv("CHROMA_SERVER_AUTHN_CREDENTIALS", CHROMA_SERVER_AUTH_CREDENTIALS)
.withEnv("CHROMA_SERVER_AUTHN_PROVIDER", "chromadb.auth.token_authn.TokenAuthenticationServerProvider");

View File

@@ -66,7 +66,7 @@ class ElasticsearchVectorStoreIT {
@Container
private static final ElasticsearchContainer elasticsearchContainer = new ElasticsearchContainer(
"docker.elastic.co/elasticsearch/elasticsearch:8.13.3")
ElasticsearchImage.DEFAULT_IMAGE)
.withEnv("xpack.security.enabled", "false");
private final List<Document> documents = List.of(

View File

@@ -46,6 +46,7 @@ import org.springframework.core.io.DefaultResourceLoader;
/**
* @author Geet Rawat
* @author Soby Chacko
* @author Thomas Vitale
* @since 1.0.0
*/
public class GemFireVectorStoreIT {
@@ -70,7 +71,7 @@ public class GemFireVectorStoreIT {
Ports.Binding hostPort = Ports.Binding.bindPort(HTTP_SERVICE_PORT);
ExposedPort exposedPort = new ExposedPort(HTTP_SERVICE_PORT);
PortBinding mappedPort = new PortBinding(hostPort, exposedPort);
gemFireCluster = new GemFireCluster("gemfire/gemfire-all:10.1-jdk17", LOCATOR_COUNT, SERVER_COUNT);
gemFireCluster = new GemFireCluster(GemFireImage.DEFAULT_IMAGE, LOCATOR_COUNT, SERVER_COUNT);
gemFireCluster.withConfiguration(GemFireCluster.SERVER_GLOB,
container -> container.withExposedPorts(HTTP_SERVICE_PORT)
.withCreateContainerCmdModifier(cmd -> cmd.getHostConfig().withPortBindings(mappedPort)));

View File

@@ -52,13 +52,14 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Christian Tzolov
* @author Eddú Meléndez
* @author Thomas Vitale
*/
@Testcontainers
@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
public class MilvusVectorStoreIT {
@Container
private static MilvusContainer milvusContainer = new MilvusContainer("milvusdb/milvus:v2.3.8");
private static MilvusContainer milvusContainer = new MilvusContainer(MilvusImage.DEFAULT_IMAGE);
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withUserConfiguration(TestApplication.class);

View File

@@ -51,13 +51,13 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Chris Smith
* @author Soby Chacko
* @author Eddú Meléndez
* @author Thomas Vitale
*/
@Testcontainers
class MongoDBAtlasVectorStoreIT {
@Container
private static MongoDBAtlasLocalContainer container = new MongoDBAtlasLocalContainer(
"mongodb/mongodb-atlas-local:7.0.9");
private static MongoDBAtlasLocalContainer container = new MongoDBAtlasLocalContainer(MongoDbImage.DEFAULT_IMAGE);
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withUserConfiguration(TestApplication.class)

View File

@@ -22,6 +22,8 @@ import org.testcontainers.utility.DockerImageName;
*/
public class Neo4jImage {
// Needs to be Neo4j 5.15+ because Neo4j 5.15 deprecated the old vector index creation
// function.
public static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse("neo4j:5.24");
}

View File

@@ -31,7 +31,6 @@ import org.springframework.ai.vectorstore.filter.FilterExpressionTextParser;
import org.testcontainers.containers.Neo4jContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingModel;
@@ -49,17 +48,14 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Gerrit Meier
* @author Michael Simons
* @author Christian Tzolov
* @author Thomas Vitale
*/
@Testcontainers
@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
class Neo4jVectorStoreIT {
// Needs to be Neo4j 5.15+, because Neo4j 5.15 deprecated the old vector index
// creation
// function.
@Container
static Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>(DockerImageName.parse("neo4j:5.18"))
.withRandomPassword();
static Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>(Neo4jImage.DEFAULT_IMAGE).withRandomPassword();
List<Document> documents = List.of(
new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!",

View File

@@ -38,7 +38,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.core.io.DefaultResourceLoader;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import java.io.IOException;
import java.net.URISyntaxException;
@@ -58,6 +57,7 @@ import static org.hamcrest.Matchers.hasSize;
/**
* @author Jemin Huh
* @author Soby Chacko
* @author Thomas Vitale
* @since 1.0.0
*/
@Testcontainers
@@ -66,7 +66,7 @@ class OpenSearchVectorStoreIT {
@Container
private static final OpensearchContainer<?> opensearchContainer = new OpensearchContainer<>(
DockerImageName.parse("opensearchproject/opensearch:2.13.0"));
OpenSearchImage.DEFAULT_IMAGE);
private static final String DEFAULT = "cosinesimil";

View File

@@ -43,9 +43,8 @@ import static org.springframework.ai.vectorstore.OracleVectorStore.DEFAULT_SEARC
public class OracleVectorStoreIT {
@Container
static OracleContainer oracle23aiContainer = new OracleContainer("gvenzl/oracle-free:23-slim")
.withCopyFileToContainer(MountableFile.forClasspathResource("/initialize.sql"),
"/container-entrypoint-initdb.d/initialize.sql");
static OracleContainer oracle23aiContainer = new OracleContainer(OracleImage.DEFAULT_IMAGE).withCopyFileToContainer(
MountableFile.forClasspathResource("/initialize.sql"), "/container-entrypoint-initdb.d/initialize.sql");
final List<Document> documents = List.of(
new Document(getText("classpath:/test/data/spring.ai.txt"), Map.of("meta1", "meta1")),

View File

@@ -43,13 +43,14 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Muthukumaran Navaneethakrishnan
* @author Thomas Vitale
*/
@Testcontainers
public class PgVectorStoreCustomNamesIT {
@Container
@SuppressWarnings("resource")
static PostgreSQLContainer<?> postgresContainer = new PostgreSQLContainer<>("pgvector/pgvector:pg16")
static PostgreSQLContainer<?> postgresContainer = new PostgreSQLContainer<>(PgVectorImage.DEFAULT_IMAGE)
.withUsername("postgres")
.withPassword("postgres");

View File

@@ -62,6 +62,7 @@ import com.zaxxer.hikari.HikariDataSource;
/**
* @author Muthukumaran Navaneethakrishnan
* @author Christian Tzolov
* @author Thomas Vitale
*/
@Testcontainers
@EnabledIfEnvironmentVariable(named = "OPENAI_API_KEY", matches = ".+")
@@ -69,7 +70,7 @@ public class PgVectorStoreIT {
@Container
@SuppressWarnings("resource")
static PostgreSQLContainer<?> postgresContainer = new PostgreSQLContainer<>("pgvector/pgvector:pg16")
static PostgreSQLContainer<?> postgresContainer = new PostgreSQLContainer<>(PgVectorImage.DEFAULT_IMAGE)
.withUsername("postgres")
.withPassword("postgres");

View File

@@ -50,6 +50,7 @@ import org.testcontainers.junit.jupiter.Testcontainers;
/**
* @author Fabian Krüger
* @author Soby Chacko
* @author Thomas Vitale
*/
@Testcontainers
class PgVectorStoreWithChatMemoryAdvisorIT {
@@ -58,7 +59,7 @@ class PgVectorStoreWithChatMemoryAdvisorIT {
@Container
@SuppressWarnings("resource")
static PostgreSQLContainer<?> postgresContainer = new PostgreSQLContainer<>("pgvector/pgvector:pg16")
static PostgreSQLContainer<?> postgresContainer = new PostgreSQLContainer<>(PgVectorImage.DEFAULT_IMAGE)
.withUsername("postgres")
.withPassword("postgres");

View File

@@ -60,7 +60,7 @@ public class QdrantVectorStoreIT {
private static final int EMBEDDING_DIMENSION = 1024;
@Container
static QdrantContainer qdrantContainer = new QdrantContainer("qdrant/qdrant:v1.9.2");
static QdrantContainer qdrantContainer = new QdrantContainer(QdrantImage.DEFAULT_IMAGE);
List<Document> documents = List.of(
new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!",

View File

@@ -49,12 +49,13 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Pablo Sanchidrian Herrera
* @author Eddú Meléndez
* @author Soby Chacko
* @author Thomas Vitale
*/
@Testcontainers
public class TypesenseVectorStoreIT {
@Container
private static GenericContainer<?> typesenseContainer = new GenericContainer<>("typesense/typesense:26.0")
private static GenericContainer<?> typesenseContainer = new GenericContainer<>(TypesenseImage.DEFAULT_IMAGE)
.withExposedPorts(8108)
.withCommand("--data-dir", "/tmp", "--api-key=xyz", "--enable-cors");

View File

@@ -47,12 +47,13 @@ import io.weaviate.client.WeaviateClient;
* @author Christian Tzolov
* @author Eddú Meléndez
* @author Soby Chacko
* @author Thomas Vitale
*/
@Testcontainers
public class WeaviateVectorStoreIT {
@Container
static WeaviateContainer weaviateContainer = new WeaviateContainer("semitechnologies/weaviate:1.25.4")
static WeaviateContainer weaviateContainer = new WeaviateContainer(WeaviateImage.DEFAULT_IMAGE)
.waitingFor(Wait.forHttp("/v1/.well-known/ready").forPort(8080));
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()