From 993f538193384f99f22b226e06aaa890345796ab Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Wed, 18 Mar 2026 23:22:53 +0000 Subject: [PATCH] feat(storage): introduce bucket lifecycle samples and tests for migration --- storage/disableBucketLifecycleManagement.js | 55 +++++++++++++ storage/enableBucketLifecycleManagement.js | 64 +++++++++++++++ storage/package.json | 30 +++++++ storage/resources/.gitignore | 1 + storage/resources/resourcesSub1/testSub1.txt | 2 + storage/resources/test.txt | 1 + storage/resources/test2.txt | 1 + storage/scripts/cleanup | 44 ++++++++++ storage/system-test/bucketLifecycle.test.js | 80 +++++++++++++++++++ ...t_9d800329-00da-4cdd-9a3e-7ac6743d5813.txt | 0 10 files changed, 278 insertions(+) create mode 100644 storage/disableBucketLifecycleManagement.js create mode 100644 storage/enableBucketLifecycleManagement.js create mode 100644 storage/package.json create mode 100644 storage/resources/.gitignore create mode 100644 storage/resources/resourcesSub1/testSub1.txt create mode 100644 storage/resources/test.txt create mode 100644 storage/resources/test2.txt create mode 100644 storage/scripts/cleanup create mode 100644 storage/system-test/bucketLifecycle.test.js create mode 100644 storage/system-test/test_9d800329-00da-4cdd-9a3e-7ac6743d5813.txt diff --git a/storage/disableBucketLifecycleManagement.js b/storage/disableBucketLifecycleManagement.js new file mode 100644 index 0000000000..04569982f9 --- /dev/null +++ b/storage/disableBucketLifecycleManagement.js @@ -0,0 +1,55 @@ +// 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. + +'use strict'; + +/** + * This application demonstrates how to disable Object Lifecycle Management for + * a bucket. + * + * For more information, see the documentation at https://cloud.google.com/storage/docs/lifecycle. + */ + +function main(bucketName = 'my-bucket') { + // [START storage_disable_bucket_lifecycle_management] + /** + * TODO(developer): Uncomment the following lines before running the sample. + */ + // The ID of your GCS bucket + // const bucketName = 'your-unique-bucket-name'; + + // Imports the Google Cloud client library + const {Storage} = require('@google-cloud/storage'); + + // Creates a client + const storage = new Storage(); + + async function disableBucketLifecycleManagement() { + try { + await storage.bucket(bucketName).setMetadata({lifecycle: null}); + + console.log(`Lifecycle management is disabled for bucket ${bucketName}`); + } catch (error) { + console.error( + 'Error executing disable bucket lifecycle management:', + error.message || error + ); + } + } + + disableBucketLifecycleManagement(); + // [END storage_disable_bucket_lifecycle_management] +} + +main(...process.argv.slice(2)); diff --git a/storage/enableBucketLifecycleManagement.js b/storage/enableBucketLifecycleManagement.js new file mode 100644 index 0000000000..a3157c93d3 --- /dev/null +++ b/storage/enableBucketLifecycleManagement.js @@ -0,0 +1,64 @@ +// 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. + +'use strict'; + +/** + * This application demonstrates how to enable Object Lifecycle Management for + * a bucket. + * + * For more information, see the documentation at https://cloud.google.com/storage/docs/lifecycle. + */ + +function main(bucketName = 'my-bucket') { + // [START storage_enable_bucket_lifecycle_management] + /** + * TODO(developer): Uncomment the following lines before running the sample. + */ + // The ID of your GCS bucket + // const bucketName = 'your-unique-bucket-name'; + + // Imports the Google Cloud client library + const {Storage} = require('@google-cloud/storage'); + + // Creates a client + const storage = new Storage(); + + async function enableBucketLifecycleManagement() { + try { + const [metadata] = await storage.bucket(bucketName).addLifecycleRule({ + action: { + type: 'Delete', + }, + condition: {age: 100}, + }); + + console.log( + `Lifecycle management is enabled for bucket ${bucketName} and the rules are:` + ); + + console.log(metadata.lifecycle.rule); + } catch (error) { + console.error( + 'Error executing enable bucket lifecycle management:', + error.message || error + ); + } + } + + enableBucketLifecycleManagement(); + // [END storage_enable_bucket_lifecycle_management] +} + +main(...process.argv.slice(2)); diff --git a/storage/package.json b/storage/package.json new file mode 100644 index 0000000000..71acc18ab5 --- /dev/null +++ b/storage/package.json @@ -0,0 +1,30 @@ +{ + "name": "@google-cloud/storage-samples", + "description": "Samples for the Cloud Storage Client Library for Node.js.", + "license": "Apache-2.0", + "author": "Google Inc.", + "engines": { + "node": ">=12" + }, + "repository": "googleapis/nodejs-storage", + "private": true, + "files": [ + "*.js" + ], + "scripts": { + "cleanup": "node scripts/cleanup", + "test": "mocha system-test/*.js --timeout 800000" + }, + "dependencies": { + "@google-cloud/pubsub": "^4.0.0", + "@google-cloud/storage": "^7.19.0", + "node-fetch": "^2.6.7", + "uuid": "^8.0.0", + "yargs": "^16.0.0" + }, + "devDependencies": { + "chai": "^4.2.0", + "mocha": "^8.0.0", + "p-limit": "^3.1.0" + } +} diff --git a/storage/resources/.gitignore b/storage/resources/.gitignore new file mode 100644 index 0000000000..6738013702 --- /dev/null +++ b/storage/resources/.gitignore @@ -0,0 +1 @@ +downloaded.txt diff --git a/storage/resources/resourcesSub1/testSub1.txt b/storage/resources/resourcesSub1/testSub1.txt new file mode 100644 index 0000000000..51f4b307d5 --- /dev/null +++ b/storage/resources/resourcesSub1/testSub1.txt @@ -0,0 +1,2 @@ +Sub1 +Hello World! \ No newline at end of file diff --git a/storage/resources/test.txt b/storage/resources/test.txt new file mode 100644 index 0000000000..c57eff55eb --- /dev/null +++ b/storage/resources/test.txt @@ -0,0 +1 @@ +Hello World! \ No newline at end of file diff --git a/storage/resources/test2.txt b/storage/resources/test2.txt new file mode 100644 index 0000000000..010302410b --- /dev/null +++ b/storage/resources/test2.txt @@ -0,0 +1 @@ +Hello World 2! \ No newline at end of file diff --git a/storage/scripts/cleanup b/storage/scripts/cleanup new file mode 100644 index 0000000000..61bd73114f --- /dev/null +++ b/storage/scripts/cleanup @@ -0,0 +1,44 @@ +#!/usr/bin/env node + +// Copyright 2019 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. + +'use strict'; + +const {Storage} = require('@google-cloud/storage'); +const storage = new Storage(); +const NAME_REG_EXP = /^nodejs-storage-samples-[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$/; + +storage + .getBuckets() + .then(([buckets]) => { + let promise = Promise.resolve(); + + buckets + .filter((bucket) => NAME_REG_EXP.test(bucket.name)) + .forEach((bucket) => { + promise = promise.then(() => { + return bucket.deleteFiles() + .then(() => bucket.deleteFiles(), console.error) + .then(() => { + console.log(`Deleting ${bucket.name}`); + return bucket.delete(); + }, console.error) + .catch(console.error); + }); + }); + }) + .catch((err) => { + console.error('ERROR:', err); + }); diff --git a/storage/system-test/bucketLifecycle.test.js b/storage/system-test/bucketLifecycle.test.js new file mode 100644 index 0000000000..8b1adf9b55 --- /dev/null +++ b/storage/system-test/bucketLifecycle.test.js @@ -0,0 +1,80 @@ +// 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. + +'use strict'; + +const {Storage} = require('@google-cloud/storage'); +const {assert} = require('chai'); +const {before, beforeEach, after, describe, it} = require('mocha'); +const cp = require('child_process'); +const uuid = require('uuid'); + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); + +const storage = new Storage(); +const bucketName = `nodejs-storage-samples-${uuid.v4()}`; +const bucket = storage.bucket(bucketName); + +describe('Bucket lifecycle management', () => { + before(async () => { + await bucket.create(); + }); + + beforeEach(async () => { + await bucket.setMetadata({lifecycle: null}); + }); + + after(async () => { + await bucket.delete().catch(console.error); + }); + + it('should add a lifecycle delete rule', async () => { + const output = execSync( + `node enableBucketLifecycleManagement.js ${bucketName}` + ); + assert.include( + output, + `Lifecycle management is enabled for bucket ${bucketName} and the rules are:` + ); + const [metadata] = await bucket.getMetadata(); + assert.deepStrictEqual(metadata.lifecycle.rule[0], { + action: {type: 'Delete'}, + condition: {age: 100}, + }); + }); + + it('should disable all lifecycle rules', async () => { + // Add a lifecycle rule in order for the sample to delete. + await bucket.addLifecycleRule({ + action: {type: 'Delete'}, + condition: {age: 100}, + }); + + const [metadata] = await bucket.getMetadata(); + assert.deepStrictEqual(metadata.lifecycle.rule[0], { + action: {type: 'Delete'}, + condition: {age: 100}, + }); + + const output = execSync( + `node disableBucketLifecycleManagement.js ${bucketName}` + ); + assert.include( + output, + `Lifecycle management is disabled for bucket ${bucketName}` + ); + const [newMetadata] = await bucket.getMetadata(); + assert.isUndefined(newMetadata.lifecycle); + }); +}); diff --git a/storage/system-test/test_9d800329-00da-4cdd-9a3e-7ac6743d5813.txt b/storage/system-test/test_9d800329-00da-4cdd-9a3e-7ac6743d5813.txt new file mode 100644 index 0000000000..e69de29bb2