From ce14fa6023866a1abbca2aecc4c202295ff45e6b Mon Sep 17 00:00:00 2001 From: joehan Date: Fri, 27 Dec 2024 09:05:40 -0800 Subject: [PATCH 1/2] Fix storage-integeration-test (#8083) * Adding sleeps and explicitly setup chrome on the GH action runner * browset actions * browser actions * Try pinning to ubuntu 22.04 --- .github/workflows/node-test.yml | 12 +++++++++++- scripts/storage-emulator-integration/run.sh | 9 +++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/workflows/node-test.yml b/.github/workflows/node-test.yml index 9ecf3d737a8..fc55932ae09 100644 --- a/.github/workflows/node-test.yml +++ b/.github/workflows/node-test.yml @@ -89,6 +89,11 @@ jobs: distribution: temurin - uses: actions/checkout@v4 + - name: Setup Chrome + uses: browser-actions/setup-chrome@v1.7.2 + with: + install-dependencies: true + install-chromedriver: true - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} @@ -146,7 +151,7 @@ jobs: integration: needs: unit if: contains(fromJSON('["push", "merge_group"]'), github.event_name) - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 env: FIREBASE_EMULATORS_PATH: ${{ github.workspace }}/emulator-cache @@ -184,6 +189,11 @@ jobs: node-version: ${{ matrix.node-version }} cache: npm cache-dependency-path: npm-shrinkwrap.json + - name: Setup Chrome + uses: browser-actions/setup-chrome@v1.7.2 + with: + install-dependencies: true + install-chromedriver: true - name: Cache firebase emulators uses: actions/cache@v3 with: diff --git a/scripts/storage-emulator-integration/run.sh b/scripts/storage-emulator-integration/run.sh index f2152963321..1b19adf5fef 100755 --- a/scripts/storage-emulator-integration/run.sh +++ b/scripts/storage-emulator-integration/run.sh @@ -12,10 +12,19 @@ firebase setup:emulators:storage mocha scripts/storage-emulator-integration/internal/tests.ts +# Brief sleep between tests to make sure emulators shut down fully. +sleep 5 + mocha scripts/storage-emulator-integration/rules/*.test.ts +sleep 5 + mocha scripts/storage-emulator-integration/import/tests.ts +sleep 5 + mocha scripts/storage-emulator-integration/multiple-targets/tests.ts +sleep 5 + mocha scripts/storage-emulator-integration/conformance/*.test.ts From 774d3f0580c8fa91c8e95378f79f28e60e1b867d Mon Sep 17 00:00:00 2001 From: Rosalyn Tan Date: Fri, 27 Dec 2024 09:50:41 -0800 Subject: [PATCH 2/2] Change how FDC determines whether creating a CSQL free trial is allowed. (#8065) * Fix log statements. * Catch backend quota error instead of querying for free trial metric. --- src/dataconnect/freeTrial.ts | 17 +++++--- src/dataconnect/provisionCloudSql.ts | 58 +++++++++++++++------------- 2 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/dataconnect/freeTrial.ts b/src/dataconnect/freeTrial.ts index c4d3841defb..1a5f2fd910f 100644 --- a/src/dataconnect/freeTrial.ts +++ b/src/dataconnect/freeTrial.ts @@ -35,6 +35,13 @@ export async function getFreeTrialInstanceId(projectId: string): Promise i.settings.userLabels?.["firebase-data-connect"] === "ft")?.name; } +export async function isFreeTrialError(err: any, projectId: string): Promise { + // checkFreeTrialInstanceUsed is also called to ensure the request didn't fail due to an unrelated quota issue. + return err.message.includes("Quota Exhausted") && (await checkFreeTrialInstanceUsed(projectId)) + ? true + : false; +} + export function printFreeTrialUnavailable( projectId: string, configYamlPath: string, @@ -42,26 +49,26 @@ export function printFreeTrialUnavailable( ): void { if (!instanceId) { utils.logLabeledError( - "data connect", + "dataconnect", "The CloudSQL free trial has already been used on this project.", ); utils.logLabeledError( - "data connect", + "dataconnect", `You may create or use a paid CloudSQL instance by visiting https://console.cloud.google.com/sql/instances`, ); return; } utils.logLabeledError( - "data connect", + "dataconnect", `Project '${projectId} already has a CloudSQL instance '${instanceId}' on the Firebase Data Connect no-cost trial.`, ); const reuseHint = `To use a different database in the same instance, ${clc.bold(`change the ${clc.blue("instanceId")} to "${instanceId}"`)} and update ${clc.blue("location")} in ` + `${clc.green(configYamlPath)}.`; - utils.logLabeledError("data connect", reuseHint); + utils.logLabeledError("dataconnect", reuseHint); utils.logLabeledError( - "data connect", + "dataconnect", `Alternatively, you may create a new (paid) CloudSQL instance at https://console.cloud.google.com/sql/instances`, ); } diff --git a/src/dataconnect/provisionCloudSql.ts b/src/dataconnect/provisionCloudSql.ts index 57993b9ae44..20b63907308 100755 --- a/src/dataconnect/provisionCloudSql.ts +++ b/src/dataconnect/provisionCloudSql.ts @@ -11,7 +11,7 @@ import { getFreeTrialInstanceId, freeTrialTermsLink, printFreeTrialUnavailable, - checkFreeTrialInstanceUsed, + isFreeTrialError, } from "./freeTrial"; import { FirebaseError } from "../error"; @@ -69,11 +69,6 @@ export async function provisionCloudSql(args: { if (err.status !== 404) { throw err; } - const freeTrialInstanceId = await getFreeTrialInstanceId(projectId); - if (await checkFreeTrialInstanceUsed(projectId)) { - printFreeTrialUnavailable(projectId, configYamlPath, freeTrialInstanceId); - throw new FirebaseError("No-cost Cloud SQL trial has already been used on this project."); - } const cta = dryRun ? "It will be created on your next deploy" : "Creating it now."; silent || utils.logLabeledBullet( @@ -84,27 +79,36 @@ export async function provisionCloudSql(args: { `\nMonitor the progress at ${cloudSqlAdminClient.instanceConsoleLink(projectId, instanceId)}`, ); if (!dryRun) { - const newInstance = await promiseWithSpinner( - () => - cloudSqlAdminClient.createInstance( - projectId, - locationId, - instanceId, - enableGoogleMlIntegration, - waitForCreation, - ), - "Creating your instance...", - ); - if (newInstance) { - silent || utils.logLabeledBullet("dataconnect", "Instance created"); - connectionName = newInstance?.connectionName || ""; - } else { - silent || - utils.logLabeledBullet( - "dataconnect", - "Cloud SQL instance creation started - it should be ready shortly. Database and users will be created on your next deploy.", - ); - return connectionName; + try { + const newInstance = await promiseWithSpinner( + () => + cloudSqlAdminClient.createInstance( + projectId, + locationId, + instanceId, + enableGoogleMlIntegration, + waitForCreation, + ), + "Creating your instance...", + ); + if (newInstance) { + silent || utils.logLabeledBullet("dataconnect", "Instance created"); + connectionName = newInstance?.connectionName || ""; + } else { + silent || + utils.logLabeledBullet( + "dataconnect", + "Cloud SQL instance creation started - it should be ready shortly. Database and users will be created on your next deploy.", + ); + return connectionName; + } + } catch (err: any) { + if (await isFreeTrialError(err, projectId)) { + const freeTrialInstanceId = await getFreeTrialInstanceId(projectId); + printFreeTrialUnavailable(projectId, configYamlPath, freeTrialInstanceId); + throw new FirebaseError("No-cost Cloud SQL trial has already been used on this project."); + } + throw err; } } }