Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions .github/workflows/publish-e2e-test-suites-docker-image.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name: Publish E2E Test Suites
run-name: ${{ format('Publish E2E Test Suites{0} {1} Release', ':', inputs.release_type) }}
name: Release UID2 E2E Image
run-name: ${{ inputs.release_type == 'Snapshot' && 'Publish Pre-release' || format('Release {0}', inputs.release_type)}} Docker Image by @${{ github.actor }}
on:
workflow_dispatch:
inputs:
release_type:
type: choice
description: 'The type of release'
description: The type of release
options:
- Snapshot
- Patch
Expand All @@ -15,14 +15,21 @@ on:
description: If set, the version number will not be incremented and the given number will be used.
type: string
default: ''
vulnerability_severity:
description: The severity to fail the workflow if such vulnerability is detected. DO NOT override it unless a Jira ticket is raised.
type: choice
options:
- CRITICAL,HIGH
- CRITICAL,HIGH,MEDIUM
- CRITICAL (DO NOT use if JIRA ticket not raised)

jobs:
Image:
uses: IABTechLab/uid2-shared-actions/.github/workflows/shared-publish-java-to-docker-versioned.yaml@v3
with:
release_type: ${{ inputs.release_type }}
version_number_input: ${{ inputs.version_number_input }}
java_version: '21'
force_release: 'yes'
vulnerability_severity: ${{ inputs.vulnerability_severity }}
java_version: 21
skip_tests: true
secrets: inherit
71 changes: 32 additions & 39 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,35 @@ COPY ./src ./src
######################
# Configure env vars #
######################
ENV UID2_E2E_ENV "github-test-pipeline"

ENV UID2_E2E_SITE_ID ""
ENV UID2_E2E_API_KEY ""
ENV UID2_E2E_API_SECRET ""
ENV UID2_E2E_API_KEY_OLD ""
ENV UID2_E2E_API_SECRET_OLD ""
ENV UID2_E2E_API_KEY_SHARING_RECIPIENT ""
ENV UID2_E2E_API_SECRET_SHARING_RECIPIENT ""
ENV UID2_E2E_API_KEY_NON_SHARING_RECIPIENT ""
ENV UID2_E2E_API_SECRET_NON_SHARING_RECIPIENT ""
ENV UID2_E2E_SUBSCRIPTION_ID ""
ENV UID2_E2E_SERVER_PUBLIC_KEY ""
ENV UID2_E2E_ORIGIN ""
ENV UID2_E2E_INVALID_ORIGIN ""

ENV UID2_E2E_IDENTITY_SCOPE ""
ENV UID2_E2E_PHONE_SUPPORT ""

ENV UID2_E2E_PIPELINE_OPERATOR_URL ""
ENV UID2_E2E_PIPELINE_OPERATOR_TYPE ""
ENV UID2_E2E_PIPELINE_OPERATOR_CLOUD_PROVIDER ""

ENV UID2_E2E_CORE_API_TOKEN ""
ENV UID2_E2E_OPTOUT_TO_CALL_CORE_API_TOKEN ""
ENV UID2_E2E_CORE_URL ""
ENV UID2_E2E_OPTOUT_URL ""

CMD \
if [ "$UID2_E2E_PIPELINE_OPERATOR_TYPE" != "PUBLIC" ] && [ "$UID2_E2E_PIPELINE_OPERATOR_TYPE" != "PRIVATE" ] ; \
then \
echo "ERROR: Incorrect operator type: $UID2_E2E_PIPELINE_OPERATOR_TYPE. Exiting." ; \
exit 1 ; \
elif [ "$UID2_E2E_PIPELINE_OPERATOR_TYPE" = "PUBLIC" ] ; \
then \
mvn test -Dtest="E2EPublicOperatorTestSuite" ; \
else \
mvn test -Dtest="E2EPrivateOperatorTestSuite" ; \
fi
ENV E2E_SUITES ""
ENV E2E_ARGS_JSON ""

