From e28ce5fb9a7672ee518463916d6594ff0fea03ae Mon Sep 17 00:00:00 2001 From: Thiyagu Karunakaran Date: Fri, 6 Sep 2024 15:26:56 +0000 Subject: [PATCH 01/19] feature added --- samples/listFilesWithFields.js | 57 ++++++++++++++++++++++++++++++++++ src/bucket.ts | 6 ++++ test/bucket.ts | 21 +++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 samples/listFilesWithFields.js diff --git a/samples/listFilesWithFields.js b/samples/listFilesWithFields.js new file mode 100644 index 000000000..b9a6c680b --- /dev/null +++ b/samples/listFilesWithFields.js @@ -0,0 +1,57 @@ +// Copyright 2020 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. + +/** + * This application demonstrates how to perform basic operations on files with + * the Google Cloud Storage API. + * + * For more information, see the README.md under /storage and the documentation + * at https://cloud.google.com/storage/docs. + */ + +function main(bucketName = 'sandbox-thee-1') { + // [START storage_list_files_with_fields] + /** + * TODO(developer): Uncomment the following lines before running the sample. + */ + // The ID of your GCS bucket + // const bucketName = 'your-unique-bucket-name'; + + // Just specify the fields you want + const fields = 'items(id,name,size)'; + + // Imports the Google Cloud client library + const {Storage} = require('@google-cloud/storage'); + + // Creates a client + const storage = new Storage(); + + async function listFilesWithFields() { + const options = {}; + if (fields) { + options.fields = fields; + } + // Lists files in the bucket with specified fields + const [files] = await storage.bucket(bucketName).getFiles(options); + + console.log('Files:'); + files.forEach(file => { + console.log(file); + }); + } + + listFilesWithFields().catch(console.error); + // [END storage_list_files_with_fields] +} +main(...process.argv.slice(2)); diff --git a/src/bucket.ts b/src/bucket.ts index 8757c4f50..73df3374d 100644 --- a/src/bucket.ts +++ b/src/bucket.ts @@ -177,6 +177,7 @@ export interface GetFilesOptions { startOffset?: string; userProject?: string; versions?: boolean; + fields?: string; } export interface CombineOptions extends PreconditionOptions { @@ -2825,6 +2826,11 @@ class Bucket extends ServiceObject { const files = itemsArray.map((file: FileMetadata) => { const options = {} as FileOptions; + if (query.fields) { + const fileInstance = file; + return fileInstance; + } + if (query.versions) { options.generation = file.generation; } diff --git a/test/bucket.ts b/test/bucket.ts index 951cef220..e34bfcbbb 100644 --- a/test/bucket.ts +++ b/test/bucket.ts @@ -1861,11 +1861,32 @@ describe('Bucket', () => { bucket.getFiles({versions: true}, (err: Error, files: FakeFile[]) => { assert.ifError(err); assert(files[0] instanceof FakeFile); + console.log(files); assert.strictEqual(files[0].calledWith_[2].generation, 1); done(); }); }); + it('should return Files with specified values if queried for fields', done => { + bucket.request = ( + reqOpts: DecorateRequestOptions, + callback: Function + ) => { + callback(null, { + items: [{name: 'fake-file-name'}], + }); + }; + + bucket.getFiles( + {fields: 'items(name)'}, + (err: Error, files: FakeFile[]) => { + assert.ifError(err); + assert.strictEqual(files[0].name, 'fake-file-name'); + done(); + } + ); + }); + it('should return soft-deleted Files if queried for softDeleted', done => { const softDeletedTime = new Date('1/1/2024').toISOString(); bucket.request = ( From 83de8275a2377835b8b47e6339c559aaebdd80f9 Mon Sep 17 00:00:00 2001 From: Thiyagu Karunakaran Date: Fri, 6 Sep 2024 15:34:36 +0000 Subject: [PATCH 02/19] fix --- samples/listFilesWithFields.js | 2 +- test/bucket.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/samples/listFilesWithFields.js b/samples/listFilesWithFields.js index b9a6c680b..4d614f4a7 100644 --- a/samples/listFilesWithFields.js +++ b/samples/listFilesWithFields.js @@ -20,7 +20,7 @@ * at https://cloud.google.com/storage/docs. */ -function main(bucketName = 'sandbox-thee-1') { +function main(bucketName = 'my-bucket') { // [START storage_list_files_with_fields] /** * TODO(developer): Uncomment the following lines before running the sample. diff --git a/test/bucket.ts b/test/bucket.ts index e34bfcbbb..3935f9b72 100644 --- a/test/bucket.ts +++ b/test/bucket.ts @@ -1861,7 +1861,6 @@ describe('Bucket', () => { bucket.getFiles({versions: true}, (err: Error, files: FakeFile[]) => { assert.ifError(err); assert(files[0] instanceof FakeFile); - console.log(files); assert.strictEqual(files[0].calledWith_[2].generation, 1); done(); }); From 828b645af8a7250c70e7c86b6c6d8ed9eb4ed141 Mon Sep 17 00:00:00 2001 From: thiyaguk09 Date: Thu, 12 Sep 2024 08:36:37 +0000 Subject: [PATCH 03/19] Added system test and sample test cases --- samples/system-test/files.test.js | 7 +++++++ system-test/common.ts | 2 +- system-test/storage.ts | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/samples/system-test/files.test.js b/samples/system-test/files.test.js index 106c12d1c..487418393 100644 --- a/samples/system-test/files.test.js +++ b/samples/system-test/files.test.js @@ -254,6 +254,13 @@ describe('file', () => { assert.match(output, new RegExp(copiedFileName)); }); + it('should list files with fields', () => { + const output = execSync(`node listFilesWithFields.js ${bucketName}`); + assert.match(output, /Files:/); + assert.match(output, new RegExp(movedFileName)); + assert.match(output, new RegExp(copiedFileName)); + }); + it('should list files by a prefix', () => { let output = execSync(`node listFilesByPrefix.js ${bucketName} test "/"`); assert.match(output, /Files:/); diff --git a/system-test/common.ts b/system-test/common.ts index bf38fa74e..0288143c6 100644 --- a/system-test/common.ts +++ b/system-test/common.ts @@ -105,9 +105,9 @@ describe('Common', () => { assert(err?.message.includes('ECONNREFUSED')); const timeResponse = Date.now(); assert(timeResponse - timeRequest > minExpectedResponseTime); - done(); } ); + done(); }); }); }); diff --git a/system-test/storage.ts b/system-test/storage.ts index 937986121..f192a614c 100644 --- a/system-test/storage.ts +++ b/system-test/storage.ts @@ -3249,6 +3249,20 @@ describe('storage', function () { assert.strictEqual(files!.length, NEW_FILES.length); }); + it('returns file name only when fields is set as name', async () => { + const expected = [ + {name: 'CloudLogo1'}, + {name: 'CloudLogo2'}, + {name: 'CloudLogo3'}, + {name: `${DIRECTORY_NAME}/CloudLogo4`}, + {name: `${DIRECTORY_NAME}/CloudLogo5`}, + {name: `${DIRECTORY_NAME}/inner/CloudLogo6`}, + ]; + const [files] = await bucket.getFiles({fields: 'items(name)'}); + + assert.deepStrictEqual(files, expected); + }); + it('returns folders as prefixes when includeFoldersAsPrefixes is set', async () => { const expected = [`${DIRECTORY_NAME}/`]; const [, , result] = await bucket.getFiles({ From 164975ad6f38e0dc70e8138a3ea5be3d2bb6a388 Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Mon, 16 Sep 2024 07:40:33 +0000 Subject: [PATCH 04/19] copyright fix --- samples/listFilesWithFields.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/listFilesWithFields.js b/samples/listFilesWithFields.js index 4d614f4a7..e64dc8fad 100644 --- a/samples/listFilesWithFields.js +++ b/samples/listFilesWithFields.js @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2024 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. From 41261d817f43b25e3a4a368976c01c68f18aa32b Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Mon, 16 Sep 2024 13:59:57 +0000 Subject: [PATCH 05/19] build: fix path-to-regexp to older version due to node 14 requirement --- package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.json b/package.json index b42dc5737..220a94528 100644 --- a/package.json +++ b/package.json @@ -122,6 +122,8 @@ "pack-n-play": "^2.0.0", "proxyquire": "^2.1.3", "sinon": "^18.0.0", + "nise": "6.0.0", + "path-to-regexp": "6.2.2", "tmp": "^0.2.0", "typescript": "^5.1.6", "yargs": "^17.3.1" From 65aaf977261c0e0ba98e9b14a2e674ffbdbdc68e Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Mon, 16 Sep 2024 14:26:54 +0000 Subject: [PATCH 06/19] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20?= =?UTF-8?q?post-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- README.md | 1 + samples/README.md | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/README.md b/README.md index 8480241f1..00e2c29c0 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,7 @@ Samples are in the [`samples/`](https://github.com/googleapis/nodejs-storage/tre | List Files | [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFiles.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFiles.js,samples/README.md) | | List Files By Prefix | [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFilesByPrefix.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFilesByPrefix.js,samples/README.md) | | List Files Paginate | [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFilesPaginate.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFilesPaginate.js,samples/README.md) | +| List Files With Fields | [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFilesWithFields.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFilesWithFields.js,samples/README.md) | | List Files with Old Versions. | [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFilesWithOldVersions.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFilesWithOldVersions.js,samples/README.md) | | List Notifications | [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listNotifications.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listNotifications.js,samples/README.md) | | Lock Retention Policy | [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/lockRetentionPolicy.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/lockRetentionPolicy.js,samples/README.md) | diff --git a/samples/README.md b/samples/README.md index 6a748e19c..1f827e45a 100644 --- a/samples/README.md +++ b/samples/README.md @@ -91,6 +91,7 @@ objects to users via direct download. * [List Files](#list-files) * [List Files By Prefix](#list-files-by-prefix) * [List Files Paginate](#list-files-paginate) + * [List Files With Fields](#list-files-with-fields) * [List Files with Old Versions.](#list-files-with-old-versions.) * [List Notifications](#list-notifications) * [Lock Retention Policy](#lock-retention-policy) @@ -1451,6 +1452,23 @@ __Usage:__ +### List Files With Fields + +View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFilesWithFields.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFilesWithFields.js,samples/README.md) + +__Usage:__ + + +`node samples/listFilesWithFields.js` + + +----- + + + + ### List Files with Old Versions. List Files with Old Versions. From 5b1a681e32d3ff00fd53db4ffecbc65ae8958c6a Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Tue, 17 Sep 2024 04:03:27 +0000 Subject: [PATCH 07/19] Remove unnecessary sample code --- samples/listFilesWithFields.js | 57 ------------------------------- samples/system-test/files.test.js | 7 ---- 2 files changed, 64 deletions(-) delete mode 100644 samples/listFilesWithFields.js diff --git a/samples/listFilesWithFields.js b/samples/listFilesWithFields.js deleted file mode 100644 index e64dc8fad..000000000 --- a/samples/listFilesWithFields.js +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2024 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. - -/** - * This application demonstrates how to perform basic operations on files with - * the Google Cloud Storage API. - * - * For more information, see the README.md under /storage and the documentation - * at https://cloud.google.com/storage/docs. - */ - -function main(bucketName = 'my-bucket') { - // [START storage_list_files_with_fields] - /** - * TODO(developer): Uncomment the following lines before running the sample. - */ - // The ID of your GCS bucket - // const bucketName = 'your-unique-bucket-name'; - - // Just specify the fields you want - const fields = 'items(id,name,size)'; - - // Imports the Google Cloud client library - const {Storage} = require('@google-cloud/storage'); - - // Creates a client - const storage = new Storage(); - - async function listFilesWithFields() { - const options = {}; - if (fields) { - options.fields = fields; - } - // Lists files in the bucket with specified fields - const [files] = await storage.bucket(bucketName).getFiles(options); - - console.log('Files:'); - files.forEach(file => { - console.log(file); - }); - } - - listFilesWithFields().catch(console.error); - // [END storage_list_files_with_fields] -} -main(...process.argv.slice(2)); diff --git a/samples/system-test/files.test.js b/samples/system-test/files.test.js index 487418393..106c12d1c 100644 --- a/samples/system-test/files.test.js +++ b/samples/system-test/files.test.js @@ -254,13 +254,6 @@ describe('file', () => { assert.match(output, new RegExp(copiedFileName)); }); - it('should list files with fields', () => { - const output = execSync(`node listFilesWithFields.js ${bucketName}`); - assert.match(output, /Files:/); - assert.match(output, new RegExp(movedFileName)); - assert.match(output, new RegExp(copiedFileName)); - }); - it('should list files by a prefix', () => { let output = execSync(`node listFilesByPrefix.js ${bucketName} test "/"`); assert.match(output, /Files:/); From e93bc982f5b86a2a66e79804507ef00c9a26b27d Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Tue, 17 Sep 2024 08:05:52 +0000 Subject: [PATCH 08/19] Manually modify README regards remove unnecessary sample code --- README.md | 1 - samples/README.md | 18 ------------------ 2 files changed, 19 deletions(-) diff --git a/README.md b/README.md index 00e2c29c0..8480241f1 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,6 @@ Samples are in the [`samples/`](https://github.com/googleapis/nodejs-storage/tre | List Files | [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFiles.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFiles.js,samples/README.md) | | List Files By Prefix | [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFilesByPrefix.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFilesByPrefix.js,samples/README.md) | | List Files Paginate | [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFilesPaginate.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFilesPaginate.js,samples/README.md) | -| List Files With Fields | [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFilesWithFields.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFilesWithFields.js,samples/README.md) | | List Files with Old Versions. | [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFilesWithOldVersions.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFilesWithOldVersions.js,samples/README.md) | | List Notifications | [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listNotifications.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listNotifications.js,samples/README.md) | | Lock Retention Policy | [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/lockRetentionPolicy.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/lockRetentionPolicy.js,samples/README.md) | diff --git a/samples/README.md b/samples/README.md index 1f827e45a..6a748e19c 100644 --- a/samples/README.md +++ b/samples/README.md @@ -91,7 +91,6 @@ objects to users via direct download. * [List Files](#list-files) * [List Files By Prefix](#list-files-by-prefix) * [List Files Paginate](#list-files-paginate) - * [List Files With Fields](#list-files-with-fields) * [List Files with Old Versions.](#list-files-with-old-versions.) * [List Notifications](#list-notifications) * [Lock Retention Policy](#lock-retention-policy) @@ -1452,23 +1451,6 @@ __Usage:__ -### List Files With Fields - -View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFilesWithFields.js). - -[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFilesWithFields.js,samples/README.md) - -__Usage:__ - - -`node samples/listFilesWithFields.js` - - ------ - - - - ### List Files with Old Versions. List Files with Old Versions. From c5a801a64369e6c6751eaece99b5cf7a75589cbb Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Thu, 19 Sep 2024 08:59:04 +0000 Subject: [PATCH 09/19] added 'skipIfExists' option for downloadMany Node Transfer Manager: add support for 'skipIfExists' option for downloadMany --- src/transfer-manager.ts | 11 ++++++++++- test/transfer-manager.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/transfer-manager.ts b/src/transfer-manager.ts index f253461d9..234824d77 100644 --- a/src/transfer-manager.ts +++ b/src/transfer-manager.ts @@ -24,7 +24,7 @@ import { } from './file.js'; import pLimit from 'p-limit'; import * as path from 'path'; -import {createReadStream, promises as fsp} from 'fs'; +import {createReadStream, existsSync, promises as fsp} from 'fs'; import {CRC32C} from './crc32c.js'; import {GoogleAuth} from 'google-auth-library'; import {XMLParser, XMLBuilder} from 'fast-xml-parser'; @@ -108,6 +108,7 @@ export interface DownloadManyFilesOptions { prefix?: string; stripPrefix?: string; passthroughOptions?: DownloadOptions; + skipIfExists?: boolean; } export interface DownloadFileInChunksOptions { @@ -524,6 +525,8 @@ export class TransferManager { * @property {string} [stripPrefix] A prefix to remove from all of the downloaded files. * @property {object} [passthroughOptions] {@link DownloadOptions} Options to be passed through * to each individual download operation. + * @property {boolean} [skipIfExists] Do not download the file if it already exists in + * the destination. * */ /** @@ -605,6 +608,12 @@ export class TransferManager { if (options.stripPrefix) { passThroughOptionsCopy.destination = file.name.replace(regex, ''); } + if ( + options.skipIfExists && + existsSync(passThroughOptionsCopy.destination || '') + ) { + continue; + } promises.push( limit(async () => { diff --git a/test/transfer-manager.ts b/test/transfer-manager.ts index af5b2d7c2..6280a5c44 100644 --- a/test/transfer-manager.ts +++ b/test/transfer-manager.ts @@ -30,6 +30,7 @@ import { TransferManager, Storage, DownloadResponse, + DownloadManyFilesOptions, } from '../src/index.js'; import assert from 'assert'; import * as path from 'path'; @@ -195,6 +196,10 @@ describe('Transfer Manager', () => { }); describe('downloadManyFiles', () => { + beforeEach(() => { + sandbox.stub(fs, 'existsSync').returns(true); + }); + it('calls download for each provided file', async () => { let count = 0; const firstFile = new File(bucket, 'first.txt'); @@ -276,6 +281,27 @@ describe('Transfer Manager', () => { await transferManager.downloadManyFiles([file], {passthroughOptions}); }); + it('does not download files that already exist locally when skipIfExists is true', async () => { + const firstFile = new File(bucket, 'first.txt'); + sandbox.stub(firstFile, 'download').callsFake(options => { + assert.strictEqual( + (options as DownloadManyFilesOptions).skipIfExists, + 0 + ); + }); + const secondFile = new File(bucket, 'second.txt'); + sandbox.stub(secondFile, 'download').callsFake(options => { + assert.strictEqual( + (options as DownloadManyFilesOptions).skipIfExists, + 0 + ); + }); + + const files = [firstFile, secondFile]; + const options = {skipIfExists: true}; + await transferManager.downloadManyFiles(files, options); + }); + it('does not set the destination when prefix, strip prefix and passthroughOptions.destination are not provided', async () => { const options = {}; const filename = 'first.txt'; From 53aab1ea4d9944cae74259f810450795466b6d6b Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Tue, 24 Sep 2024 16:05:49 +0000 Subject: [PATCH 10/19] feat: adds integration tests for Universe Domain configuration --- system-test/storage.ts | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/system-test/storage.ts b/system-test/storage.ts index f192a614c..f6b8efe21 100644 --- a/system-test/storage.ts +++ b/system-test/storage.ts @@ -24,6 +24,7 @@ import * as path from 'path'; import * as tmp from 'tmp'; import * as uuid from 'uuid'; import {ApiError} from '../src/nodejs-common/index.js'; +import {DEFAULT_UNIVERSE} from 'google-auth-library'; import { AccessControlObject, Bucket, @@ -3866,6 +3867,50 @@ describe('storage', function () { }); }); + describe('universeDomainTests', () => { + storage.universeDomain = DEFAULT_UNIVERSE; + const bucketName = generateName(); + const bucket = storage.bucket(bucketName); + const localFile = fs.readFileSync(FILES.logo.path); + let file: File; + + before(async () => { + await bucket.create(); + + file = bucket.file('LogoToSign.jpg'); + fs.createReadStream(FILES.logo.path).pipe(file.createWriteStream()); + }); + + after(async () => { + await deleteFileAsync(file); + storage.bucket(bucketName).delete(); + }); + + it('should get bucket', async () => { + const [buckets] = await storage.getBuckets(); + const getBucket = buckets.filter(item => item.name === bucketName); + assert.strictEqual(getBucket[0].name, bucketName); + }); + + it('should get files', async () => { + const [files] = await bucket.getFiles(); + assert.strictEqual(files[0].name, file.name); + }); + + it('should create a signed read url', async () => { + const [signedReadUrl] = await file.getSignedUrl({ + version: 'v2', + action: 'read', + expires: Date.now() + 5000, + virtualHostedStyle: true, + }); + + const res = await fetch(signedReadUrl); + const body = await res.text(); + assert.strictEqual(body, localFile.toString()); + }); + }); + async function deleteBucketAsync(bucket: Bucket, options?: {}) { // After files are deleted, eventual consistency may require a bit of a // delay to ensure that the bucket recognizes that the files don't exist From e45a650f6f7b30987ef3394b15b1f85501f6fb02 Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Thu, 26 Sep 2024 06:26:47 +0000 Subject: [PATCH 11/19] feat: adds integration tests for Universe Domain configuration with kokoro feat: adds integration tests for Universe Domain configuration with kokoro changes --- .kokoro/continuous/node14/system-test.cfg | 2 +- .kokoro/presubmit/node14/system-test.cfg | 2 +- .kokoro/release/publish.cfg | 2 +- .kokoro/system-test.sh | 6 ++++ system-test/storage.ts | 35 ++++++++++++++++------- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/.kokoro/continuous/node14/system-test.cfg b/.kokoro/continuous/node14/system-test.cfg index 9ba9ad1c7..c7c9507a8 100644 --- a/.kokoro/continuous/node14/system-test.cfg +++ b/.kokoro/continuous/node14/system-test.cfg @@ -8,5 +8,5 @@ env_vars: { env_vars: { key: "SECRET_MANAGER_KEYS" - value: "long-door-651-kokoro-system-test-service-account" + value: "long-door-651-kokoro-system-test-service-account,client-library-test-universe-domain-credential" } \ No newline at end of file diff --git a/.kokoro/presubmit/node14/system-test.cfg b/.kokoro/presubmit/node14/system-test.cfg index 9ba9ad1c7..c7c9507a8 100644 --- a/.kokoro/presubmit/node14/system-test.cfg +++ b/.kokoro/presubmit/node14/system-test.cfg @@ -8,5 +8,5 @@ env_vars: { env_vars: { key: "SECRET_MANAGER_KEYS" - value: "long-door-651-kokoro-system-test-service-account" + value: "long-door-651-kokoro-system-test-service-account,client-library-test-universe-domain-credential" } \ No newline at end of file diff --git a/.kokoro/release/publish.cfg b/.kokoro/release/publish.cfg index baea5db3c..019cc24a5 100644 --- a/.kokoro/release/publish.cfg +++ b/.kokoro/release/publish.cfg @@ -18,7 +18,7 @@ before_action { env_vars: { key: "SECRET_MANAGER_KEYS" - value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem" + value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem,client-library-test-universe-domain-credential" } # Download trampoline resources. diff --git a/.kokoro/system-test.sh b/.kokoro/system-test.sh index 0b3043d26..7fbc86314 100755 --- a/.kokoro/system-test.sh +++ b/.kokoro/system-test.sh @@ -22,6 +22,12 @@ export NPM_CONFIG_PREFIX=${HOME}/.npm-global export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/secret_manager/long-door-651-kokoro-system-test-service-account export GCLOUD_PROJECT=long-door-651 +# For universe domain testing +export TEST_UNIVERSE_DOMAIN_CREDENTIAL=$(realpath ${KOKORO_GFILE_DIR}/secret_manager/client-library-test-universe-domain-credential) +export TEST_UNIVERSE_DOMAIN=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-domain) +export TEST_UNIVERSE_PROJECT_ID=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-project-id) +export TEST_UNIVERSE_LOCATION=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-storage-location) + cd $(dirname $0)/.. # Run a pre-test hook, if a pre-system-test.sh is in the project diff --git a/system-test/storage.ts b/system-test/storage.ts index f6b8efe21..42b1b9a66 100644 --- a/system-test/storage.ts +++ b/system-test/storage.ts @@ -24,7 +24,6 @@ import * as path from 'path'; import * as tmp from 'tmp'; import * as uuid from 'uuid'; import {ApiError} from '../src/nodejs-common/index.js'; -import {DEFAULT_UNIVERSE} from 'google-auth-library'; import { AccessControlObject, Bucket, @@ -3868,14 +3867,26 @@ describe('storage', function () { }); describe('universeDomainTests', () => { - storage.universeDomain = DEFAULT_UNIVERSE; + const TEST_UNIVERSE_DOMAIN = process.env.TEST_UNIVERSE_DOMAIN; + const TEST_PROJECT_ID = process.env.TEST_UNIVERSE_PROJECT_ID; + const TEST_UNIVERSE_LOCATION = process.env.TEST_UNIVERSE_LOCATION; + const CREDENTIAL_PATH = process.env.TEST_UNIVERSE_DOMAIN_CREDENTIAL; + + // Create a client with universe domain credentials + const universeDomainStorage = new Storage({ + projectId: TEST_PROJECT_ID, + keyFilename: CREDENTIAL_PATH, + universeDomain: TEST_UNIVERSE_DOMAIN, + }); + const bucketName = generateName(); - const bucket = storage.bucket(bucketName); const localFile = fs.readFileSync(FILES.logo.path); let file: File; before(async () => { - await bucket.create(); + const [bucket] = await universeDomainStorage.createBucket(bucketName, { + location: TEST_UNIVERSE_LOCATION, + }); file = bucket.file('LogoToSign.jpg'); fs.createReadStream(FILES.logo.path).pipe(file.createWriteStream()); @@ -3883,21 +3894,23 @@ describe('storage', function () { after(async () => { await deleteFileAsync(file); - storage.bucket(bucketName).delete(); + universeDomainStorage.bucket(bucketName).delete(); }); - it('should get bucket', async () => { - const [buckets] = await storage.getBuckets(); + it.only('should get bucket', async () => { + const [buckets] = await universeDomainStorage.getBuckets(); const getBucket = buckets.filter(item => item.name === bucketName); assert.strictEqual(getBucket[0].name, bucketName); }); - it('should get files', async () => { - const [files] = await bucket.getFiles(); - assert.strictEqual(files[0].name, file.name); + it.only('should get files', async () => { + const fileName = await universeDomainStorage + .bucket(bucketName) + .file(file.name).name; + assert.strictEqual(fileName, file.name); }); - it('should create a signed read url', async () => { + it.only('should create a signed read url', async () => { const [signedReadUrl] = await file.getSignedUrl({ version: 'v2', action: 'read', From 5b1ff10d4a76de41009b001a7609d7e13d9482c9 Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Thu, 26 Sep 2024 08:34:51 +0000 Subject: [PATCH 12/19] remove only test lint fix --- system-test/storage.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/system-test/storage.ts b/system-test/storage.ts index 42b1b9a66..af1406048 100644 --- a/system-test/storage.ts +++ b/system-test/storage.ts @@ -3897,20 +3897,20 @@ describe('storage', function () { universeDomainStorage.bucket(bucketName).delete(); }); - it.only('should get bucket', async () => { + it('should get bucket', async () => { const [buckets] = await universeDomainStorage.getBuckets(); const getBucket = buckets.filter(item => item.name === bucketName); assert.strictEqual(getBucket[0].name, bucketName); }); - it.only('should get files', async () => { + it('should get files', async () => { const fileName = await universeDomainStorage .bucket(bucketName) .file(file.name).name; assert.strictEqual(fileName, file.name); }); - it.only('should create a signed read url', async () => { + it('should create a signed read url', async () => { const [signedReadUrl] = await file.getSignedUrl({ version: 'v2', action: 'read', From 31ca74401772ad48f1d119850328fd78451623d8 Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Mon, 30 Sep 2024 07:27:20 +0000 Subject: [PATCH 13/19] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20?= =?UTF-8?q?post-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- .kokoro/continuous/node14/system-test.cfg | 2 +- .kokoro/presubmit/node14/system-test.cfg | 2 +- .kokoro/release/publish.cfg | 2 +- .kokoro/system-test.sh | 6 ------ 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/.kokoro/continuous/node14/system-test.cfg b/.kokoro/continuous/node14/system-test.cfg index c7c9507a8..9ba9ad1c7 100644 --- a/.kokoro/continuous/node14/system-test.cfg +++ b/.kokoro/continuous/node14/system-test.cfg @@ -8,5 +8,5 @@ env_vars: { env_vars: { key: "SECRET_MANAGER_KEYS" - value: "long-door-651-kokoro-system-test-service-account,client-library-test-universe-domain-credential" + value: "long-door-651-kokoro-system-test-service-account" } \ No newline at end of file diff --git a/.kokoro/presubmit/node14/system-test.cfg b/.kokoro/presubmit/node14/system-test.cfg index c7c9507a8..9ba9ad1c7 100644 --- a/.kokoro/presubmit/node14/system-test.cfg +++ b/.kokoro/presubmit/node14/system-test.cfg @@ -8,5 +8,5 @@ env_vars: { env_vars: { key: "SECRET_MANAGER_KEYS" - value: "long-door-651-kokoro-system-test-service-account,client-library-test-universe-domain-credential" + value: "long-door-651-kokoro-system-test-service-account" } \ No newline at end of file diff --git a/.kokoro/release/publish.cfg b/.kokoro/release/publish.cfg index 019cc24a5..baea5db3c 100644 --- a/.kokoro/release/publish.cfg +++ b/.kokoro/release/publish.cfg @@ -18,7 +18,7 @@ before_action { env_vars: { key: "SECRET_MANAGER_KEYS" - value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem,client-library-test-universe-domain-credential" + value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem" } # Download trampoline resources. diff --git a/.kokoro/system-test.sh b/.kokoro/system-test.sh index 7fbc86314..0b3043d26 100755 --- a/.kokoro/system-test.sh +++ b/.kokoro/system-test.sh @@ -22,12 +22,6 @@ export NPM_CONFIG_PREFIX=${HOME}/.npm-global export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/secret_manager/long-door-651-kokoro-system-test-service-account export GCLOUD_PROJECT=long-door-651 -# For universe domain testing -export TEST_UNIVERSE_DOMAIN_CREDENTIAL=$(realpath ${KOKORO_GFILE_DIR}/secret_manager/client-library-test-universe-domain-credential) -export TEST_UNIVERSE_DOMAIN=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-domain) -export TEST_UNIVERSE_PROJECT_ID=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-project-id) -export TEST_UNIVERSE_LOCATION=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-storage-location) - cd $(dirname $0)/.. # Run a pre-test hook, if a pre-system-test.sh is in the project From 91d51b9d66339975f40cd8f0ce90d959179990c7 Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Thu, 3 Oct 2024 08:27:35 +0000 Subject: [PATCH 14/19] fix after hook error --- system-test/storage.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/system-test/storage.ts b/system-test/storage.ts index af1406048..71c341e3e 100644 --- a/system-test/storage.ts +++ b/system-test/storage.ts @@ -3894,7 +3894,6 @@ describe('storage', function () { after(async () => { await deleteFileAsync(file); - universeDomainStorage.bucket(bucketName).delete(); }); it('should get bucket', async () => { From 3090467ac57926e1b327a8526caa5ca14b636644 Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Thu, 3 Oct 2024 13:38:56 +0000 Subject: [PATCH 15/19] added delete bucket --- system-test/storage.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/system-test/storage.ts b/system-test/storage.ts index 71c341e3e..8f4f31c5a 100644 --- a/system-test/storage.ts +++ b/system-test/storage.ts @@ -3894,6 +3894,7 @@ describe('storage', function () { after(async () => { await deleteFileAsync(file); + await universeDomainStorage.bucket(bucketName).delete(); }); it('should get bucket', async () => { From c04f06bd2aa920da08930075fbaa7750272cbed7 Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Thu, 3 Oct 2024 13:51:06 +0000 Subject: [PATCH 16/19] use existing deleteBucketAsync --- system-test/storage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system-test/storage.ts b/system-test/storage.ts index 8f4f31c5a..8e238d108 100644 --- a/system-test/storage.ts +++ b/system-test/storage.ts @@ -3894,7 +3894,7 @@ describe('storage', function () { after(async () => { await deleteFileAsync(file); - await universeDomainStorage.bucket(bucketName).delete(); + await deleteBucketAsync(bucket); }); it('should get bucket', async () => { From 6deb02ad3af036cc5a9912de768c27b072dbae28 Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Fri, 4 Oct 2024 11:29:53 +0000 Subject: [PATCH 17/19] Add environment variables validation --- system-test/storage.ts | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/system-test/storage.ts b/system-test/storage.ts index 8e238d108..4b004c830 100644 --- a/system-test/storage.ts +++ b/system-test/storage.ts @@ -3867,23 +3867,27 @@ describe('storage', function () { }); describe('universeDomainTests', () => { - const TEST_UNIVERSE_DOMAIN = process.env.TEST_UNIVERSE_DOMAIN; - const TEST_PROJECT_ID = process.env.TEST_UNIVERSE_PROJECT_ID; - const TEST_UNIVERSE_LOCATION = process.env.TEST_UNIVERSE_LOCATION; - const CREDENTIAL_PATH = process.env.TEST_UNIVERSE_DOMAIN_CREDENTIAL; - - // Create a client with universe domain credentials - const universeDomainStorage = new Storage({ - projectId: TEST_PROJECT_ID, - keyFilename: CREDENTIAL_PATH, - universeDomain: TEST_UNIVERSE_DOMAIN, - }); - + let universeDomainStorage: Storage; const bucketName = generateName(); const localFile = fs.readFileSync(FILES.logo.path); let file: File; before(async () => { + const TEST_UNIVERSE_DOMAIN = isNullOrUndefined('TEST_UNIVERSE_DOMAIN'); + const TEST_PROJECT_ID = isNullOrUndefined('TEST_UNIVERSE_PROJECT_ID'); + const TEST_UNIVERSE_LOCATION = isNullOrUndefined( + 'TEST_UNIVERSE_LOCATION' + ); + const CREDENTIAL_PATH = isNullOrUndefined( + 'TEST_UNIVERSE_DOMAIN_CREDENTIAL' + ); + // Create a client with universe domain credentials + universeDomainStorage = new Storage({ + projectId: TEST_PROJECT_ID, + keyFilename: CREDENTIAL_PATH, + universeDomain: TEST_UNIVERSE_DOMAIN, + }); + const [bucket] = await universeDomainStorage.createBucket(bucketName, { location: TEST_UNIVERSE_LOCATION, }); @@ -4073,4 +4077,12 @@ describe('storage', function () { function createFileWithContentPromise(content: string) { return bucket.file(`${generateName()}.txt`).save(content); } + + function isNullOrUndefined(envVarName: string) { + const value = process.env[envVarName]; + if (value === undefined || value === null) { + throw new Error(`Please set the ${envVarName} environment variable.`); + } + return value; + } }); From 04b23a161501f3bbf0272c7e41bf7b463ec8f29b Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Fri, 4 Oct 2024 11:43:03 +0000 Subject: [PATCH 18/19] added kokoro changes --- .kokoro/continuous/node14/system-test.cfg | 2 +- .kokoro/presubmit/node14/system-test.cfg | 2 +- .kokoro/release/publish.cfg | 2 +- .kokoro/samples-test.sh | 6 ++++++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.kokoro/continuous/node14/system-test.cfg b/.kokoro/continuous/node14/system-test.cfg index 9ba9ad1c7..c7c9507a8 100644 --- a/.kokoro/continuous/node14/system-test.cfg +++ b/.kokoro/continuous/node14/system-test.cfg @@ -8,5 +8,5 @@ env_vars: { env_vars: { key: "SECRET_MANAGER_KEYS" - value: "long-door-651-kokoro-system-test-service-account" + value: "long-door-651-kokoro-system-test-service-account,client-library-test-universe-domain-credential" } \ No newline at end of file diff --git a/.kokoro/presubmit/node14/system-test.cfg b/.kokoro/presubmit/node14/system-test.cfg index 9ba9ad1c7..c7c9507a8 100644 --- a/.kokoro/presubmit/node14/system-test.cfg +++ b/.kokoro/presubmit/node14/system-test.cfg @@ -8,5 +8,5 @@ env_vars: { env_vars: { key: "SECRET_MANAGER_KEYS" - value: "long-door-651-kokoro-system-test-service-account" + value: "long-door-651-kokoro-system-test-service-account,client-library-test-universe-domain-credential" } \ No newline at end of file diff --git a/.kokoro/release/publish.cfg b/.kokoro/release/publish.cfg index baea5db3c..019cc24a5 100644 --- a/.kokoro/release/publish.cfg +++ b/.kokoro/release/publish.cfg @@ -18,7 +18,7 @@ before_action { env_vars: { key: "SECRET_MANAGER_KEYS" - value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem" + value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem,client-library-test-universe-domain-credential" } # Download trampoline resources. diff --git a/.kokoro/samples-test.sh b/.kokoro/samples-test.sh index 8c5d108cb..ac422aeb3 100755 --- a/.kokoro/samples-test.sh +++ b/.kokoro/samples-test.sh @@ -22,6 +22,12 @@ export NPM_CONFIG_PREFIX=${HOME}/.npm-global export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/secret_manager/long-door-651-kokoro-system-test-service-account export GCLOUD_PROJECT=long-door-651 +# For universe domain testing +export TEST_UNIVERSE_DOMAIN_CREDENTIAL=$(realpath ${KOKORO_GFILE_DIR}/secret_manager/client-library-test-universe-domain-credential) +export TEST_UNIVERSE_DOMAIN=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-domain) +export TEST_UNIVERSE_PROJECT_ID=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-project-id) +export TEST_UNIVERSE_LOCATION=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-storage-location) + cd $(dirname $0)/.. # Run a pre-test hook, if a pre-samples-test.sh is in the project From ffbc3d8f97db77d856ba5ef2ff25acb4695c6671 Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Fri, 4 Oct 2024 13:13:10 +0000 Subject: [PATCH 19/19] fix environment variables to correct path --- .kokoro/samples-test.sh | 6 ------ .kokoro/system-test.sh | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.kokoro/samples-test.sh b/.kokoro/samples-test.sh index ac422aeb3..8c5d108cb 100755 --- a/.kokoro/samples-test.sh +++ b/.kokoro/samples-test.sh @@ -22,12 +22,6 @@ export NPM_CONFIG_PREFIX=${HOME}/.npm-global export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/secret_manager/long-door-651-kokoro-system-test-service-account export GCLOUD_PROJECT=long-door-651 -# For universe domain testing -export TEST_UNIVERSE_DOMAIN_CREDENTIAL=$(realpath ${KOKORO_GFILE_DIR}/secret_manager/client-library-test-universe-domain-credential) -export TEST_UNIVERSE_DOMAIN=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-domain) -export TEST_UNIVERSE_PROJECT_ID=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-project-id) -export TEST_UNIVERSE_LOCATION=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-storage-location) - cd $(dirname $0)/.. # Run a pre-test hook, if a pre-samples-test.sh is in the project diff --git a/.kokoro/system-test.sh b/.kokoro/system-test.sh index 0b3043d26..e219954ae 100755 --- a/.kokoro/system-test.sh +++ b/.kokoro/system-test.sh @@ -22,6 +22,12 @@ export NPM_CONFIG_PREFIX=${HOME}/.npm-global export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/secret_manager/long-door-651-kokoro-system-test-service-account export GCLOUD_PROJECT=long-door-651 +# For universe domain testing +export TEST_UNIVERSE_DOMAIN_CREDENTIAL=${KOKORO_GFILE_DIR}/secret_manager/client-library-test-universe-domain-credential +export TEST_UNIVERSE_DOMAIN=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-domain) +export TEST_UNIVERSE_PROJECT_ID=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-project-id) +export TEST_UNIVERSE_LOCATION=$(gcloud secrets versions access latest --project cloud-devrel-kokoro-resources --secret=client-library-test-universe-storage-location) + cd $(dirname $0)/.. # Run a pre-test hook, if a pre-system-test.sh is in the project