Skip to content

Testing composite index queries against production #7632

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 53 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
1c42909
testing out the changes
milaGGL Sep 14, 2023
2e8e443
format
milaGGL Sep 15, 2023
1e166e5
Update composite_index_query.test.ts
milaGGL Sep 15, 2023
85933f6
try github workflow
milaGGL Sep 15, 2023
b073d8f
move .tf file up
milaGGL Sep 18, 2023
b8f4bee
copy project.json
milaGGL Sep 18, 2023
4d75c75
Update composite_index.tf
milaGGL Sep 18, 2023
e0d3a11
Update composite_index.tf
milaGGL Sep 18, 2023
b869a52
Update composite_index.tf
milaGGL Sep 18, 2023
6f3b983
add env:
milaGGL Sep 18, 2023
f26a87e
Update test-changed-firestore-integration.yml
milaGGL Sep 18, 2023
c62c8aa
Update test-changed-firestore-integration.yml
milaGGL Sep 18, 2023
9e44a4c
Update composite_index.tf
milaGGL Sep 18, 2023
3b192f0
Update composite_index.tf
milaGGL Sep 18, 2023
987800f
try FIREBASE_CLI_TOKEN
milaGGL Sep 18, 2023
27ad483
Revert "try FIREBASE_CLI_TOKEN"
milaGGL Sep 18, 2023
f42e295
Update test-changed-firestore-integration.yml
milaGGL Sep 18, 2023
a913d74
Revert "Update test-changed-firestore-integration.yml"
milaGGL Sep 18, 2023
75a33da
remove services
milaGGL Sep 18, 2023
5e4464c
Update test-changed-firestore-integration.yml
milaGGL Sep 18, 2023
b6bdc65
Update test-changed-firestore.yml
milaGGL Sep 18, 2023
7035d6c
Update test-changed-firestore.yml
milaGGL Sep 18, 2023
80c95eb
check project
milaGGL Sep 18, 2023
c32b3d9
remove unnecessary terraform run
milaGGL Sep 18, 2023
aed8c2f
run all integration tests
milaGGL Sep 19, 2023
4531fdb
skip MIEQ
milaGGL Sep 19, 2023
a78eebe
Update query.test.ts
milaGGL Sep 19, 2023
37e3770
Update test-changed-firestore.yml
milaGGL Sep 19, 2023
f37eeaf
try run export EXPERIMENTAL_MODE=true
milaGGL Sep 19, 2023
75ba836
add or query tests to composite index tests
milaGGL Sep 19, 2023
ff6b0a9
Revert "try run export EXPERIMENTAL_MODE=true"
milaGGL Sep 19, 2023
d0affc9
upgrade cloud firestore emulator version
milaGGL Sep 19, 2023
035b560
Update query.test.ts
milaGGL Sep 19, 2023
c7fd478
format
milaGGL Sep 19, 2023
e742e2a
Merge branch 'mila/test-MIEQ-against-Emulator' into mila/composite-in…
milaGGL Sep 20, 2023
5c3e9dd
format
milaGGL Sep 20, 2023
6e3514c
Update composite_index_test_helper.ts
milaGGL Sep 20, 2023
3ac112c
hash document keys
milaGGL Sep 20, 2023
144c9b2
Merge branch 'master' into mila/composite-index-testing
milaGGL Sep 21, 2023
d9488d1
resolve comments
milaGGL Sep 22, 2023
32b23a7
pass in project.json as variable to terrafrom
milaGGL Sep 22, 2023
2b7ac37
Update composite_index_test_helper.ts
milaGGL Sep 25, 2023
0552cd1
Update composite_index_test_helper.ts
milaGGL Sep 25, 2023
6296a34
Merge branch 'master' into mila/composite-index-testing
milaGGL Sep 27, 2023
1af8c3c
move the composite index tests into the dedicates file
milaGGL Sep 27, 2023
946c0ba
format
milaGGL Sep 27, 2023
66821d8
Update composite_index_query.test.ts
milaGGL Sep 27, 2023
719e51a
remove duplicated cp config/ci.config.json config/project.json
milaGGL Sep 28, 2023
aa01d4a
move terraform into firestore
milaGGL Oct 2, 2023
364aa84
add extra test helpers
milaGGL Oct 3, 2023
bd906a5
move the terraform into firestore
milaGGL Oct 3, 2023
ed3f5cf
format
milaGGL Oct 3, 2023
e78dff5
Update composite_index_test_helper.ts
milaGGL Oct 3, 2023
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
19 changes: 16 additions & 3 deletions .github/workflows/test-changed-firestore-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@ jobs:
with:
# This makes Actions fetch all Git history so run-changed script can diff properly.
fetch-depth: 0
- uses: 'google-github-actions/auth@v0'
with:
credentials_json: '${{ secrets.JSSDK_ACTIONS_SA_KEY }}'
# create composite indexes with Terraform
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
- name: Terraform Init
run: terraform init
continue-on-error: true
- name: Terraform Apply
if: github.event_name == 'pull_request'
run: |
cp config/ci.config.json config/project.json
terraform apply -var-file=config/project.json -auto-approve
continue-on-error: true
- name: Set up Node (16)
uses: actions/setup-node@v3
with:
Expand All @@ -24,9 +39,7 @@ jobs:
- name: Bump Node memory limit
run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV
- name: Test setup and yarn install
run: |
cp config/ci.config.json config/project.json
yarn
run: yarn
- name: build
run: yarn build:changed firestore-integration
- name: Run tests if firestore or its dependencies has changed
Expand Down
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,10 @@ tsdoc-metadata.json
# generated html docs
docs-rut/
docs/
toc/
toc/

