Skip to content

Commit 842b6c6

Browse files
committed
fix(*): Updated v1 and v2 tests to run simultaneously without error. Additonally comments, formatting and linting included.
1 parent 023ddb9 commit 842b6c6

File tree

14 files changed

+268
-224
lines changed

14 files changed

+268
-224
lines changed

integration_test/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ Auth tests use Firebase client SDK configuration that is hardcoded in `tests/fir
148148

149149
The configuration is automatically used by auth tests and no additional setup is required.
150150

151-
### Auth Blocking Functions Limitation
151+
### Auth Blocking Functions Configuration
152152

153153
Firebase has a limitation where **only ONE blocking auth function can be deployed per project at any time**. This means:
154154

@@ -176,7 +176,7 @@ These tests remain in the codebase but are marked with `describe.skip()` until t
176176

177177
## Architecture
178178

179-
```
179+
```text
180180
integration_test/
181181
├── config/
182182
│ ├── v1/

integration_test/cloudbuild-v1.yaml

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,6 @@ options:
88
timeout: "3600s"
99

1010
steps:
11-
# Create storage bucket for test results if it doesn't exist
12-
- name: "gcr.io/google.com/cloudsdktool/cloud-sdk:stable"
13-
id: "create-bucket"
14-
entrypoint: "bash"
15-
args:
16-
- "-c"
17-
- |
18-
# Create bucket for test results if it doesn't exist
19-
BUCKET_NAME="gs://functions-integration-tests-test-results"
20-
echo "Checking if bucket $$BUCKET_NAME exists..."
21-
if ! gsutil ls "$$BUCKET_NAME" &>/dev/null; then
22-
echo "Creating bucket $$BUCKET_NAME..."
23-
gsutil mb -p "functions-integration-tests" "$$BUCKET_NAME"
24-
else
25-
echo "Bucket $$BUCKET_NAME already exists"
26-
fi
27-
2811
# Build SDK and run all V1 test suites sequentially
2912
- name: "node:20"
3013
id: "build-sdk-and-test-v1"
@@ -51,15 +34,16 @@ steps:
5134
# Verify tools are installed
5235
firebase --version
5336
gcloud --version
54-
# V1 tests use functions-integration-tests project
55-
echo "Running V1 tests on project: functions-integration-tests"
37+
# Set environment variables
38+
export PROJECT_ID="$PROJECT_ID"
39+
echo "Running all tests on project: $PROJECT_ID"
5640
# Use Application Default Credentials (Cloud Build service account)
57-
# Run all V1 test suites sequentially
58-
node scripts/run-tests.js --sequential --filter=v1 --use-published-sdk=file:firebase-functions-local.tgz
41+
# Run all test suites sequentially
42+
node scripts/run-tests.js --sequential --skip-cleanup
5943
6044
# Artifacts to store
6145
artifacts:
6246
objects:
63-
location: "gs://functions-integration-tests-test-results/${BUILD_ID}"
47+
location: "gs://${PROJECT_ID}-artifacts/${BUILD_ID}"
6448
paths:
6549
- "logs/**/*.log"

integration_test/cloudbuild-v2.yaml

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,6 @@ options:
88
timeout: "3600s"
99

1010
steps:
11-
# Create storage bucket for test results if it doesn't exist
12-
- name: "gcr.io/google.com/cloudsdktool/cloud-sdk:stable"
13-
id: "create-bucket"
14-
entrypoint: "bash"
15-
args:
16-
- "-c"
17-
- |
18-
# Create bucket for test results if it doesn't exist
19-
BUCKET_NAME="gs://functions-integration-tests-v2-test-results"
20-
echo "Checking if bucket $$BUCKET_NAME exists..."
21-
if ! gsutil ls "$$BUCKET_NAME" &>/dev/null; then
22-
echo "Creating bucket $$BUCKET_NAME..."
23-
gsutil mb -p "functions-integration-tests-v2" "$$BUCKET_NAME"
24-
else
25-
echo "Bucket $$BUCKET_NAME already exists"
26-
fi
27-
2811
# Build SDK and run all V2 test suites sequentially
2912
# Using the official Google Cloud SDK image which includes gcloud pre-installed
3013
- name: "gcr.io/google.com/cloudsdktool/cloud-sdk:stable"
@@ -60,21 +43,22 @@ steps:
6043
# Install firebase-tools globally
6144
npm install -g firebase-tools
6245
# gcloud is already available in this image
63-
gcloud config set project functions-integration-tests-v2
46+
gcloud config set project "$PROJECT_ID"
6447
# Verify tools are installed
6548
firebase --version
6649
gcloud --version
6750
# Verify gcloud project is set correctly
6851
gcloud config get-value project
69-
# V2 tests use functions-integration-tests-v2 project
70-
echo "Running V2 tests on project: functions-integration-tests-v2"
52+
# Set environment variables
53+
export PROJECT_ID="$PROJECT_ID"
54+
echo "Running all tests on project: $PROJECT_ID"
7155
# Use Application Default Credentials (Cloud Build service account)
72-
# Run all V2 test suites sequentially
73-
node scripts/run-tests.js --sequential --filter=v2 --use-published-sdk=file:firebase-functions-local.tgz
56+
# Run all test suites sequentially
57+
node scripts/run-tests.js --sequential --skip-cleanup
7458
7559
# Artifacts to store
7660
artifacts:
7761
objects:
78-
location: "gs://functions-integration-tests-v2-test-results/${BUILD_ID}"
62+
location: "gs://${PROJECT_ID}-artifacts/${BUILD_ID}"
7963
paths:
8064
- "logs/**/*.log"

integration_test/config/v1/suites.yaml

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Common values are defined in the defaults section to reduce duplication
44

55
defaults:
6-
projectId: functions-integration-tests
6+
projectId: ${PROJECT_ID:-functions-integration-tests}
77
region: us-central1
88
timeout: 540
99
dependencies:
@@ -78,22 +78,16 @@ suites:
7878
- name: storageOnMetadataUpdateTests
7979
trigger: onMetadataUpdate
8080

81-
# Auth triggers (all non-blocking functions)
81+
# Auth triggers (non-blocking functions only - blocking functions must be run separately)
8282
- name: v1_auth
83-
description: "V1 Auth trigger tests"
83+
description: "V1 Auth trigger tests (non-blocking only)"
8484
version: v1
8585
service: auth
8686
functions:
8787
- name: authUserOnCreateTests
8888
trigger: onCreate
8989
- name: authUserOnDeleteTests
9090
trigger: onDelete
91-
- name: authUserBeforeCreateTests
92-
trigger: beforeCreate
93-
collection: authBeforeCreateTests
94-
- name: authUserBeforeSignInTests
95-
trigger: beforeSignIn
96-
collection: authBeforeSignInTests
9791

9892
# Auth non-blocking only (for parallel execution)
9993
- name: v1_auth_nonblocking
@@ -115,7 +109,7 @@ suites:
115109
# - name: authUserBeforeCreateTests
116110
# trigger: beforeCreate
117111
# collection: authBeforeCreateTests
118-
# blocking: true
112+
# timeout: 10 # Short timeout for blocking function (Firebase enforces 7s max)
119113

120114
# Auth beforeSignIn blocking function (must run separately)
121115
# - name: v1_auth_before_signin
@@ -126,7 +120,7 @@ suites:
126120
# - name: authUserBeforeSignInTests
127121
# trigger: beforeSignIn
128122
# collection: authBeforeSignInTests
129-
# blocking: true
123+
# timeout: 10 # Short timeout for blocking function (Firebase enforces 7s max)
130124

131125
# Cloud Tasks triggers
132126
# - name: v1_tasks

integration_test/config/v2/suites.yaml

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Common values are defined in the defaults section to reduce duplication
44

55
defaults:
6-
projectId: functions-integration-tests-v2
6+
projectId: ${PROJECT_ID:-functions-integration-tests-v2}
77
region: us-central1
88
timeout: 540
99
dependencies:
@@ -19,18 +19,22 @@ suites:
1919
version: v2
2020
service: firestore
2121
functions:
22-
- name: firestoreOnDocumentCreatedTests
22+
- name: v2FirestoreOnDocumentCreatedTests
2323
trigger: onDocumentCreated
24-
document: "tests/{testId}"
25-
- name: firestoreOnDocumentDeletedTests
24+
document: "v2tests/{testId}"
25+
collection: "v2FirestoreOnDocumentCreatedTests"
26+
- name: v2FirestoreOnDocumentDeletedTests
2627
trigger: onDocumentDeleted
27-
document: "tests/{testId}"
28-
- name: firestoreOnDocumentUpdatedTests
28+
document: "v2tests/{testId}"
29+
collection: "v2FirestoreOnDocumentDeletedTests"
30+
- name: v2FirestoreOnDocumentUpdatedTests
2931
trigger: onDocumentUpdated
30-
document: "tests/{testId}"
31-
- name: firestoreOnDocumentWrittenTests
32+
document: "v2tests/{testId}"
33+
collection: "v2FirestoreOnDocumentUpdatedTests"
34+
- name: v2FirestoreOnDocumentWrittenTests
3235
trigger: onDocumentWritten
33-
document: "tests/{testId}"
36+
document: "v2tests/{testId}"
37+
collection: "v2FirestoreOnDocumentWrittenTests"
3438

3539
# Realtime Database triggers
3640
- name: v2_database

integration_test/jest.config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ const config = {
33
preset: "ts-jest",
44
testEnvironment: "node",
55
testMatch: ["**/tests/**/*.test.ts"],
6-
testTimeout: 120_000,
6+
testTimeout: 180_000, // Increased to 3 minutes for auth blocking functions
77
transform: {
88
"^.+\\.(t|j)s$": ["ts-jest", { tsconfig: "tsconfig.test.json" }],
99
},
1010
};
1111

12-
export default config;
12+
export default config;

integration_test/package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717
"test:all:sequential": "node scripts/run-tests.js --sequential",
1818
"test:v1:auth-before-create": "node scripts/run-tests.js v1_auth_before_create",
1919
"test:v1:auth-before-signin": "node scripts/run-tests.js v1_auth_before_signin",
20-
"cloudbuild:v1": "gcloud builds submit --config=cloudbuild-v1.yaml --project=functions-integration-tests",
21-
"cloudbuild:v2": "gcloud builds submit --config=cloudbuild-v2.yaml --project=cf3-integration-tests-v2-qa",
22-
"cloudbuild:both": "gcloud builds submit --config=cloudbuild-v1.yaml --project=functions-integration-tests & gcloud builds submit --config=cloudbuild-v2.yaml --project=cf3-integration-tests-v2-qa & wait",
20+
"cloudbuild:v1": "gcloud builds submit --config=cloudbuild-v1.yaml --project=${PROJECT_ID:-functions-integration-tests}",
21+
"cloudbuild:v2": "gcloud builds submit --config=cloudbuild-v2.yaml --project=${PROJECT_ID:-functions-integration-tests}",
22+
"cloudbuild:unified": "gcloud builds submit --config=cloudbuild-v2.yaml --project=${PROJECT_ID:-functions-integration-tests}",
23+
"cloudbuild:both": "gcloud builds submit --config=cloudbuild-v1.yaml --project=${PROJECT_ID:-functions-integration-tests} & gcloud builds submit --config=cloudbuild-v2.yaml --project=${PROJECT_ID:-functions-integration-tests} & wait",
2324
"cleanup": "./scripts/cleanup-suite.sh",
2425
"cleanup:list": "./scripts/cleanup-suite.sh --list-artifacts",
2526
"clean": "rm -rf generated/*"

integration_test/scripts/config-loader.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,16 @@ export function loadUnifiedConfig(configPath = DEFAULT_CONFIG_PATH) {
110110
try {
111111
// Read and parse YAML file
112112
const configContent = readFileSync(configPath, "utf8");
113-
const config = parse(configContent);
113+
114+
// Substitute environment variables in the YAML content
115+
const substitutedContent = configContent.replace(
116+
/\$\{PROJECT_ID:-([^}]+)\}/g,
117+
(match, defaultValue) => {
118+
return process.env.PROJECT_ID || defaultValue;
119+
}
120+
);
121+
122+
const config = parse(substitutedContent);
114123

115124
// Validate basic structure
116125
if (!config || typeof config !== "object") {

integration_test/scripts/generate.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ export async function generateFunctions(suitePatterns, options = {}) {
221221
testRunId,
222222
sdkTarball,
223223
timestamp: new Date().toISOString(),
224-
v1ProjectId: "functions-integration-tests",
225-
v2ProjectId: "functions-integration-tests-v2",
224+
v1ProjectId: process.env.PROJECT_ID || "functions-integration-tests",
225+
v2ProjectId: process.env.PROJECT_ID || "functions-integration-tests",
226226
};
227227

228228
// Generate the test file for this suite

integration_test/scripts/run-tests.js

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -575,14 +575,23 @@ class TestRunner {
575575
const functionStillExists = listResult.stdout.includes(functionName);
576576

577577
if (!functionStillExists) {
578-
this.log(` ✅ Verified: Function deleted via Firebase CLI: ${functionName}`, "success");
578+
this.log(
579+
` ✅ Verified: Function deleted via Firebase CLI: ${functionName}`,
580+
"success"
581+
);
579582
deleted = true;
580583
} else {
581-
this.log(` ⚠️ Function still exists after Firebase CLI delete: ${functionName}`, "warn");
584+
this.log(
585+
` ⚠️ Function still exists after Firebase CLI delete: ${functionName}`,
586+
"warn"
587+
);
582588
}
583589
} catch (listError) {
584590
// If we can't list functions, assume deletion worked
585-
this.log(` ✅ Deleted function via Firebase CLI (unverified): ${functionName}`, "success");
591+
this.log(
592+
` ✅ Deleted function via Firebase CLI (unverified): ${functionName}`,
593+
"success"
594+
);
586595
deleted = true;
587596
}
588597
} catch (error) {
@@ -611,7 +620,10 @@ class TestRunner {
611620
{ silent: true }
612621
);
613622
// If describe succeeds, function still exists
614-
this.log(` ⚠️ Cloud Run service still exists after deletion: ${functionName}`, "warn");
623+
this.log(
624+
` ⚠️ Cloud Run service still exists after deletion: ${functionName}`,
625+
"warn"
626+
);
615627
} catch {
616628
// If describe fails, function was deleted
617629
this.log(` ✅ Deleted function as Cloud Run service: ${functionName}`, "success");
@@ -766,11 +778,10 @@ class TestRunner {
766778
* Get project IDs from configuration (YAML files are source of truth)
767779
*/
768780
getProjectIds() {
769-
// Project IDs are read from the YAML configuration files
770-
// V1 tests use functions-integration-tests
771-
// V2 tests use functions-integration-tests-v2
772-
const v1ProjectId = "functions-integration-tests";
773-
const v2ProjectId = "functions-integration-tests-v2";
781+
// Use single project for both V1 and V2 tests
782+
const projectId = process.env.PROJECT_ID || "functions-integration-tests";
783+
const v1ProjectId = projectId;
784+
const v2ProjectId = projectId;
774785

775786
this.log(`Using V1 Project ID: ${v1ProjectId}`, "info");
776787
this.log(`Using V2 Project ID: ${v2ProjectId}`, "info");
@@ -991,7 +1002,7 @@ class TestRunner {
9911002

9921003
// Wait for functions to become fully available
9931004
this.log("⏳ Waiting 20 seconds for functions to become fully available...", "info");
994-
await new Promise(resolve => setTimeout(resolve, 20000));
1005+
await new Promise((resolve) => setTimeout(resolve, 20000));
9951006

9961007
// Run tests
9971008
await this.runTests([suiteName]);
@@ -1041,6 +1052,13 @@ class TestRunner {
10411052
for (let i = 0; i < suiteNames.length; i++) {
10421053
const suite = suiteNames[i];
10431054
await this.runSuite(suite);
1055+
1056+
// Add delay between suites to allow Firebase to fully process cleanup
1057+
if (i < suiteNames.length - 1) {
1058+
this.log("⏳ Waiting 60 seconds between suites for complete Firebase cleanup...", "info");
1059+
await new Promise((resolve) => setTimeout(resolve, 60000));
1060+
}
1061+
10441062
this.log("");
10451063
}
10461064

@@ -1100,7 +1118,7 @@ class TestRunner {
11001118

11011119
// Wait for functions to become fully available
11021120
this.log("⏳ Waiting 20 seconds for functions to become fully available...", "info");
1103-
await new Promise(resolve => setTimeout(resolve, 20000));
1121+
await new Promise((resolve) => setTimeout(resolve, 20000));
11041122

11051123
// Run tests for this project's suites
11061124
await this.runTests(projectSuites);
@@ -1125,7 +1143,7 @@ class TestRunner {
11251143

11261144
// Wait for functions to become fully available
11271145
this.log("⏳ Waiting 20 seconds for functions to become fully available...", "info");
1128-
await new Promise(resolve => setTimeout(resolve, 20000));
1146+
await new Promise((resolve) => setTimeout(resolve, 20000));
11291147

11301148
// Run tests
11311149
await this.runTests(suiteNames);

0 commit comments

Comments
 (0)