Skip to content

Commit 1ecdbb4

Browse files
authored
Support skipping integration tests for unavailable CF features via environment variables (#1346)
1 parent 3e79d08 commit 1ecdbb4

65 files changed

Lines changed: 577 additions & 76 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,10 @@ Name | Description
353353
`TEST_PROXY_PORT` | _(Optional)_ The port of a proxy to route all requests through. Defaults to `8080`.
354354
`TEST_PROXY_USERNAME` | _(Optional)_ The username for a proxy to route all requests through
355355
`TEST_SKIPSSLVALIDATION` | _(Optional)_ Whether to skip SSL validation when connecting to the Cloud Foundry instance. Defaults to `false`.
356+
`SKIP_BROWSER_AUTH_TESTS` | _(Optional)_ Set to `true` to skip integration tests that require browser-based authentication (e.g., SSO tests). Useful when the Cloud Foundry instance's UAA does not have browser-based authentication configured. Defaults to `false`.
357+
`SKIP_METRIC_REGISTRAR_TESTS` | _(Optional)_ Set to `true` to skip integration tests that require the Metric Registrar service (e.g., MetricRegistrarTest). Useful when the Cloud Foundry instance does not have the Metric Registrar service available. Defaults to `false`.
358+
`SKIP_TCP_ROUTING_TESTS` | _(Optional)_ Set to `true` to skip TCP routing integration tests (TcpRoutesTest, RouterGroupsTest). Useful when the Cloud Foundry instance does not have TCP routing configured (i.e., no `routing_endpoint` in the info payload). Defaults to `false`.
359+
`SKIP_V2_TESTS` | _(Optional)_ Set to `true` to skip all V2 API integration tests. Useful when the Cloud Foundry V2 API is rate-limited or unavailable. When enabled, tests annotated with `@RequiresV2Api` will be skipped, including V3 tests that depend on V2 API calls (e.g., service broker creation). Defaults to `false`.
356360

357361
If you do not have access to a CloudFoundry instance with admin access, you can run one locally using [bosh-deployment](https://github.com/cloudfoundry/bosh-deployment) & [cf-deployment](https://github.com/cloudfoundry/cf-deployment/) and Virtualbox.
358362

cloudfoundry-client/src/main/java/org/cloudfoundry/client/v3/stacks/Stack.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,18 @@ public abstract class Stack extends Resource {
6666
@JsonProperty("default")
6767
@Nullable
6868
abstract Boolean geDefault();
69+
70+
/**
71+
* The state of the stack (e.g. ready)
72+
*/
73+
@JsonProperty("state")
74+
@Nullable
75+
abstract String getState();
76+
77+
/**
78+
* The reason for the stack's current state
79+
*/
80+
@JsonProperty("state_reason")
81+
@Nullable
82+
abstract String getStateReason();
6983
}

cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/applications/DefaultApplicationsTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1378,7 +1378,11 @@ void logsLogCache() {
13781378
requestLogsRecentLogCache(this.logCacheClient, "test-metadata-id");
13791379

13801380
this.applications
1381-
.logs(ApplicationLogsRequest.builder().name("test-application-name").recent(true).build())
1381+
.logs(
1382+
ApplicationLogsRequest.builder()
1383+
.name("test-application-name")
1384+
.recent(true)
1385+
.build())
13821386
.as(StepVerifier::create)
13831387
.expectNextMatches(
13841388
log ->

integration-test/src/test/java/org/cloudfoundry/CloudFoundryCleaner.java

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import java.util.function.Supplier;
2929
import javax.net.ssl.SSLException;
3030
import org.cloudfoundry.client.CloudFoundryClient;
31-
import org.cloudfoundry.client.v2.applications.ListApplicationServiceBindingsRequest;
3231
import org.cloudfoundry.client.v2.applications.RemoveApplicationServiceBindingRequest;
3332
import org.cloudfoundry.client.v2.buildpacks.DeleteBuildpackRequest;
3433
import org.cloudfoundry.client.v2.buildpacks.ListBuildpacksRequest;
@@ -79,6 +78,8 @@
7978
import org.cloudfoundry.client.v3.applications.Application;
8079
import org.cloudfoundry.client.v3.applications.DeleteApplicationRequest;
8180
import org.cloudfoundry.client.v3.applications.ListApplicationsRequest;
81+
import org.cloudfoundry.client.v3.servicebindings.DeleteServiceBindingRequest;
82+
import org.cloudfoundry.client.v3.servicebindings.ListServiceBindingsRequest;
8283
import org.cloudfoundry.client.v3.serviceinstances.ListSharedSpacesRelationshipRequest;
8384
import org.cloudfoundry.client.v3.serviceinstances.ListSharedSpacesRelationshipResponse;
8485
import org.cloudfoundry.client.v3.serviceinstances.UnshareServiceInstanceRequest;
@@ -129,6 +130,8 @@ final class CloudFoundryCleaner implements InitializingBean, DisposableBean {
129130

130131
private static final Logger LOGGER = LoggerFactory.getLogger("cloudfoundry-client.test");
131132

133+
private static final boolean RUN_V2_CLEANUP = RequiresV2Api.V2ApiCondition.isEnabled();
134+
132135
private static final Map<String, Boolean> STANDARD_FEATURE_FLAGS =
133136
FluentMap.<String, Boolean>builder()
134137
.entry("app_bits_upload", true)
@@ -186,6 +189,28 @@ public void destroy() {
186189
}
187190

188191
void clean() {
192+
if (!RUN_V2_CLEANUP) {
193+
LOGGER.info("Skipping V2 API cleanup operations (SKIP_V2_TESTS=true)");
194+
// Only run V3 and UAA cleanup operations
195+
Flux.empty()
196+
.thenMany(
197+
Mono.when( // No prerequisites - V3/UAA only
198+
cleanClients(this.uaaClient, this.nameFactory),
199+
cleanGroups(this.uaaClient, this.nameFactory),
200+
cleanIdentityProviders(this.uaaClient, this.nameFactory),
201+
cleanIdentityZones(this.uaaClient, this.nameFactory)))
202+
.thenMany(
203+
Mono.when(
204+
cleanApplicationsV3(this.cloudFoundryClient, this.nameFactory),
205+
cleanUsers(this.uaaClient, this.nameFactory)))
206+
.retryWhen(Retry.max(5).filter(SSLException.class::isInstance))
207+
.doOnSubscribe(s -> LOGGER.debug(">> CLEANUP (V3 only) <<"))
208+
.doOnComplete(() -> LOGGER.debug("<< CLEANUP (V3 only) >>"))
209+
.then()
210+
.block(Duration.ofMinutes(30));
211+
return;
212+
}
213+
189214
Flux.empty()
190215
.thenMany(
191216
Mono.when( // Before Routes
@@ -216,10 +241,7 @@ void clean() {
216241
cleanUsers(this.cloudFoundryClient, this.nameFactory)))
217242
.thenMany(
218243
Mono.when(
219-
cleanApplicationsV3(
220-
this.cloudFoundryClient,
221-
this.nameFactory), // After Routes, cannot run with
222-
// other cleanApps
244+
cleanApplicationsV3(this.cloudFoundryClient, this.nameFactory),
223245
cleanUsers(this.uaaClient, this.nameFactory) // After CF Users
224246
))
225247
.thenMany(
@@ -1160,21 +1182,24 @@ private static boolean isCleanable(NameFactory nameFactory, UserResource resourc
11601182

11611183
private static Flux<Void> removeApplicationServiceBindings(
11621184
CloudFoundryClient cloudFoundryClient, Application application) {
1163-
return PaginationUtils.requestClientV2Resources(
1185+
return PaginationUtils.requestClientV3Resources(
11641186
page ->
11651187
cloudFoundryClient
1166-
.applicationsV2()
1167-
.listServiceBindings(
1168-
ListApplicationServiceBindingsRequest.builder()
1188+
.serviceBindingsV3()
1189+
.list(
1190+
ListServiceBindingsRequest.builder()
11691191
.page(page)
11701192
.applicationId(application.getId())
11711193
.build()))
11721194
.flatMap(
11731195
serviceBinding ->
1174-
requestRemoveServiceBinding(
1175-
cloudFoundryClient,
1176-
application.getId(),
1177-
ResourceUtils.getId(serviceBinding))
1196+
cloudFoundryClient
1197+
.serviceBindingsV3()
1198+
.delete(
1199+
DeleteServiceBindingRequest.builder()
1200+
.serviceBindingId(serviceBinding.getId())
1201+
.build())
1202+
.then()
11781203
.doOnError(
11791204
t ->
11801205
LOGGER.error(

0 commit comments

Comments
 (0)