ENV E2E_ENV ""
ENV E2E_IDENTITY_SCOPE ""
ENV E2E_PHONE_SUPPORT ""

ENV UID2_CORE_E2E_OPERATOR_API_KEY ""
ENV UID2_CORE_E2E_OPTOUT_API_KEY ""
ENV UID2_CORE_E2E_CORE_URL ""
ENV UID2_CORE_E2E_OPTOUT_URL ""

ENV UID2_OPERATOR_E2E_CLIENT_SITE_ID ""
ENV UID2_OPERATOR_E2E_CLIENT_API_KEY ""
ENV UID2_OPERATOR_E2E_CLIENT_API_SECRET ""
ENV UID2_OPERATOR_E2E_CLIENT_API_KEY_BEFORE_OPTOUT_CUTOFF ""
ENV UID2_OPERATOR_E2E_CLIENT_API_SECRET_BEFORE_OPTOUT_CUTOFF ""
ENV UID2_OPERATOR_E2E_CLIENT_API_KEY_SHARING_RECIPIENT ""
ENV UID2_OPERATOR_E2E_CLIENT_API_SECRET_SHARING_RECIPIENT ""
ENV UID2_OPERATOR_E2E_CLIENT_API_KEY_NON_SHARING_RECIPIENT ""
ENV UID2_OPERATOR_E2E_CLIENT_API_SECRET_NON_SHARING_RECIPIENT ""
ENV UID2_OPERATOR_E2E_CSTG_SUBSCRIPTION_ID ""
ENV UID2_OPERATOR_E2E_CSTG_SERVER_PUBLIC_KEY ""
ENV UID2_OPERATOR_E2E_CSTG_ORIGIN ""
ENV UID2_OPERATOR_E2E_CSTG_INVALID_ORIGIN ""

ENV UID2_PIPELINE_E2E_CORE_URL ""
ENV UID2_PIPELINE_E2E_OPERATOR_URL ""
ENV UID2_PIPELINE_E2E_OPERATOR_TYPE ""
ENV UID2_PIPELINE_E2E_OPERATOR_CLOUD_PROVIDER ""

