Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ public GoogleProjectCreationFlight(FlightMap inputParameters, Object application
new CreateStorageLogBucketStep(clientConfig, gcpProjectConfig),
newCloudApiDefaultRetryRule());
addStep(
new CreateConsumerDefinedQuotaForBigQueryDailyUsageStep(serviceUsageCow, gcpProjectConfig));
new CreateConsumerDefinedQuotaForBigQueryDailyUsageStep(serviceUsageCow, gcpProjectConfig),
newCloudApiDefaultRetryRule());

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the only step in the flight that didn't have the retry rule. Adding it.

addStep(
new DeleteDefaultServiceAccountStep(iamCow, gcpProjectConfig),
newCloudApiDefaultRetryRule());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import static bio.terra.buffer.service.resource.flight.GoogleProjectConfigUtils.REGION_TO_IP_RANGE;
import static bio.terra.buffer.service.resource.flight.GoogleProjectConfigUtils.getRegionToIpRange;
import static bio.terra.buffer.service.resource.flight.GoogleUtils.*;
import static org.awaitility.Awaitility.await;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
Expand Down Expand Up @@ -127,11 +128,13 @@
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.awaitility.core.ConditionFactory;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -525,6 +528,8 @@ public void testCreateGoogleProject_errorWhenResourceStateChange() throws Except
FlightStatus.ERROR, stairwayComponent.get().getFlightState(flightId).getFlightStatus());
}

@Disabled(
"Since Oct 2026, the integration test environment is not working correctly for quota changes; root cause unknown")
@Test
public void testCreateGoogleProject_createsConsumerOverride() throws Exception {
FlightManager manager =
Expand Down Expand Up @@ -691,28 +696,31 @@ private void assertEnableApisContains(Project project, List<String> enabledApis)
Matchers.hasItems(serviceNames.toArray()));
}

private void assertIamBindingsContains(Project project, List<IamBinding> iamBindings)
throws Exception {
private void assertIamBindingsContains(Project project, List<IamBinding> iamBindings) {
// By default we enable some services, which causes GCP to automatically create Service Accounts
// and grant them permissions on the project.
// e.g.,"serviceAccount:{projectId}-compute@developer.gserviceaccount.com" has editor role.
// So we need to iterate through all bindings and verify they at least contain the members &
// roles we expect.

Map<String, List<String>> allBindings =
rmCow
.projects()
.getIamPolicy(project.getProjectId(), new GetIamPolicyRequest())
.execute()
.getBindings()
.stream()
.collect(Collectors.toMap(Binding::getRole, Binding::getMembers));

for (IamBinding iamBinding : iamBindings) {
assertThat(
new ArrayList<>(allBindings.get(iamBinding.getRole())),
Matchers.hasItems(iamBinding.getMembers().toArray()));
}
// IAM policy changes may not be visible immediately, so poll until they are.
awaitEventualConsistency()
.untilAsserted(
() -> {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this diff is easier to see if you hide whitespace!

Map<String, List<String>> allBindings =
rmCow
.projects()
.getIamPolicy(project.getProjectId(), new GetIamPolicyRequest())
.execute()
.getBindings()
.stream()
.collect(Collectors.toMap(Binding::getRole, Binding::getMembers));

for (IamBinding iamBinding : iamBindings) {
assertThat(
new ArrayList<>(allBindings.getOrDefault(iamBinding.getRole(), List.of())),
Matchers.hasItems(iamBinding.getMembers().toArray()));
}
});
}

private void assertLogStorageBucketExists(Project project) throws Exception {
Expand Down Expand Up @@ -1002,19 +1010,30 @@ private void assertDefaultVpcNotExists(Project project) throws Exception {
404));
}

private void assertServiceAccountExists(Project project, String serviceAccountEmail)
throws Exception {
List<ServiceAccount> serviceAccounts =
Optional.ofNullable(
iamCow
.projects()
.serviceAccounts()
.list("projects/" + project.getProjectId())
.execute()
.getAccounts())
.orElse(List.of());

assertTrue(serviceAccounts.stream().anyMatch(s -> serviceAccountEmail.equals(s.getEmail())));
private void assertServiceAccountExists(Project project, String serviceAccountEmail) {
// Newly created service accounts may not show up in the list immediately.
awaitEventualConsistency()
.untilAsserted(
() -> {
List<ServiceAccount> serviceAccounts =
Optional.ofNullable(
iamCow
.projects()
.serviceAccounts()
.list("projects/" + project.getProjectId())
.execute()
.getAccounts())
.orElse(List.of());

assertTrue(
serviceAccounts.stream().anyMatch(s -> serviceAccountEmail.equals(s.getEmail())),
"Service account " + serviceAccountEmail + " not found");
});
}

/** Polls for GCP state that may not be immediately visible after a flight completes. */
private static ConditionFactory awaitEventualConsistency() {
return await().atMost(Duration.ofMinutes(4)).pollInterval(Duration.ofSeconds(5));
}

private void assertDefaultServiceAccountExists(Project project) throws Exception {
Expand Down
Loading