Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,10 @@ Name | Description
`TEST_PROXY_PORT` | _(Optional)_ The port of a proxy to route all requests through. Defaults to `8080`.
`TEST_PROXY_USERNAME` | _(Optional)_ The username for a proxy to route all requests through
`TEST_SKIPSSLVALIDATION` | _(Optional)_ Whether to skip SSL validation when connecting to the Cloud Foundry instance. Defaults to `false`.
`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`.
`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`.
`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`.
`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`.

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.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,18 @@ public abstract class Stack extends Resource {
@JsonProperty("default")
@Nullable
abstract Boolean geDefault();

/**
* The state of the stack (e.g. ready)
*/
@JsonProperty("state")
@Nullable
abstract String getState();

/**
* The reason for the stack's current state
*/
@JsonProperty("state_reason")
@Nullable
abstract String getStateReason();
}
Original file line number Diff line number Diff line change
Expand Up @@ -1378,7 +1378,11 @@ void logsLogCache() {
requestLogsRecentLogCache(this.logCacheClient, "test-metadata-id");

this.applications
.logs(ApplicationLogsRequest.builder().name("test-application-name").recent(true).build())
.logs(
ApplicationLogsRequest.builder()
.name("test-application-name")
.recent(true)
.build())
.as(StepVerifier::create)
.expectNextMatches(
log ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import java.util.function.Supplier;
import javax.net.ssl.SSLException;
import org.cloudfoundry.client.CloudFoundryClient;
import org.cloudfoundry.client.v2.applications.ListApplicationServiceBindingsRequest;
import org.cloudfoundry.client.v2.applications.RemoveApplicationServiceBindingRequest;
import org.cloudfoundry.client.v2.buildpacks.DeleteBuildpackRequest;
import org.cloudfoundry.client.v2.buildpacks.ListBuildpacksRequest;
Expand Down Expand Up @@ -79,6 +78,8 @@
import org.cloudfoundry.client.v3.applications.Application;
import org.cloudfoundry.client.v3.applications.DeleteApplicationRequest;
import org.cloudfoundry.client.v3.applications.ListApplicationsRequest;
import org.cloudfoundry.client.v3.servicebindings.DeleteServiceBindingRequest;
import org.cloudfoundry.client.v3.servicebindings.ListServiceBindingsRequest;
import org.cloudfoundry.client.v3.serviceinstances.ListSharedSpacesRelationshipRequest;
import org.cloudfoundry.client.v3.serviceinstances.ListSharedSpacesRelationshipResponse;
import org.cloudfoundry.client.v3.serviceinstances.UnshareServiceInstanceRequest;
Expand Down Expand Up @@ -129,6 +130,8 @@ final class CloudFoundryCleaner implements InitializingBean, DisposableBean {

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

private static final boolean RUN_V2_CLEANUP = RequiresV2Api.V2ApiCondition.isEnabled();

private static final Map<String, Boolean> STANDARD_FEATURE_FLAGS =
FluentMap.<String, Boolean>builder()
.entry("app_bits_upload", true)
Expand Down Expand Up @@ -186,6 +189,28 @@ public void destroy() {
}

void clean() {
if (!RUN_V2_CLEANUP) {
LOGGER.info("Skipping V2 API cleanup operations (SKIP_V2_TESTS=true)");
// Only run V3 and UAA cleanup operations
Flux.empty()
.thenMany(
Mono.when( // No prerequisites - V3/UAA only
cleanClients(this.uaaClient, this.nameFactory),
cleanGroups(this.uaaClient, this.nameFactory),
cleanIdentityProviders(this.uaaClient, this.nameFactory),
cleanIdentityZones(this.uaaClient, this.nameFactory)))
.thenMany(
Mono.when(
cleanApplicationsV3(this.cloudFoundryClient, this.nameFactory),
cleanUsers(this.uaaClient, this.nameFactory)))
.retryWhen(Retry.max(5).filter(SSLException.class::isInstance))
.doOnSubscribe(s -> LOGGER.debug(">> CLEANUP (V3 only) <<"))
.doOnComplete(() -> LOGGER.debug("<< CLEANUP (V3 only) >>"))
.then()
.block(Duration.ofMinutes(30));
return;
}

Flux.empty()
.thenMany(
Mono.when( // Before Routes
Expand Down Expand Up @@ -216,10 +241,7 @@ void clean() {
cleanUsers(this.cloudFoundryClient, this.nameFactory)))
.thenMany(
Mono.when(
cleanApplicationsV3(
this.cloudFoundryClient,
this.nameFactory), // After Routes, cannot run with
// other cleanApps
cleanApplicationsV3(this.cloudFoundryClient, this.nameFactory),
cleanUsers(this.uaaClient, this.nameFactory) // After CF Users
))
.thenMany(
Expand Down Expand Up @@ -1160,21 +1182,24 @@ private static boolean isCleanable(NameFactory nameFactory, UserResource resourc

private static Flux<Void> removeApplicationServiceBindings(
CloudFoundryClient cloudFoundryClient, Application application) {
return PaginationUtils.requestClientV2Resources(
return PaginationUtils.requestClientV3Resources(
page ->
cloudFoundryClient
.applicationsV2()
.listServiceBindings(
ListApplicationServiceBindingsRequest.builder()
.serviceBindingsV3()
.list(
ListServiceBindingsRequest.builder()
.page(page)
.applicationId(application.getId())
.build()))
.flatMap(
serviceBinding ->
requestRemoveServiceBinding(
cloudFoundryClient,
application.getId(),
ResourceUtils.getId(serviceBinding))
cloudFoundryClient
.serviceBindingsV3()
.delete(
DeleteServiceBindingRequest.builder()
.serviceBindingId(serviceBinding.getId())
.build())
.then()
.doOnError(
t ->
LOGGER.error(
Expand Down
Loading