# generated Terraform docs
.terraform/*
.terraform.lock.hcl
*.tfstate
*.tfstate.*
104 changes: 104 additions & 0 deletions firestore_index_config.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
locals {
indexes = {
index1 = [
{
field_path = "testId"
order = "ASCENDING"
},
{
field_path = "a"
order = "ASCENDING"
},
]
index2 = [
{
field_path = "testId"
order = "ASCENDING"
},
{
field_path = "b"
order = "ASCENDING"
},
]
index3 = [
{
field_path = "testId"
order = "ASCENDING"
},
{
field_path = "b"
order = "DESCENDING"
},
]
index4 = [
{
field_path = "a"
order = "ASCENDING"
},
{
field_path = "testId"
order = "ASCENDING"
},
{
field_path = "b"
order = "ASCENDING"
},
]
index5 = [
{
field_path = "a"
order = "ASCENDING"
},
{
field_path = "testId"
order = "ASCENDING"
},
{
field_path = "b"
order = "DESCENDING"
},
]
index6 = [
{
field_path = "a"
order = "ASCENDING"
},
{
field_path = "testId"
order = "ASCENDING"
},
{
field_path = "a"
order = "DESCENDING"
},
]
index7 = [
{
field_path = "b"
order = "ASCENDING"
},
{
field_path = "testId"
order = "ASCENDING"
},
{
field_path = "a"
order = "ASCENDING"
},
]
index8 = [
{
field_path = "b"
order = "ASCENDING"
},
{
field_path = "testId"
order = "ASCENDING"
},
{
field_path = "a"
order = "DESCENDING"
},
]
}
}
41 changes: 41 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
variable "projectId" {}

provider "google" {
project = var.projectId
}

resource "google_firestore_index" "default-db-index" {
collection = "composite-index-test-collection"

for_each = local.indexes
dynamic "fields" {
for_each = distinct(flatten([for k, v in local.indexes : [
for i in each.value : {
field_path = i.field_path
order = i.order
}]]))
content {
field_path = lookup(fields.value, "field_path", null)
order = lookup(fields.value, "order", null)
}
}

}

resource "google_firestore_index" "named-db-index" {
collection = "composite-index-test-collection"
database = "test-db"

for_each = local.indexes
dynamic "fields" {
for_each = distinct(flatten([for k, v in local.indexes : [
for i in each.value : {
field_path = i.field_path
order = i.order
}]]))
content {
field_path = lookup(fields.value, "field_path", null)
order = lookup(fields.value, "order", null)
}
}
}
141 changes: 141 additions & 0 deletions packages/firestore/test/integration/api/composite_index_query.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/**
* @license
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { CompositeIndexTestHelper } from '../util/composite_index_test_helper';
import {
where,
orderBy,
limit,
limitToLast,
or
} from '../util/firebase_export';
import { apiDescribe } from '../util/helpers';

/*
* Guidance for Creating Tests:
* ----------------------------
* When creating tests that require composite indexes, it is recommended to utilize the
* "CompositeIndexTestHelper" class. This utility class provides methods for creating
* and setting test documents and running queries with ease, ensuring proper data
* isolation and query construction.
*
* Please remember to update the main index configuration file (firestore_index_config.tf)
* with any new composite indexes needed for the tests. This ensures synchronization with
* other testing environments, including CI. You can generate the required index link by
* clicking on the Firebase console link in the error message while running tests locally.
*/