CMD mvn test -Dtest="${E2E_SUITES}"
70 changes: 61 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,68 @@ Any changes to [uid2-operator](https://github.com/IABTechLab/uid2-operator) need

There are different test suites that can be run depending on the environment and operator type:

| Test Suite | Description |
|---------------------------------------|--------------------------------------------------------------|
| `E2ELocalFullTestSuite` | Used when running both public and private operators locally. |
| `E2EPipelinePrivateOperatorTestSuite` | Used when testing private operators in a pipeline. |
| `E2EPipelinePublicOperatorTestSuite` | Used when testing public operators in a pipeline. |
| `E2EPrivateOperatorTestSuite` | Used when testing real private operators. |
| `E2EPublicOperatorTestSuite` | Used when testing real public operators. |
| Test Suite | Description |
|-------------------------------|-------------------------------------|
| `E2ELocalFullTestSuite` | Used to test all apps locally |
| `E2ECoreTestSuite` | Used when testing Core |
| `E2EPublicOperatorTestSuite` | Used when testing public Operators |
| `E2EPrivateOperatorTestSuite` | Used when testing private Operators |

## Environment Variables

* `E2E_SUITES` - **Docker image only** - The test suites to run, comma separated
* e.g. `E2EPrivateOperatorTestSuite,E2ECoreTestSuite`
* `E2E_ARGS_JSON` - The below environment variables can be put into this environment variable as a JSON
* Any environment variables declared explicitly will override args in `E2E_ARGS_JSON`

### General

| Name | Value |
|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
| `E2E_ENV` | The E2E environment - this determines which apps get instantiated<br/>Certain tests run for `local` environments only<br/>Check `AppsMap` for details |
| `E2E_IDENTITY_SCOPE` | The identity scope - one of [UID2, EUID] |
| `E2E_PHONE_SUPPORT` | True if APIs support phone numbers, false otherwise |

### Core

| Name | Value |
|----------------------------------|------------------------------------------------------|
| `UID2_CORE_E2E_OPERATOR_API_KEY` | The API key for an Operator to communicate with Core |
| `UID2_CORE_E2E_OPTOUT_API_KEY` | The API key for Optout to communicate with Core |
| `UID2_CORE_E2E_CORE_URL` | The Core URL to include in attestation requests |
| `UID2_CORE_E2E_OPTOUT_URL` | The Optout URL to include in attestation requests |

### Operator

| Name | Value |
|-------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------|
| `UID2_OPERATOR_E2E_CLIENT_SITE_ID` | The site ID of the client communicating with Operator |
| `UID2_OPERATOR_E2E_CLIENT_API_KEY` | The API key for a client to communicate with Operator |
| `UID2_OPERATOR_E2E_CLIENT_API_SECRET` | The API secret for a client to communicate with Operator |
| `UID2_OPERATOR_E2E_CLIENT_API_KEY_BEFORE_OPTOUT_CUTOFF` | **Optout cutoff tests** - The API key before the optout policy cutoff for a client to communicate with Operator |
| `UID2_OPERATOR_E2E_CLIENT_API_SECRET_BEFORE_OPTOUT_CUTOFF` | **Optout cutoff tests** - The API secret before the optout policy cutoff for a client to communicate with Operator |
| `UID2_OPERATOR_E2E_CLIENT_API_KEY_SHARING_RECIPIENT` | **Sharing tests** - The API key with SHARER role for a client to communicate with Operator |
| `UID2_OPERATOR_E2E_CLIENT_API_SECRET_SHARING_RECIPIENT` | **Sharing tests** - The API with SHARER role secret for a client to communicate with Operator |
| `UID2_OPERATOR_E2E_CLIENT_API_KEY_NON_SHARING_RECIPIENT` | **Sharing tests** - The API key without SHARER role for a client to communicate with Operator |
| `UID2_OPERATOR_E2E_CLIENT_API_SECRET_NON_SHARING_RECIPIENT` | **Sharing tests** - The API without SHARER role secret for a client to communicate with Operator |
| `UID2_OPERATOR_E2E_CSTG_SUBSCRIPTION_ID` | **CSTG tests** - The subscription ID |
| `UID2_OPERATOR_E2E_CSTG_SERVER_PUBLIC_KEY` | **CSTG tests** - The server public key |
| `UID2_OPERATOR_E2E_CSTG_ORIGIN` | **CSTG tests** - A valid origin |
| `UID2_OPERATOR_E2E_CSTG_INVALID_ORIGIN` | **CSTG tests** - An invalid origin |

### Pipeline

| Name | Value |
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------|
| `UID2_PIPELINE_E2E_CORE_URL` | The Core URL |
| `UID2_PIPELINE_E2E_OPERATOR_URL` | The Operator URL |
| `UID2_PIPELINE_E2E_OPERATOR_TYPE` | The type of Operator - one of [PUBLIC, PRIVATE] |
| `UID2_PIPELINE_E2E_OPERATOR_CLOUD_PROVIDER` | Empty for public Operators, the cloud provider for private Operators - one of [aws-nitro, gcp-oidc, azure-cc] |

## Running the Dockerfile

`docker build -f Dockerfile -t uid2-e2e . && docker run --env <ENV>=<VAR> ... uid2-e2e`
* Set each environment variable specified in the Dockerfile as `--env <ENV>=<VAR>`
```shell
docker build -f Dockerfile -t uid2-e2e .
docker run --env <ENV>=<VAR> ... uid2-e2e
```
* If running the E2E tests against localhost, include the option `--network=host`
6 changes: 2 additions & 4 deletions src/test/java/app/AppsMap.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package app;

import common.EnvUtil;
import app.component.App;

import java.lang.reflect.InvocationTargetException;
Expand All @@ -10,8 +9,6 @@

public final class AppsMap {
private static final Map<String, String> APP_MAP;
private static final String ENV = EnvUtil.getEnv("UID2_E2E_ENV");

private static final Apps APPS;

static {
Expand All @@ -24,10 +21,11 @@ public final class AppsMap {
"uid2-prod", "app.Uid2ProdApps",
"euid-integ", "app.EuidIntegApps",
"euid-prod", "app.EuidProdApps",
"github-test-pipeline-local", "app.GitHubTestPipelineApps",
"github-test-pipeline", "app.GitHubTestPipelineApps"
);

APPS = (Apps) Class.forName(APP_MAP.get(ENV)).getDeclaredConstructor().newInstance();
APPS = (Apps) Class.forName(APP_MAP.get(App.ENV)).getDeclaredConstructor().newInstance();
} catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
Expand Down
19 changes: 11 additions & 8 deletions src/test/java/app/GitHubTestPipelineApps.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
package app;

import common.Const;
import common.EnabledCondition;
import common.EnvUtil;
import app.component.Core;
import app.component.Operator;

import java.util.Set;

public class GitHubTestPipelineApps extends Apps {
private static final String OPERATOR_URL = EnvUtil.getEnv("UID2_E2E_PIPELINE_OPERATOR_URL");
private static final Operator.Type OPERATOR_TYPE = Operator.Type.valueOf(EnvUtil.getEnv("UID2_E2E_PIPELINE_OPERATOR_TYPE"));
private static final Operator.CloudProvider OPERATOR_CLOUD_PROVIDER = Operator.CloudProvider.valueOf(EnvUtil.getEnv("UID2_E2E_PIPELINE_OPERATOR_CLOUD_PROVIDER"));
private static final String CORE_URL = EnvUtil.getEnv(Const.Config.Pipeline.CORE_URL, EnabledCondition.isLocal());

private static final String CORE_URL = EnvUtil.getEnv("UID2_E2E_CORE_URL");
private static final String OPERATOR_URL = EnvUtil.getEnv(Const.Config.Pipeline.OPERATOR_URL);
private static final Operator.Type OPERATOR_TYPE = Operator.Type.valueOf(EnvUtil.getEnv(Const.Config.Pipeline.OPERATOR_TYPE));
private static final Operator.CloudProvider OPERATOR_CLOUD_PROVIDER = Operator.CloudProvider.valueOf(EnvUtil.getEnv(Const.Config.Pipeline.OPERATOR_CLOUD_PROVIDER));
private static final String OPERATOR_NAME = OPERATOR_TYPE == Operator.Type.PUBLIC
? "GitHub Test Pipeline - Public Operator"
: "GitHub Test Pipeline - Private %s Operator".formatted(OPERATOR_CLOUD_PROVIDER.toString());

public GitHubTestPipelineApps() {
super(Set.of(
new Operator(OPERATOR_URL, OPERATOR_NAME, OPERATOR_TYPE),
new Core(CORE_URL, "GitHub Test Pipeline - Core")
));
super(EnabledCondition.isLocal() ?
Set.of(
new Operator(OPERATOR_URL, OPERATOR_NAME, OPERATOR_TYPE),
new Core(CORE_URL, "GitHub Test Pipeline - Core")) :
Set.of(new Operator(OPERATOR_URL, OPERATOR_NAME, OPERATOR_TYPE)));
}
}
2 changes: 1 addition & 1 deletion src/test/java/app/LocalApps.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import java.util.Set;

public final class LocalApps extends Apps {
// TODO: Add optout
public LocalApps() {
super(Set.of(
// TODO: Add optout, monitorstack
new Localstack("http://localhost", 5001, "Local - Localstack"),
new Admin("http://localhost", 8089, "Local - Admin"),
new Core("http://localhost", 8088, "Local - Core"),
Expand Down
21 changes: 9 additions & 12 deletions src/test/java/app/component/App.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
package app.component;

import com.uid2.client.IdentityScope;
import common.Const;
import common.EnvUtil;
import common.HttpClient;
import lombok.Getter;

@Getter
public abstract class App {
public static final String ENV = EnvUtil.getEnv(Const.Config.ENV);
public static final IdentityScope IDENTITY_SCOPE = IdentityScope.valueOf(EnvUtil.getEnv(Const.Config.IDENTITY_SCOPE));
public static final boolean PHONE_SUPPORT = Boolean.parseBoolean(EnvUtil.getEnv(Const.Config.PHONE_SUPPORT));

private final String host;
private final Integer port;
private final String name;
Expand All @@ -13,18 +22,6 @@ public App(String host, Integer port, String name) {
this.name = name;
}

public String getHost() {
return host;
}

public Integer getPort() {
return port;
}

public String getName() {
return name;
}

public String getBaseUrl() {
return getPort() == null ? getHost() : "%s:%d".formatted(getHost(), getPort());
}
Expand Down
15 changes: 8 additions & 7 deletions src/test/java/app/component/Core.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package app.component;

import common.Const;
import common.EnvUtil;
import common.HttpClient;
import common.Mapper;
Expand All @@ -9,10 +10,10 @@
import java.util.Map;

public class Core extends App {
private static final String CORE_API_TOKEN = EnvUtil.getEnv("UID2_E2E_CORE_API_TOKEN");
private static final String OPTOUT_TO_CALL_CORE_API_TOKEN = EnvUtil.getEnv("UID2_E2E_OPTOUT_TO_CALL_CORE_API_TOKEN");
public static final String CORE_URL = EnvUtil.getEnv("UID2_E2E_CORE_URL");
public static final String OPTOUT_URL = EnvUtil.getEnv("UID2_E2E_OPTOUT_URL");
private static final String OPERATOR_API_KEY = EnvUtil.getEnv(Const.Config.Core.OPERATOR_API_KEY);
private static final String OPTOUT_API_KEY = EnvUtil.getEnv(Const.Config.Core.OPTOUT_API_KEY);
public static final String CORE_URL = EnvUtil.getEnv(Const.Config.Core.CORE_URL);
public static final String OPTOUT_URL = EnvUtil.getEnv(Const.Config.Core.OPTOUT_URL);

public Core(String host, Integer port, String name) {
super(host, port, name);
Expand All @@ -23,7 +24,7 @@ public Core(String host, String name) {
}

public JsonNode attest(String attestationRequest) throws Exception {
String response = HttpClient.post(getBaseUrl() + "/attest", attestationRequest, CORE_API_TOKEN);
String response = HttpClient.post(getBaseUrl() + "/attest", attestationRequest, OPERATOR_API_KEY);
return Mapper.OBJECT_MAPPER.readTree(response);
}

Expand All @@ -35,12 +36,12 @@ public JsonNode getWithCoreApiToken(String path, boolean encrypted) throws Excep
Map<String, String> headers = new HashMap<>();
if (encrypted)
headers.put("Encrypted", "true");
String response = HttpClient.get(getBaseUrl() + path, CORE_API_TOKEN, headers);
String response = HttpClient.get(getBaseUrl() + path, OPERATOR_API_KEY, headers);
return Mapper.OBJECT_MAPPER.readTree(response);
}

public JsonNode getWithOptOutApiToken(String path) throws Exception {
String response = HttpClient.get(getBaseUrl() + path, OPTOUT_TO_CALL_CORE_API_TOKEN);
String response = HttpClient.get(getBaseUrl() + path, OPTOUT_API_KEY);
return Mapper.OBJECT_MAPPER.readTree(response);
}
}
Loading