This is an automated email from the ASF dual-hosted git repository.
jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push:
new a1a1cd85e2 Use Pinecone emulator for integration testing
a1a1cd85e2 is described below
commit a1a1cd85e220abb432728f4be3876b9d42448685
Author: Jono Morris <[email protected]>
AuthorDate: Sat Apr 12 00:08:13 2025 +1200
Use Pinecone emulator for integration testing
* use pinecone emulator for testing
* Add profile for windows build
---
integration-tests/pinecone/pom.xml | 27 ++++++++++++
.../component/pinecone/it/PineconeResource.java | 31 ++------------
.../component/pinecone/it/PineconeTest.java | 38 +++++++----------
.../pinecone/it/PineconeTestResource.java | 48 ++++++++++++++++------
...dexes-0cb5785f-987c-481d-b49a-51dac8cc4a5a.json | 29 -------------
...dexes-293cf644-849f-4860-809f-13278d509acb.json | 30 --------------
...dexes-5854cd4f-0384-40dd-bfa5-bf36592d3a9b.json | 33 ---------------
...index-92a8d520-01e3-48ae-89eb-1f51beed3276.json | 26 ------------
pom.xml | 1 +
9 files changed, 83 insertions(+), 180 deletions(-)
diff --git a/integration-tests/pinecone/pom.xml
b/integration-tests/pinecone/pom.xml
index c8707b0f41..2ce380fa1a 100644
--- a/integration-tests/pinecone/pom.xml
+++ b/integration-tests/pinecone/pom.xml
@@ -57,6 +57,22 @@
</dependency>
<!-- test dependencies -->
+ <dependency>
+ <groupId>org.testcontainers</groupId>
+ <artifactId>pinecone</artifactId>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-junit4-mock</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
@@ -144,6 +160,17 @@
</dependency>
</dependencies>
</profile>
+ <profile>
+ <id>skip-testcontainers-tests</id>
+ <activation>
+ <property>
+ <name>skip-testcontainers-tests</name>
+ </property>
+ </activation>
+ <properties>
+ <skipTests>true</skipTests>
+ </properties>
+ </profile>
</profiles>
</project>
diff --git
a/integration-tests/pinecone/src/main/java/org/apache/camel/quarkus/component/pinecone/it/PineconeResource.java
b/integration-tests/pinecone/src/main/java/org/apache/camel/quarkus/component/pinecone/it/PineconeResource.java
index 9f2d7da503..bf937ea3c4 100644
---
a/integration-tests/pinecone/src/main/java/org/apache/camel/quarkus/component/pinecone/it/PineconeResource.java
+++
b/integration-tests/pinecone/src/main/java/org/apache/camel/quarkus/component/pinecone/it/PineconeResource.java
@@ -16,9 +16,7 @@
*/
package org.apache.camel.quarkus.component.pinecone.it;
-import java.io.IOException;
import java.util.List;
-import java.util.Optional;
import io.pinecone.clients.Pinecone;
import io.pinecone.proto.UpsertResponse;
@@ -35,15 +33,10 @@ import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
-import okhttp3.Interceptor;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.Response;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.component.pinecone.PineconeVectorDbComponent;
import org.apache.camel.component.pinecone.PineconeVectorDbConfiguration;
import org.eclipse.microprofile.config.ConfigProvider;
-import org.jetbrains.annotations.NotNull;
import org.openapitools.db_control.client.model.IndexModel;
@Path("/pinecone")
@@ -100,26 +93,10 @@ public class PineconeResource {
}
static Pinecone createPineconeClient() {
- Optional<String> wireMockUrl =
ConfigProvider.getConfig().getOptionalValue("wiremock.url", String.class);
- String apiKey =
ConfigProvider.getConfig().getValue("camel.component.pinecone.token",
String.class);
- Pinecone.Builder builder = new Pinecone.Builder(apiKey);
- if (wireMockUrl.isPresent()) {
- String baseUri = wireMockUrl.get();
- OkHttpClient client = new OkHttpClient.Builder()
- .addInterceptor(new Interceptor() {
- @NotNull
- @Override
- public Response intercept(@NotNull Interceptor.Chain
chain) throws IOException {
- Request originalRequest = chain.request();
- Request wireMockedRequest =
originalRequest.newBuilder()
- .url(baseUri +
originalRequest.url().encodedPath())
- .build();
- return chain.proceed(wireMockedRequest);
- }
- })
- .build();
- return builder.withOkHttpClient(client).build();
- }
+ String endpoint =
ConfigProvider.getConfig().getValue("pinecone.emulator.endpoint", String.class);
+ Pinecone.Builder builder = new Pinecone.Builder("pclocal")
+ .withHost(endpoint)
+ .withTlsEnabled(false);
return builder.build();
}
}
diff --git
a/integration-tests/pinecone/src/test/java/org/apache/camel/quarkus/component/pinecone/it/PineconeTest.java
b/integration-tests/pinecone/src/test/java/org/apache/camel/quarkus/component/pinecone/it/PineconeTest.java
index 3f5fc4f2f4..2884e1be44 100644
---
a/integration-tests/pinecone/src/test/java/org/apache/camel/quarkus/component/pinecone/it/PineconeTest.java
+++
b/integration-tests/pinecone/src/test/java/org/apache/camel/quarkus/component/pinecone/it/PineconeTest.java
@@ -18,14 +18,12 @@ package org.apache.camel.quarkus.component.pinecone.it;
import java.time.Duration;
import java.util.List;
-import java.util.Optional;
import io.pinecone.clients.Pinecone;
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
-import org.eclipse.microprofile.config.ConfigProvider;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openapitools.db_control.client.model.IndexModel;
@@ -70,32 +68,26 @@ class PineconeTest {
.anyMatch(status -> status.getState().equals(READY));
});
- // Some index endpoints are not mocked:
- // - They use a dynamic host, separate from the core pinecone API
endpoints
- // - They are gRPC endpoints
- Optional<String> wireMockUrl =
ConfigProvider.getConfig().getOptionalValue("wiremock.url", String.class);
- if (!wireMockUrl.isPresent()) {
- // Upsert
- List<Float> vectors = List.of(1.0f, 2.0f, 3.0f);
+ // Upsert
+ List<Float> vectors = List.of(1.0f, 2.0f, 3.0f);
+ RestAssured.given()
+ .contentType(ContentType.JSON)
+ .body(vectors)
+ .put("/pinecone/index")
+ .then()
+ .statusCode(200)
+ .body(is("1"));
+
+ // Query upserted data by vector
+
await().pollInterval(Duration.ofSeconds(1)).atMost(Duration.ofSeconds(30)).untilAsserted(()
-> {
RestAssured.given()
.contentType(ContentType.JSON)
.body(vectors)
- .put("/pinecone/index")
+ .get("/pinecone/index")
.then()
.statusCode(200)
- .body(is("1"));
-
- // Query upserted data by vector
-
await().pollInterval(Duration.ofSeconds(1)).atMost(Duration.ofSeconds(30)).untilAsserted(()
-> {
- RestAssured.given()
- .contentType(ContentType.JSON)
- .body(vectors)
- .get("/pinecone/index")
- .then()
- .statusCode(200)
- .body(startsWith("0.9"));
- });
- }
+ .body(startsWith("0.9"));
+ });
} finally {
RestAssured.given()
.delete("/pinecone/index")
diff --git
a/integration-tests/pinecone/src/test/java/org/apache/camel/quarkus/component/pinecone/it/PineconeTestResource.java
b/integration-tests/pinecone/src/test/java/org/apache/camel/quarkus/component/pinecone/it/PineconeTestResource.java
index a639c6d6ff..b884ada52f 100644
---
a/integration-tests/pinecone/src/test/java/org/apache/camel/quarkus/component/pinecone/it/PineconeTestResource.java
+++
b/integration-tests/pinecone/src/test/java/org/apache/camel/quarkus/component/pinecone/it/PineconeTestResource.java
@@ -16,28 +16,52 @@
*/
package org.apache.camel.quarkus.component.pinecone.it;
+import java.util.List;
import java.util.Map;
-import
org.apache.camel.quarkus.test.wiremock.WireMockTestResourceLifecycleManager;
+import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
import org.apache.camel.util.CollectionHelper;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.output.Slf4jLogConsumer;
+import org.testcontainers.containers.wait.strategy.Wait;
+import org.testcontainers.pinecone.PineconeLocalContainer;
-public class PineconeTestResource extends WireMockTestResourceLifecycleManager
{
- public static final String PINECONE_API_BASE_URL =
"https://api.pinecone.io";
- private static final String PINECONE_API_KEY_ENV = "PINECONE_API_KEY";
+public class PineconeTestResource implements
QuarkusTestResourceLifecycleManager {
+
+ private static final Logger log =
LoggerFactory.getLogger(PineconeTestResource.class);
+ private static final String PINECONE_IMAGE =
ConfigProvider.getConfig().getValue("pinecone.container.image", String.class);
+
+ private PineconeLocalContainer container;
@Override
public Map<String, String> start() {
- return CollectionHelper.mergeMaps(super.start(),
CollectionHelper.mapOf(
- "camel.component.pinecone.token",
envOrDefault(PINECONE_API_KEY_ENV, "test-pinecone-api-key")));
- }
+ try {
+ container = new PineconeLocalContainer(PINECONE_IMAGE)
+ .withLogConsumer(new Slf4jLogConsumer(log))
+ .waitingFor(Wait.forListeningPort());
- @Override
- protected String getRecordTargetBaseUrl() {
- return PINECONE_API_BASE_URL;
+ // port 5081 for the index
+ container.setPortBindings(List.of("5080:5080", "5081:5081"));
+
+ container.start();
+
+ return CollectionHelper.mapOf("pinecone.emulator.endpoint",
container.getEndpoint());
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
@Override
- protected boolean isMockingEnabled() {
- return !envVarsPresent("PINECONE_API_KEY");
+ public void stop() {
+ try {
+ if (container != null) {
+ container.stop();
+ }
+ } catch (Exception e) {
+ // ignored
+ }
}
}
diff --git
a/integration-tests/pinecone/src/test/resources/mappings/indexes-0cb5785f-987c-481d-b49a-51dac8cc4a5a.json
b/integration-tests/pinecone/src/test/resources/mappings/indexes-0cb5785f-987c-481d-b49a-51dac8cc4a5a.json
deleted file mode 100644
index fbcfc19f22..0000000000
---
a/integration-tests/pinecone/src/test/resources/mappings/indexes-0cb5785f-987c-481d-b49a-51dac8cc4a5a.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "id" : "0cb5785f-987c-481d-b49a-51dac8cc4a5a",
- "name" : "indexes",
- "request" : {
- "url" : "/indexes",
- "method" : "GET"
- },
- "response" : {
- "status" : 200,
- "body" : "{\"indexes\":[]}",
- "headers" : {
- "X-Cloud-Trace-Context" : "bd4d9cb6698e7373332f57eaeeea6592",
- "access-control-allow-origin" : "*",
- "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000",
- "Server" : "Google Frontend",
- "vary" :
"origin,access-control-request-method,access-control-request-headers",
- "content-type" : "application/json",
- "Date" : "Fri, 22 Nov 2024 09:23:39 GMT",
- "Via" : "1.1 google",
- "x-pinecone-api-version" : "2024-10",
- "access-control-expose-headers" : "*"
- }
- },
- "uuid" : "0cb5785f-987c-481d-b49a-51dac8cc4a5a",
- "persistent" : true,
- "scenarioName" : "scenario-1-indexes",
- "requiredScenarioState" : "scenario-1-indexes-2",
- "insertionIndex" : 1
-}
\ No newline at end of file
diff --git
a/integration-tests/pinecone/src/test/resources/mappings/indexes-293cf644-849f-4860-809f-13278d509acb.json
b/integration-tests/pinecone/src/test/resources/mappings/indexes-293cf644-849f-4860-809f-13278d509acb.json
deleted file mode 100644
index 39aef73586..0000000000
---
a/integration-tests/pinecone/src/test/resources/mappings/indexes-293cf644-849f-4860-809f-13278d509acb.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "id" : "293cf644-849f-4860-809f-13278d509acb",
- "name" : "indexes",
- "request" : {
- "url" : "/indexes",
- "method" : "GET"
- },
- "response" : {
- "status" : 200,
- "body" :
"{\"indexes\":[{\"name\":\"test-index\",\"metric\":\"cosine\",\"dimension\":3,\"status\":{\"ready\":true,\"state\":\"Ready\"},\"host\":\"test-index-3ncz9x1.svc.aped-4627-b74a.pinecone.io\",\"spec\":{\"serverless\":{\"region\":\"us-east-1\",\"cloud\":\"aws\"}},\"deletion_protection\":\"disabled\",\"tags\":null}]}",
- "headers" : {
- "X-Cloud-Trace-Context" : "5d76189a457047bf315cdd0913392ffe",
- "access-control-allow-origin" : "*",
- "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000",
- "Server" : "Google Frontend",
- "vary" :
"origin,access-control-request-method,access-control-request-headers",
- "content-type" : "application/json",
- "Date" : "Fri, 22 Nov 2024 09:23:37 GMT",
- "Via" : "1.1 google",
- "x-pinecone-api-version" : "2024-10",
- "access-control-expose-headers" : "*"
- }
- },
- "uuid" : "293cf644-849f-4860-809f-13278d509acb",
- "persistent" : true,
- "scenarioName" : "scenario-1-indexes",
- "requiredScenarioState" : "Started",
- "newScenarioState" : "scenario-1-indexes-2",
- "insertionIndex" : 3
-}
\ No newline at end of file
diff --git
a/integration-tests/pinecone/src/test/resources/mappings/indexes-5854cd4f-0384-40dd-bfa5-bf36592d3a9b.json
b/integration-tests/pinecone/src/test/resources/mappings/indexes-5854cd4f-0384-40dd-bfa5-bf36592d3a9b.json
deleted file mode 100644
index 6fa62e106d..0000000000
---
a/integration-tests/pinecone/src/test/resources/mappings/indexes-5854cd4f-0384-40dd-bfa5-bf36592d3a9b.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "id" : "5854cd4f-0384-40dd-bfa5-bf36592d3a9b",
- "name" : "indexes",
- "request" : {
- "url" : "/indexes",
- "method" : "POST",
- "bodyPatterns" : [ {
- "equalToJson" :
"{\"name\":\"test-index\",\"dimension\":3,\"metric\":\"cosine\",\"deletion_protection\":\"disabled\",\"spec\":{\"serverless\":{\"cloud\":\"aws\",\"region\":\"us-east-1\"}}}",
- "ignoreArrayOrder" : true,
- "ignoreExtraElements" : true
- } ]
- },
- "response" : {
- "status" : 201,
- "body" :
"{\"name\":\"test-index\",\"metric\":\"cosine\",\"dimension\":3,\"status\":{\"ready\":false,\"state\":\"Initializing\"},\"host\":\"test-index-3ncz9x1.svc.aped-4627-b74a.pinecone.io\",\"spec\":{\"serverless\":{\"region\":\"us-east-1\",\"cloud\":\"aws\"}},\"deletion_protection\":\"disabled\",\"tags\":null}",
- "headers" : {
- "X-Cloud-Trace-Context" : "7cae6b2507fa30364f1f71182f9319aa",
- "access-control-allow-origin" : "*",
- "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000",
- "Server" : "Google Frontend",
- "vary" :
"origin,access-control-request-method,access-control-request-headers",
- "content-type" : "application/json",
- "x-pinecone-operation-id" : "4e23a028-63e6-430d-9c8a-bbfab9596819",
- "Date" : "Fri, 22 Nov 2024 09:23:35 GMT",
- "Via" : "1.1 google",
- "x-pinecone-api-version" : "2024-10",
- "access-control-expose-headers" : "*"
- }
- },
- "uuid" : "5854cd4f-0384-40dd-bfa5-bf36592d3a9b",
- "persistent" : true,
- "insertionIndex" : 4
-}
\ No newline at end of file
diff --git
a/integration-tests/pinecone/src/test/resources/mappings/indexes_test-index-92a8d520-01e3-48ae-89eb-1f51beed3276.json
b/integration-tests/pinecone/src/test/resources/mappings/indexes_test-index-92a8d520-01e3-48ae-89eb-1f51beed3276.json
deleted file mode 100644
index 28585d8222..0000000000
---
a/integration-tests/pinecone/src/test/resources/mappings/indexes_test-index-92a8d520-01e3-48ae-89eb-1f51beed3276.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "id" : "92a8d520-01e3-48ae-89eb-1f51beed3276",
- "name" : "indexes_test-index",
- "request" : {
- "url" : "/indexes/test-index",
- "method" : "DELETE"
- },
- "response" : {
- "status" : 202,
- "headers" : {
- "X-Cloud-Trace-Context" : "99e9c93ac1094bbc1a4df5f322b49a40",
- "access-control-allow-origin" : "*",
- "Alt-Svc" : "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000",
- "Server" : "Google Frontend",
- "vary" :
"origin,access-control-request-method,access-control-request-headers",
- "Date" : "Fri, 22 Nov 2024 09:23:37 GMT",
- "Via" : "1.1 google",
- "Content-Type" : "text/html",
- "x-pinecone-api-version" : "2024-10",
- "access-control-expose-headers" : "*"
- }
- },
- "uuid" : "92a8d520-01e3-48ae-89eb-1f51beed3276",
- "persistent" : true,
- "insertionIndex" : 2
-}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index a9e6047406..1a14a17272 100644
--- a/pom.xml
+++ b/pom.xml
@@ -256,6 +256,7 @@
<mongodb.container.image>mirror.gcr.io/mongo:7.0</mongodb.container.image>
<nats.container.image>mirror.gcr.io/nats:2.10.18</nats.container.image>
<openssh-server.container.image>mirror.gcr.io/linuxserver/openssh-server:version-9.7_p1-r4</openssh-server.container.image>
+
<pinecone.container.image>ghcr.io/pinecone-io/pinecone-local:v0.7.0</pinecone.container.image>
<postgres.container.image>mirror.gcr.io/postgres:15.0</postgres.container.image>
<postgres-debezium.container.image>mirror.gcr.io/debezium/postgres:15-alpine</postgres-debezium.container.image>
<qdrant.container.image>mirror.gcr.io/qdrant/qdrant:v1.9.7-unprivileged</qdrant.container.image>