Skip to content

Commit d4880a6

Browse files
authored
feat: Compatibility tests integration (#2542)
* feat: initial commit * feat: move IatpParticipant to fixtures * feat: combine data and control plane * feat: use IatpParticipant as base class * feat: fix style, KICS and workflow * feat: minor fix * feat: move to edc-tests * feat: clean up
1 parent c5325b7 commit d4880a6

File tree

36 files changed

+1352
-46
lines changed

36 files changed

+1352
-46
lines changed

.github/workflows/verify.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,20 @@ jobs:
191191
env:
192192
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_API_TOKEN }}
193193

194+
compatibility-tests:
195+
runs-on: ubuntu-latest
196+
steps:
197+
- uses: actions/checkout@v6
198+
- uses: ./.github/actions/setup-java
199+
200+
- name: Build docker images
201+
run: ./gradlew :edc-tests:runtime:runtime-compatibility:stable:connector-stable:dockerize_stable
202+
203+
- name: Run Compatibility tests
204+
run: ./gradlew test -DincludeTags="CompatibilityTest" -PverboseTest=true --no-build-cache
205+
env:
206+
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_API_TOKEN }}
207+
194208
generate-allure-report:
195209
runs-on: ubuntu-latest
196210
needs: end-to-end-tests

build.gradle.kts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/********************************************************************************
22
* Copyright (c) 2023 Contributors to the Eclipse Foundation
3+
* Copyright (c) 2026 Cofinity-X GmbH
34
*
45
* See the NOTICE file(s) distributed with this work for additional
56
* information regarding copyright ownership.
@@ -245,7 +246,8 @@ fun childrenDependencies(dependency: ResolvedDependency): List<ResolvedDependenc
245246

246247
fun downloadYamlArtifact(dep: ResolvedDependency, classifier: String, destinationDirectory: java.nio.file.Path) {
247248
try {
248-
val managementApi = dependencies.create(dep.moduleGroup, dep.moduleName, dep.moduleVersion, classifier = classifier, ext = "yaml")
249+
val managementApiNotation = "${dep.moduleGroup}:${dep.moduleName}:${dep.moduleVersion}:${classifier}@yaml"
250+
val managementApi = dependencies.create(managementApiNotation)
249251
configurations
250252
.detachedConfiguration(managementApi)
251253
.resolve()
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
3+
* Copyright (c) 2026 Cofinity-X GmbH
4+
*
5+
* See the NOTICE file(s) distributed with this work for additional
6+
* information regarding copyright ownership.
7+
*
8+
* This program and the accompanying materials are made available under the
9+
* terms of the Apache License, Version 2.0 which is available at
10+
* https://www.apache.org/licenses/LICENSE-2.0.
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15+
* License for the specific language governing permissions and limitations
16+
* under the License.
17+
*
18+
* SPDX-License-Identifier: Apache-2.0
19+
******************************************************************************/
20+
21+
plugins {
22+
`java-library`
23+
}
24+
25+
dependencies {
26+
testImplementation(libs.edc.junit)
27+
testImplementation(libs.edc.lib.cryptocommon)
28+
testImplementation(libs.edc.lib.jws2020)
29+
testImplementation(libs.edc.transaction.local)
30+
testImplementation(libs.edc.spi.sts)
31+
testImplementation(libs.edc.iam.mock)
32+
testImplementation(libs.edc.ih.spi.did)
33+
testImplementation(libs.edc.ih.spi.credentials)
34+
testImplementation(libs.edc.ih.spi.participant.context)
35+
testImplementation(project(":spi:bdrs-client-spi"))
36+
testImplementation(libs.jakartaJson)
37+
testImplementation(libs.jacksonJsonP)
38+
testImplementation(libs.restAssured)
39+
testImplementation(libs.awaitility)
40+
testImplementation(libs.wiremock)
41+
testImplementation(libs.testcontainers.junit)
42+
testImplementation(libs.testcontainers.postgres)
43+
testImplementation(testFixtures(libs.edc.api.management.test.fixtures))
44+
testImplementation(testFixtures(libs.edc.sql.test.fixtures))
45+
testImplementation(testFixtures(project(":edc-tests:e2e-fixtures")))
46+
testImplementation("com.networknt:json-schema-validator:2.0.0")
47+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 Cofinity-X GmbH
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information regarding copyright ownership.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Apache License, Version 2.0 which is available at
9+
* https://www.apache.org/licenses/LICENSE-2.0.
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
* License for the specific language governing permissions and limitations
15+
* under the License.
16+
*
17+
* SPDX-License-Identifier: Apache-2.0
18+
******************************************************************************/
19+
20+
package org.eclipse.tractusx.edc.compatibility.tests;
21+
22+
import org.eclipse.edc.junit.annotations.IntegrationTest;
23+
import org.junit.jupiter.api.Tag;
24+
25+
import java.lang.annotation.ElementType;
26+
import java.lang.annotation.Retention;
27+
import java.lang.annotation.RetentionPolicy;
28+
import java.lang.annotation.Target;
29+
30+
@Target({ElementType.TYPE})
31+
@Retention(RetentionPolicy.RUNTIME)
32+
@IntegrationTest
33+
@Tag("CompatibilityTest")
34+
public @interface CompatibilityTest {
35+
}
36+
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
3+
* Copyright (c) 2026 Cofinity-X GmbH
4+
*
5+
* See the NOTICE file(s) distributed with this work for additional
6+
* information regarding copyright ownership.
7+
*
8+
* This program and the accompanying materials are made available under the
9+
* terms of the Apache License, Version 2.0 which is available at
10+
* https://www.apache.org/licenses/LICENSE-2.0.
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15+
* License for the specific language governing permissions and limitations
16+
* under the License.
17+
*
18+
* SPDX-License-Identifier: Apache-2.0
19+
******************************************************************************/
20+
21+
package org.eclipse.tractusx.edc.compatibility.tests.fixtures;
22+
23+
import org.eclipse.edc.iam.decentralizedclaims.sts.spi.service.StsAccountService;
24+
import org.eclipse.edc.iam.did.spi.document.Service;
25+
import org.eclipse.edc.identityhub.spi.participantcontext.ParticipantContextService;
26+
import org.eclipse.edc.identityhub.spi.participantcontext.model.KeyDescriptor;
27+
import org.eclipse.edc.identityhub.spi.participantcontext.model.ParticipantManifest;
28+
import org.eclipse.edc.identityhub.spi.verifiablecredentials.store.CredentialStore;
29+
import org.eclipse.edc.junit.extensions.RuntimeExtension;
30+
import org.eclipse.edc.spi.security.Vault;
31+
import org.eclipse.tractusx.edc.tests.participant.DataspaceIssuer;
32+
import org.eclipse.tractusx.edc.tests.participant.TractusxIatpParticipantBase;
33+
34+
import java.util.Base64;
35+
36+
public class DcpHelperFunctions {
37+
public static void configureParticipantContext(DataspaceIssuer issuer, IdentityHubParticipant identityHubParticipant, RuntimeExtension identityHubRuntime) {
38+
var participantContextService = identityHubRuntime.getService(ParticipantContextService.class);
39+
40+
var participantKey = issuer.getKeyPairAsJwk();
41+
var key = KeyDescriptor.Builder.newInstance()
42+
.keyId(issuer.getFullKeyId())
43+
.publicKeyJwk(participantKey.toPublicJWK().toJSONObject())
44+
.privateKeyAlias(issuer.getPrivateKeyAlias())
45+
.build();
46+
47+
var service = new Service();
48+
service.setId("#credential-service");
49+
service.setType("CredentialService");
50+
service.setServiceEndpoint(identityHubParticipant.getResolutionApi() + "/v1/participants/" + toBase64(issuer.didUrl()));
51+
52+
var participantManifest = ParticipantManifest.Builder.newInstance()
53+
.participantContextId(issuer.didUrl())
54+
.did(issuer.didUrl())
55+
.key(key)
56+
.serviceEndpoint(service)
57+
.active(true)
58+
.build();
59+
60+
participantContextService.createParticipantContext(participantManifest);
61+
62+
var vault = identityHubRuntime.getService(Vault.class);
63+
vault.storeSecret(issuer.getPrivateKeyAlias(), issuer.getPrivateKeyAsString());
64+
}
65+
66+
public static void configureParticipant(TractusxIatpParticipantBase participant, DataspaceIssuer issuer, IdentityHubParticipant identityHubParticipant, RuntimeExtension identityHubRuntime) {
67+
configureParticipantContext(participant, identityHubParticipant, identityHubRuntime);
68+
69+
var accountService = identityHubRuntime.getService(StsAccountService.class);
70+
var vault = identityHubRuntime.getService(Vault.class);
71+
var credentialStore = identityHubRuntime.getService(CredentialStore.class);
72+
73+
var credentials = issuer.issueCredentials(participant.getDid(), participant.getId());
74+
75+
credentials.forEach(credentialStore::create);
76+
77+
accountService.findById(participant.getDid())
78+
.onSuccess(account -> vault.storeSecret(account.getSecretAlias(), "clientSecret"));
79+
80+
}
81+
82+
public static void configureParticipantContext(TractusxIatpParticipantBase participant, IdentityHubParticipant identityHubParticipant, RuntimeExtension identityHubRuntime) {
83+
var participantContextService = identityHubRuntime.getService(ParticipantContextService.class);
84+
85+
var participantKey = participant.getKeyPairAsJwk();
86+
var key = KeyDescriptor.Builder.newInstance()
87+
.keyId(participant.getFullKeyId())
88+
.publicKeyJwk(participantKey.toPublicJWK().toJSONObject())
89+
.privateKeyAlias(participant.getPrivateKeyAlias())
90+
.build();
91+
92+
var service = new Service();
93+
service.setId("#credential-service");
94+
service.setType("CredentialService");
95+
service.setServiceEndpoint(identityHubParticipant.getResolutionApi() + "/v1/participants/" + toBase64(participant.getDid()));
96+
97+
var participantManifest = ParticipantManifest.Builder.newInstance()
98+
.participantContextId(participant.getDid())
99+
.did(participant.getDid())
100+
.key(key)
101+
.serviceEndpoint(service)
102+
.active(true)
103+
.build();
104+
105+
participantContextService.createParticipantContext(participantManifest);
106+
107+
var vault = identityHubRuntime.getService(Vault.class);
108+
vault.storeSecret(participant.getPrivateKeyAlias(), participant.getPrivateKeyAsString());
109+
}
110+
111+
static String toBase64(String s) {
112+
return Base64.getUrlEncoder().encodeToString(s.getBytes());
113+
}
114+
115+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
3+
* Copyright (c) 2026 Cofinity-X GmbH
4+
*
5+
* See the NOTICE file(s) distributed with this work for additional
6+
* information regarding copyright ownership.
7+
*
8+
* This program and the accompanying materials are made available under the
9+
* terms of the Apache License, Version 2.0 which is available at
10+
* https://www.apache.org/licenses/LICENSE-2.0.
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15+
* License for the specific language governing permissions and limitations
16+
* under the License.
17+
*
18+
* SPDX-License-Identifier: Apache-2.0
19+
******************************************************************************/
20+
21+
package org.eclipse.tractusx.edc.compatibility.tests.fixtures;
22+
23+
import org.testcontainers.containers.GenericContainer;
24+
import org.testcontainers.containers.wait.strategy.Wait;
25+
26+
import java.util.Map;
27+
28+
public enum EdcDockerRuntimes {
29+
30+
STABLE_CONNECTOR("connector-stable:latest");
31+
32+
private final String image;
33+
34+
EdcDockerRuntimes(String image) {
35+
this.image = image;
36+
}
37+
38+
public GenericContainer<?> create(String name, Map<String, String> env) {
39+
return new GenericContainer<>(image)
40+
.withCreateContainerCmdModifier(cmd -> cmd.withName(name))
41+
.withNetworkMode("host")
42+
.withLogConsumer(it -> System.out.printf("[%s] %s%n", name, it.getUtf8StringWithoutLineEnding()))
43+
.waitingFor(Wait.forLogMessage(".*Runtime .* ready.*", 1))
44+
.withEnv(env);
45+
}
46+
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
3+
* Copyright (c) 2026 Cofinity-X GmbH
4+
*
5+
* See the NOTICE file(s) distributed with this work for additional
6+
* information regarding copyright ownership.
7+
*
8+
* This program and the accompanying materials are made available under the
9+
* terms of the Apache License, Version 2.0 which is available at
10+
* https://www.apache.org/licenses/LICENSE-2.0.
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15+
* License for the specific language governing permissions and limitations
16+
* under the License.
17+
*
18+
* SPDX-License-Identifier: Apache-2.0
19+
******************************************************************************/
20+
21+
package org.eclipse.tractusx.edc.compatibility.tests.fixtures;
22+
23+
import org.eclipse.edc.junit.utils.LazySupplier;
24+
import org.eclipse.edc.spi.system.configuration.Config;
25+
import org.eclipse.edc.spi.system.configuration.ConfigFactory;
26+
27+
import java.net.URI;
28+
import java.net.URLEncoder;
29+
import java.nio.charset.StandardCharsets;
30+
import java.util.HashMap;
31+
import java.util.Map;
32+
import java.util.Objects;
33+
34+
import static org.eclipse.edc.util.io.Ports.getFreePort;
35+
36+
public class IdentityHubParticipant {
37+
38+
protected final LazySupplier<URI> sts = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort() + "/api/sts"));
39+
protected final LazySupplier<URI> accountsApi = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort() + "/api/accounts"));
40+
protected final LazySupplier<URI> credentialsApi = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort() + "/api/credentials"));
41+
protected final LazySupplier<URI> identityApi = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort() + "/api/identity"));
42+
protected final LazySupplier<URI> didApi = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort() + "/"));
43+
protected String id;
44+
protected String name;
45+
46+
public Config getConfig() {
47+
Map<String, String> settings = new HashMap<>();
48+
49+
settings.put("web.http.port", String.valueOf(getFreePort()));
50+
settings.put("web.http.path", "/api");
51+
settings.put("web.http.credentials.port", String.valueOf(credentialsApi.get().getPort()));
52+
settings.put("web.http.credentials.path", credentialsApi.get().getPath());
53+
settings.put("web.http.identity.port", String.valueOf(identityApi.get().getPort()));
54+
settings.put("web.http.identity.path", identityApi.get().getPath());
55+
settings.put("web.http.sts.port", String.valueOf(sts.get().getPort()));
56+
settings.put("web.http.sts.path", sts.get().getPath());
57+
settings.put("web.http.accounts.port", String.valueOf(accountsApi.get().getPort()));
58+
settings.put("web.http.accounts.path", accountsApi.get().getPath());
59+
settings.put("web.http.did.port", String.valueOf(didApi.get().getPort()));
60+
settings.put("web.http.did.path", didApi.get().getPath());
61+
settings.put("edc.iam.did.web.use.https", "false");
62+
settings.put("edc.api.accounts.key", "password");
63+
64+
return ConfigFactory.fromMap(settings);
65+
}
66+
67+
public LazySupplier<URI> getSts() {
68+
return sts;
69+
}
70+
71+
public URI getResolutionApi() {
72+
return credentialsApi.get();
73+
}
74+
75+
public String didFor(String participantId) {
76+
var didUri = didApi.get();
77+
return "did:web:" + URLEncoder.encode(didUri.getHost() + ":" + didUri.getPort(), StandardCharsets.UTF_8) + ":" + participantId;
78+
}
79+
80+
public static class Builder {
81+
protected final IdentityHubParticipant participant;
82+
83+
protected Builder() {
84+
this.participant = new IdentityHubParticipant();
85+
}
86+
87+
public static Builder newInstance() {
88+
return new Builder();
89+
}
90+
91+
public Builder id(String id) {
92+
this.participant.id = id;
93+
return this;
94+
}
95+
96+
public Builder name(String name) {
97+
this.participant.name = name;
98+
return this;
99+
}
100+
101+
public IdentityHubParticipant build() {
102+
Objects.requireNonNull(this.participant.id, "id");
103+
Objects.requireNonNull(this.participant.name, "name");
104+
105+
return this.participant;
106+
}
107+
}
108+
}

0 commit comments

Comments
 (0)