apiDescribe('Composite Index Queries', persistence => {
// OR Query tests only run when the SDK's local cache is configured to use
// LRU garbage collection (rather than eager garbage collection) because
// they validate that the result from server and cache match.
// eslint-disable-next-line no-restricted-properties
(persistence.gc === 'lru' ? describe : describe.skip)('OR Queries', () => {
it('can use query overloads', () => {
const testDocs = {
doc1: { a: 1, b: 0 },
doc2: { a: 2, b: 1 },
doc3: { a: 3, b: 2 },
doc4: { a: 1, b: 3 },
doc5: { a: 1, b: 1 }
};
const testHelper = new CompositeIndexTestHelper();
return testHelper.withTestDocs(persistence, testDocs, async coll => {
// a == 1, limit 2, b - desc
await testHelper.assertOnlineAndOfflineResultsMatch(
testHelper.query(
coll,
where('a', '==', 1),
limit(2),
orderBy('b', 'desc')
),
'doc4',
'doc5'
);
});
});

it('can use or queries', () => {
const testDocs = {
doc1: { a: 1, b: 0 },
doc2: { a: 2, b: 1 },
doc3: { a: 3, b: 2 },
doc4: { a: 1, b: 3 },
doc5: { a: 1, b: 1 }
};
const testHelper = new CompositeIndexTestHelper();
return testHelper.withTestDocs(persistence, testDocs, async coll => {
// with one inequality: a>2 || b==1.
await testHelper.assertOnlineAndOfflineResultsMatch(
testHelper.compositeQuery(
coll,
or(where('a', '>', 2), where('b', '==', 1))
),
'doc5',
'doc2',
'doc3'
);

// Test with limits (implicit order by ASC): (a==1) || (b > 0) LIMIT 2
await testHelper.assertOnlineAndOfflineResultsMatch(
testHelper.compositeQuery(
coll,
or(where('a', '==', 1), where('b', '>', 0)),
limit(2)
),
'doc1',
'doc2'
);

// Test with limits (explicit order by): (a==1) || (b > 0) LIMIT_TO_LAST 2
// Note: The public query API does not allow implicit ordering when limitToLast is used.
await testHelper.assertOnlineAndOfflineResultsMatch(
testHelper.compositeQuery(
coll,
or(where('a', '==', 1), where('b', '>', 0)),
limitToLast(2),
orderBy('b')
),
'doc3',
'doc4'
);

// Test with limits (explicit order by ASC): (a==2) || (b == 1) ORDER BY a LIMIT 1
await testHelper.assertOnlineAndOfflineResultsMatch(
testHelper.compositeQuery(
coll,
or(where('a', '==', 2), where('b', '==', 1)),
limit(1),
orderBy('a')
),
'doc5'
);

// Test with limits (explicit order by DESC): (a==2) || (b == 1) ORDER BY a LIMIT_TO_LAST 1
await testHelper.assertOnlineAndOfflineResultsMatch(
testHelper.compositeQuery(
coll,
or(where('a', '==', 2), where('b', '==', 1)),
limitToLast(1),
orderBy('a')
),
'doc2'
);
});
});
});
});
Loading