Skip to content

Commit

Permalink
chore(java): use Testcontainers OpenFGA module for integration tests (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
rhamzeh authored Mar 27, 2024
2 parents 81b9dca + fdc9ea4 commit f183ded
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 30 deletions.
13 changes: 9 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Main config
OPENFGA_DOCKER_TAG = v1.4.0
OPENFGA_DOCKER_TAG = v1.5.1
OPEN_API_REF ?= main
OPEN_API_URL = https://raw.githubusercontent.com/openfga/api/${OPEN_API_REF}/docs/openapiv2/apidocs.swagger.json
OPENAPI_GENERATOR_CLI_DOCKER_TAG = v6.4.0
Expand All @@ -17,6 +17,12 @@ DOCS_CACHE_DIR = ${PWD}/docs/openapi
TMP_DIR = $(shell mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXX")
CURRENT_UID := $(shell id -u)
CURRENT_GID := $(shell id -g)
# Determine if Docker is being used via Docker Desktop, if so we need to tell testcontainers to
# use the Docker Desktop host. We can't just always set this because GitHub Actions will fail.
DOCKER_PLATFORM := $(shell docker version -f json | jq .Server.Platform.Name)
ifeq ($(findstring Docker Desktop,$(DOCKER_PLATFORM)),Docker Desktop)
TEST_CONTAINERS_ENV=-e TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal
endif

all: test-all-clients

Expand Down Expand Up @@ -134,17 +140,16 @@ test-client-java: build-client-java

.PHONY: test-integration-client-java
test-integration-client-java: test-client-java
docker container rm --force openfga-for-java-client || true
docker run --detach --name openfga-for-java-client -p 8080:8080 openfga/openfga:${OPENFGA_DOCKER_TAG} run
make run-in-docker sdk_language=java image=gradle:${GRADLE_DOCKER_TAG} command="/bin/sh -c 'gradle test-integration'"
docker container rm --force openfga-for-java-client

.PHONY: run-in-docker
run-in-docker:
docker run --rm \
-v "${CLIENTS_OUTPUT_DIR}/fga-${sdk_language}-sdk":/module \
-v ${CONFIG_DIR}:/config \
-v /var/run/docker.sock:/var/run/docker.sock \
-w /module \
$(TEST_CONTAINERS_ENV) \
--net="host" \
${image} \
${command}
Expand Down
2 changes: 1 addition & 1 deletion config/clients/java/config.overrides.json
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@
"destinationFilename": "example/example1/src/main/kotlin/dev/openfga/sdk/example/KotlinExample1.kt",
"templateType": "SupportingFiles"
},
"ExampleTest.java" : {
"ExampleTest.java.mustache" : {
"destinationFilename": "src/test-integration/java/dev/openfga/sdk/example/ExampleTest.java",
"templateType": "SupportingFiles"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ jobs:
# runs tests and lints. See the project's build.gradle for configurations.
- name: Test and Build with Gradle
run: |
./gradlew build
./gradlew build test-integration


publish-maven-central:
runs-on: ubuntu-latest
Expand Down
13 changes: 0 additions & 13 deletions config/clients/java/template/ExampleTest.java

This file was deleted.

21 changes: 21 additions & 0 deletions config/clients/java/template/ExampleTest.java.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package dev.openfga.sdk.example;

import org.junit.jupiter.api.Test;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.openfga.OpenFGAContainer;

@Testcontainers
public class ExampleTest {
@Container
private static final OpenFGAContainer openfga = new OpenFGAContainer("openfga/openfga:{{openFGADockerTag}}");
private final Example1 example1 = new Example1();
@Test
public void example1() throws Exception {
example1.module = "test-integration";
example1.run(openfga.getHttpEndpoint());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import static org.junit.jupiter.api.Assertions.*;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import {{clientPackage}}.model.*;
import {{configPackage}}.*;
import {{modelPackage}}.*;
import java.io.IOException;
Expand All @@ -19,9 +18,17 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.openfga.OpenFGAContainer;

@TestInstance(Lifecycle.PER_CLASS)
@Testcontainers
public class OpenFgaApiIntegrationTest {
@Container
private static final OpenFGAContainer openfga = new OpenFGAContainer("openfga/openfga:{{openFGADockerTag}}");
private static final ObjectMapper mapper = new ObjectMapper().findAndRegisterModules();
private static final String DEFAULT_USER = "user:81684243-9356-4421-8fbf-a4f8d36aa31b";
private static final String DEFAULT_DOC = "document:2021-budget";
Expand All @@ -41,7 +48,7 @@ public class OpenFgaApiIntegrationTest {
public void initializeApi() throws Exception {
System.setProperty("HttpRequestAttempt.debug-logging", "enable");
Configuration apiConfig = new Configuration().apiUrl("http://localhost:8080");
Configuration apiConfig = new Configuration().apiUrl(openfga.getHttpEndpoint());
api = new OpenFgaApi(apiConfig);
}

Expand Down Expand Up @@ -124,7 +131,7 @@ public class OpenFgaApiIntegrationTest {
assertEquals(authModelId, authModel.getId());
String typeDefsJson = mapper.writeValueAsString(authModel.getTypeDefinitions());
assertEquals(
"[{\"type\":\"user\",\"relations\":{},\"metadata\":null},{\"type\":\"document\",\"relations\":{\"owner\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"reader\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"writer\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null}},\"metadata\":{\"relations\":{\"conditional_reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"name_starts_with_a\"}]},\"owner\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}]},\"reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}]},\"writer\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}]}}}}]",
"[{\"type\":\"user\",\"relations\":{},\"metadata\":null},{\"type\":\"document\",\"relations\":{\"owner\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"reader\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"writer\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null}},\"metadata\":{\"relations\":{\"conditional_reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"name_starts_with_a\"}],\"module\":\"\",\"source_info\":null},\"owner\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}],\"module\":\"\",\"source_info\":null},\"reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}],\"module\":\"\",\"source_info\":null},\"writer\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}],\"module\":\"\",\"source_info\":null}},\"module\":\"\",\"source_info\":null}}]",
typeDefsJson);
}

Expand All @@ -148,7 +155,7 @@ public class OpenFgaApiIntegrationTest {
String typeDefsJson = mapper.writeValueAsString(authModel.getTypeDefinitions());
assertEquals(
"[{\"type\":\"user\",\"relations\":{},\"metadata\":null},{\"type\":\"document\",\"relations\":{\"owner\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"reader\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"writer\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null}},\"metadata\":{\"relations\":{\"conditional_reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"name_starts_with_a\"}]},\"owner\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}]},\"reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}]},\"writer\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}]}}}}]",
"[{\"type\":\"user\",\"relations\":{},\"metadata\":null},{\"type\":\"document\",\"relations\":{\"owner\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"reader\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"writer\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null}},\"metadata\":{\"relations\":{\"conditional_reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"name_starts_with_a\"}],\"module\":\"\",\"source_info\":null},\"owner\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}],\"module\":\"\",\"source_info\":null},\"reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}],\"module\":\"\",\"source_info\":null},\"writer\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}],\"module\":\"\",\"source_info\":null}},\"module\":\"\",\"source_info\":null}}]",
typeDefsJson);
} catch (JsonProcessingException ex) {
assertNull(ex);
Expand Down
2 changes: 2 additions & 0 deletions config/clients/java/template/build.gradle.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ testing {
dependencies {
implementation "com.fasterxml.jackson.core:jackson-core:$jackson_version"
implementation "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
implementation "org.testcontainers:junit-jupiter:1.19.7"
implementation "org.testcontainers:openfga:1.19.7"
implementation project()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,17 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.openfga.OpenFGAContainer;

@TestInstance(Lifecycle.PER_CLASS)
@Testcontainers
public class OpenFgaClientIntegrationTest {
@Container
private static final OpenFGAContainer openfga = new OpenFGAContainer("openfga/openfga:{{openFGADockerTag}}");
private static final ObjectMapper mapper = new ObjectMapper().findAndRegisterModules();
private static final String DEFAULT_USER = "user:81684243-9356-4421-8fbf-a4f8d36aa31b";
private static final String DEFAULT_DOC = "document:2021-budget";
Expand Down Expand Up @@ -52,7 +60,7 @@ public class OpenFgaClientIntegrationTest {
public void initializeApi() throws Exception {
System.setProperty("HttpRequestAttempt.debug-logging", "enable");
ClientConfiguration apiConfig = new ClientConfiguration().apiUrl("http://localhost:8080");
ClientConfiguration apiConfig = new ClientConfiguration().apiUrl(openfga.getHttpEndpoint());
fga = new OpenFgaClient(apiConfig);
}

Expand Down Expand Up @@ -142,7 +150,7 @@ public class OpenFgaClientIntegrationTest {
assertEquals(authModelId, response.getAuthorizationModel().getId());
String typeDefsJson = mapper.writeValueAsString(authModel.getTypeDefinitions());
assertEquals(
"[{\"type\":\"user\",\"relations\":{},\"metadata\":null},{\"type\":\"document\",\"relations\":{\"owner\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"reader\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"writer\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null}},\"metadata\":{\"relations\":{\"conditional_reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"name_starts_with_a\"}]},\"owner\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}]},\"reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}]},\"writer\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}]}}}}]",
"[{\"type\":\"user\",\"relations\":{},\"metadata\":null},{\"type\":\"document\",\"relations\":{\"owner\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"reader\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"writer\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null}},\"metadata\":{\"relations\":{\"conditional_reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"name_starts_with_a\"}],\"module\":\"\",\"source_info\":null},\"owner\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}],\"module\":\"\",\"source_info\":null},\"reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}],\"module\":\"\",\"source_info\":null},\"writer\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}],\"module\":\"\",\"source_info\":null}},\"module\":\"\",\"source_info\":null}}]",
typeDefsJson);
}

Expand Down Expand Up @@ -170,7 +178,7 @@ public class OpenFgaClientIntegrationTest {
String typeDefsJson = mapper.writeValueAsString(authModel.getTypeDefinitions());
assertEquals(
"[{\"type\":\"user\",\"relations\":{},\"metadata\":null},{\"type\":\"document\",\"relations\":{\"owner\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"reader\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"writer\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null}},\"metadata\":{\"relations\":{\"conditional_reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"name_starts_with_a\"}]},\"owner\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}]},\"reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}]},\"writer\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}]}}}}]",
"[{\"type\":\"user\",\"relations\":{},\"metadata\":null},{\"type\":\"document\",\"relations\":{\"owner\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"reader\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null},\"writer\":{\"this\":{},\"computedUserset\":null,\"tupleToUserset\":null,\"union\":null,\"intersection\":null,\"difference\":null}},\"metadata\":{\"relations\":{\"conditional_reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"name_starts_with_a\"}],\"module\":\"\",\"source_info\":null},\"owner\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}],\"module\":\"\",\"source_info\":null},\"reader\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}],\"module\":\"\",\"source_info\":null},\"writer\":{\"directly_related_user_types\":[{\"type\":\"user\",\"relation\":null,\"wildcard\":null,\"condition\":\"\"}],\"module\":\"\",\"source_info\":null}},\"module\":\"\",\"source_info\":null}}]",
typeDefsJson);
} catch (JsonProcessingException ex) {
assertNull(ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import java.util.List;

class Example1 {
public void run() throws Exception {
public void run(String apiUrl) throws Exception {
var credentials = new Credentials();
if (System.getenv("FGA_CLIENT_ID") != null) {
credentials = new Credentials(new ClientCredentials()
Expand All @@ -26,7 +26,7 @@ public void run() throws Exception {
}

var configuration = new ClientConfiguration()
.apiUrl(System.getenv("FGA_API_URL")) // required, e.g. https://api.fga.example
.apiUrl(apiUrl) // required, e.g. https://api.fga.example
.storeId(System.getenv("FGA_STORE_ID")) // not needed when calling `CreateStore` or `ListStores`
.authorizationModelId(
System.getenv("FGA_AUTHORIZATION_MODEL_ID")) // Optional, can be overridden per request
Expand Down Expand Up @@ -179,7 +179,7 @@ public void run() throws Exception {
public static void main(String[] args) {
System.out.println("=== Example 1 (Java) ===");
try {
new Example1().run();
new Example1().run(System.getenv("FGA_API_URL"));
} catch (Exception e) {
System.err.printf("ERROR: %s%n", e);
}
Expand Down
3 changes: 2 additions & 1 deletion config/common/config.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,6 @@
"tokenExpiryThresholdBufferInSec": 300,
"tokenExpiryJitterInSec": 300,
"clientMethodHeader": "X-OpenFGA-Client-Method",
"clientBulkRequestIdHeader": "X-OpenFGA-Client-Bulk-Request-Id"
"clientBulkRequestIdHeader": "X-OpenFGA-Client-Bulk-Request-Id",
"openFGADockerTag": "v1.5.1"
}

0 comments on commit f183ded

Please sign in to comment.