From e7cca79413817474ccec3ccc99c60c8e54cdd4de Mon Sep 17 00:00:00 2001 From: Chandra Sirimala Date: Mon, 2 Nov 2026 13:09:50 +0000 Subject: [PATCH 1/4] feat(storage): add enterprise storage class constants and tuple entries --- .../google/cloud/storage/blob.py | 8 +++++ .../google/cloud/storage/bucket.py | 8 +++++ .../google/cloud/storage/constants.py | 12 +++++++ .../tests/system/test_blob.py | 34 +++++++++++++++++++ .../tests/system/test_bucket.py | 31 +++++++++++++++++ .../tests/unit/test_blob.py | 19 +++++++++++ .../tests/unit/test_bucket.py | 20 +++++++++++ 7 files changed, 132 insertions(+) diff --git a/packages/google-cloud-storage/google/cloud/storage/blob.py b/packages/google-cloud-storage/google/cloud/storage/blob.py index 87493a30dfc0..a40f46d1f230 100644 --- a/packages/google-cloud-storage/google/cloud/storage/blob.py +++ b/packages/google-cloud-storage/google/cloud/storage/blob.py @@ -67,9 +67,11 @@ _DEFAULT_TIMEOUT, ARCHIVE_STORAGE_CLASS, COLDLINE_STORAGE_CLASS, + LR_STANDARD_ENTERPRISE_STORAGE_CLASS, MULTI_REGIONAL_LEGACY_STORAGE_CLASS, NEARLINE_STORAGE_CLASS, REGIONAL_LEGACY_STORAGE_CLASS, + STANDARD_ENTERPRISE_STORAGE_CLASS, STANDARD_STORAGE_CLASS, ) from google.cloud.storage.exceptions import DataCorruption, InvalidResponse @@ -191,9 +193,11 @@ class Blob(_PropertyMixin): STORAGE_CLASSES = ( STANDARD_STORAGE_CLASS, + STANDARD_ENTERPRISE_STORAGE_CLASS, NEARLINE_STORAGE_CLASS, COLDLINE_STORAGE_CLASS, ARCHIVE_STORAGE_CLASS, + LR_STANDARD_ENTERPRISE_STORAGE_CLASS, MULTI_REGIONAL_LEGACY_STORAGE_CLASS, REGIONAL_LEGACY_STORAGE_CLASS, ) @@ -4239,6 +4243,8 @@ def update_storage_class( :attr:`~google.cloud.storage.constants.COLDLINE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.ARCHIVE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.STANDARD_STORAGE_CLASS`, + :attr:`~google.cloud.storage.constants.STANDARD_ENTERPRISE_STORAGE_CLASS`, + :attr:`~google.cloud.storage.constants.LR_STANDARD_ENTERPRISE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.MULTI_REGIONAL_LEGACY_STORAGE_CLASS`, or :attr:`~google.cloud.storage.constants.REGIONAL_LEGACY_STORAGE_CLASS`. @@ -4957,9 +4963,11 @@ def kms_key_name(self, value): :returns: If set, one of :attr:`~google.cloud.storage.constants.STANDARD_STORAGE_CLASS`, + :attr:`~google.cloud.storage.constants.STANDARD_ENTERPRISE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.NEARLINE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.COLDLINE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.ARCHIVE_STORAGE_CLASS`, + :attr:`~google.cloud.storage.constants.LR_STANDARD_ENTERPRISE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.MULTI_REGIONAL_LEGACY_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.REGIONAL_LEGACY_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.DURABLE_REDUCED_AVAILABILITY_STORAGE_CLASS`, diff --git a/packages/google-cloud-storage/google/cloud/storage/bucket.py b/packages/google-cloud-storage/google/cloud/storage/bucket.py index 7954e70e08f9..3f19e61faa6e 100644 --- a/packages/google-cloud-storage/google/cloud/storage/bucket.py +++ b/packages/google-cloud-storage/google/cloud/storage/bucket.py @@ -50,12 +50,14 @@ DURABLE_REDUCED_AVAILABILITY_LEGACY_STORAGE_CLASS, ENFORCEMENT_MODE_FULLY_RESTRICTED, ENFORCEMENT_MODE_NOT_RESTRICTED, + LR_STANDARD_ENTERPRISE_STORAGE_CLASS, MULTI_REGION_LOCATION_TYPE, MULTI_REGIONAL_LEGACY_STORAGE_CLASS, NEARLINE_STORAGE_CLASS, PUBLIC_ACCESS_PREVENTION_INHERITED, REGION_LOCATION_TYPE, REGIONAL_LEGACY_STORAGE_CLASS, + STANDARD_ENTERPRISE_STORAGE_CLASS, STANDARD_STORAGE_CLASS, ) from google.cloud.storage.ip_filter import IPFilter @@ -650,9 +652,11 @@ class Bucket(_PropertyMixin): STORAGE_CLASSES = ( STANDARD_STORAGE_CLASS, + STANDARD_ENTERPRISE_STORAGE_CLASS, NEARLINE_STORAGE_CLASS, COLDLINE_STORAGE_CLASS, ARCHIVE_STORAGE_CLASS, + LR_STANDARD_ENTERPRISE_STORAGE_CLASS, MULTI_REGIONAL_LEGACY_STORAGE_CLASS, # legacy REGIONAL_LEGACY_STORAGE_CLASS, # legacy DURABLE_REDUCED_AVAILABILITY_LEGACY_STORAGE_CLASS, # legacy @@ -3081,6 +3085,8 @@ def storage_class(self): :attr:`~google.cloud.storage.constants.COLDLINE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.ARCHIVE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.STANDARD_STORAGE_CLASS`, + :attr:`~google.cloud.storage.constants.STANDARD_ENTERPRISE_STORAGE_CLASS`, + :attr:`~google.cloud.storage.constants.LR_STANDARD_ENTERPRISE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.MULTI_REGIONAL_LEGACY_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.REGIONAL_LEGACY_STORAGE_CLASS`, or @@ -3102,6 +3108,8 @@ def storage_class(self, value): :attr:`~google.cloud.storage.constants.COLDLINE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.ARCHIVE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.STANDARD_STORAGE_CLASS`, + :attr:`~google.cloud.storage.constants.STANDARD_ENTERPRISE_STORAGE_CLASS`, + :attr:`~google.cloud.storage.constants.LR_STANDARD_ENTERPRISE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.MULTI_REGIONAL_LEGACY_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.REGIONAL_LEGACY_STORAGE_CLASS`, or diff --git a/packages/google-cloud-storage/google/cloud/storage/constants.py b/packages/google-cloud-storage/google/cloud/storage/constants.py index c6c1b63c413e..14119c36dd26 100644 --- a/packages/google-cloud-storage/google/cloud/storage/constants.py +++ b/packages/google-cloud-storage/google/cloud/storage/constants.py @@ -27,6 +27,12 @@ See: https://cloud.google.com/storage/docs/storage-classes """ +STANDARD_ENTERPRISE_STORAGE_CLASS = "STANDARD_ENTERPRISE" +"""Enterprise storage class for standard storage. + +See: https://cloud.google.com/storage/docs/storage-classes +""" + NEARLINE_STORAGE_CLASS = "NEARLINE" """Storage class for objects accessed at most once per month. @@ -45,6 +51,12 @@ See: https://cloud.google.com/storage/docs/storage-classes """ +LR_STANDARD_ENTERPRISE_STORAGE_CLASS = "LR_STANDARD_ENTERPRISE" +"""Enterprise storage class for locally redundant standard storage. + +See: https://cloud.google.com/storage/docs/storage-classes +""" + MULTI_REGIONAL_LEGACY_STORAGE_CLASS = "MULTI_REGIONAL" """Legacy storage class. diff --git a/packages/google-cloud-storage/tests/system/test_blob.py b/packages/google-cloud-storage/tests/system/test_blob.py index e3b558f5b606..b028f9db8148 100644 --- a/packages/google-cloud-storage/tests/system/test_blob.py +++ b/packages/google-cloud-storage/tests/system/test_blob.py @@ -1212,6 +1212,40 @@ def test_blob_update_storage_class_large_file( assert blob.storage_class == constants.COLDLINE_STORAGE_CLASS +def test_blob_update_storage_class_enterprise( + storage_client, buckets_to_delete, blobs_to_delete, file_data +): + from google.cloud.storage import constants + + bucket_name = _helpers.unique_name("blob-ent-sc") + bucket = storage_client.bucket(bucket_name) + bucket.storage_class = constants.STANDARD_ENTERPRISE_STORAGE_CLASS + + try: + _helpers.retry_429_503(bucket.create)(location="us-central1") + except exceptions.BadRequest as exc: + if "is not allowed for project" in str( + exc + ) or "may not create storageClass" in str(exc): + pytest.skip(f"Project not allowlisted for enterprise storage class: {exc}") + raise + buckets_to_delete.append(bucket) + + blob = bucket.blob("EnterpriseSmallFile") + info = file_data["simple"] + blob.upload_from_filename(info["path"]) + blobs_to_delete.append(blob) + assert blob.storage_class == constants.STANDARD_ENTERPRISE_STORAGE_CLASS + + blob.update_storage_class(constants.LR_STANDARD_ENTERPRISE_STORAGE_CLASS) + blob.reload() + assert blob.storage_class == constants.LR_STANDARD_ENTERPRISE_STORAGE_CLASS + + blob.update_storage_class(constants.STANDARD_ENTERPRISE_STORAGE_CLASS) + blob.reload() + assert blob.storage_class == constants.STANDARD_ENTERPRISE_STORAGE_CLASS + + def test_object_retention_lock(storage_client, buckets_to_delete, blobs_to_delete): from google.cloud.storage._helpers import _NOW, _UTC diff --git a/packages/google-cloud-storage/tests/system/test_bucket.py b/packages/google-cloud-storage/tests/system/test_bucket.py index ae194fe46793..4b6323aa847e 100644 --- a/packages/google-cloud-storage/tests/system/test_bucket.py +++ b/packages/google-cloud-storage/tests/system/test_bucket.py @@ -49,6 +49,37 @@ def test_bucket_create_w_alt_storage_class(storage_client, buckets_to_delete): assert created.storage_class == constants.ARCHIVE_STORAGE_CLASS +def test_bucket_create_w_enterprise_storage_class(storage_client, buckets_to_delete): + from google.cloud.storage import constants + + for storage_class, suffix in ( + (constants.STANDARD_ENTERPRISE_STORAGE_CLASS, "std-ent"), + (constants.LR_STANDARD_ENTERPRISE_STORAGE_CLASS, "lr-std-ent"), + ): + bucket_name = _helpers.unique_name(f"bucket-w-{suffix}") + + with pytest.raises(exceptions.NotFound): + storage_client.get_bucket(bucket_name) + + bucket = storage_client.bucket(bucket_name) + bucket.storage_class = storage_class + + try: + _helpers.retry_429_503(bucket.create)(location="us-central1") + except exceptions.BadRequest as exc: + if "is not allowed for project" in str( + exc + ) or "may not create storageClass" in str(exc): + pytest.skip( + f"Project not allowlisted for enterprise storage class: {exc}" + ) + raise + buckets_to_delete.append(bucket) + + created = storage_client.get_bucket(bucket_name) + assert created.storage_class == storage_class + + def test_bucket_lifecycle_rules(storage_client, buckets_to_delete): from google.cloud.storage import constants from google.cloud.storage.bucket import ( diff --git a/packages/google-cloud-storage/tests/unit/test_blob.py b/packages/google-cloud-storage/tests/unit/test_blob.py index c5609e3dd5c6..fa8cb89cd0ca 100644 --- a/packages/google-cloud-storage/tests/unit/test_blob.py +++ b/packages/google-cloud-storage/tests/unit/test_blob.py @@ -6197,6 +6197,25 @@ def test_storage_class_setter(self): self.assertEqual(blob.storage_class, storage_class) self.assertEqual(blob._properties, {"storageClass": storage_class}) + def test_storage_class_enterprise_constants(self): + from google.cloud.storage.constants import ( + LR_STANDARD_ENTERPRISE_STORAGE_CLASS, + STANDARD_ENTERPRISE_STORAGE_CLASS, + ) + + blob_name = "blob-name" + bucket = _Bucket() + blob = self._make_one(blob_name, bucket=bucket) + self.assertIn(STANDARD_ENTERPRISE_STORAGE_CLASS, blob.STORAGE_CLASSES) + self.assertIn(LR_STANDARD_ENTERPRISE_STORAGE_CLASS, blob.STORAGE_CLASSES) + for storage_class in ( + STANDARD_ENTERPRISE_STORAGE_CLASS, + LR_STANDARD_ENTERPRISE_STORAGE_CLASS, + ): + blob.storage_class = storage_class + self.assertEqual(blob.storage_class, storage_class) + self.assertEqual(blob._properties, {"storageClass": storage_class}) + def test_temporary_hold_getter_missing(self): BLOB_NAME = "blob-name" bucket = _Bucket() diff --git a/packages/google-cloud-storage/tests/unit/test_bucket.py b/packages/google-cloud-storage/tests/unit/test_bucket.py index 19b3456b816e..33cb2fd49328 100644 --- a/packages/google-cloud-storage/tests/unit/test_bucket.py +++ b/packages/google-cloud-storage/tests/unit/test_bucket.py @@ -3279,6 +3279,26 @@ def test_storage_class_setter_STANDARD(self): self.assertEqual(bucket.storage_class, STANDARD_STORAGE_CLASS) self.assertTrue("storageClass" in bucket._changes) + def test_storage_class_setter_STANDARD_ENTERPRISE(self): + from google.cloud.storage.constants import STANDARD_ENTERPRISE_STORAGE_CLASS + + NAME = "name" + bucket = self._make_one(name=NAME) + self.assertIn(STANDARD_ENTERPRISE_STORAGE_CLASS, bucket.STORAGE_CLASSES) + bucket.storage_class = STANDARD_ENTERPRISE_STORAGE_CLASS + self.assertEqual(bucket.storage_class, STANDARD_ENTERPRISE_STORAGE_CLASS) + self.assertTrue("storageClass" in bucket._changes) + + def test_storage_class_setter_LR_STANDARD_ENTERPRISE(self): + from google.cloud.storage.constants import LR_STANDARD_ENTERPRISE_STORAGE_CLASS + + NAME = "name" + bucket = self._make_one(name=NAME) + self.assertIn(LR_STANDARD_ENTERPRISE_STORAGE_CLASS, bucket.STORAGE_CLASSES) + bucket.storage_class = LR_STANDARD_ENTERPRISE_STORAGE_CLASS + self.assertEqual(bucket.storage_class, LR_STANDARD_ENTERPRISE_STORAGE_CLASS) + self.assertTrue("storageClass" in bucket._changes) + def test_storage_class_setter_NEARLINE(self): from google.cloud.storage.constants import NEARLINE_STORAGE_CLASS From f3c5c500079eab531f7fe3c8a04ab35d79165802 Mon Sep 17 00:00:00 2001 From: Chandra Sirimala Date: Mon, 2 Nov 2026 13:29:28 +0000 Subject: [PATCH 2/4] feat(storage): add STANDARD_FLEXBACKUP_ENTERPRISE storage class --- .../google/cloud/storage/blob.py | 4 ++++ .../google/cloud/storage/bucket.py | 4 ++++ .../google/cloud/storage/constants.py | 6 ++++++ .../tests/system/test_bucket.py | 14 ++++++++++---- .../google-cloud-storage/tests/unit/test_blob.py | 5 +++++ .../tests/unit/test_bucket.py | 16 ++++++++++++++++ 6 files changed, 45 insertions(+), 4 deletions(-) diff --git a/packages/google-cloud-storage/google/cloud/storage/blob.py b/packages/google-cloud-storage/google/cloud/storage/blob.py index a40f46d1f230..28e13b955cd2 100644 --- a/packages/google-cloud-storage/google/cloud/storage/blob.py +++ b/packages/google-cloud-storage/google/cloud/storage/blob.py @@ -72,6 +72,7 @@ NEARLINE_STORAGE_CLASS, REGIONAL_LEGACY_STORAGE_CLASS, STANDARD_ENTERPRISE_STORAGE_CLASS, + STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS, STANDARD_STORAGE_CLASS, ) from google.cloud.storage.exceptions import DataCorruption, InvalidResponse @@ -194,6 +195,7 @@ class Blob(_PropertyMixin): STORAGE_CLASSES = ( STANDARD_STORAGE_CLASS, STANDARD_ENTERPRISE_STORAGE_CLASS, + STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS, NEARLINE_STORAGE_CLASS, COLDLINE_STORAGE_CLASS, ARCHIVE_STORAGE_CLASS, @@ -4244,6 +4246,7 @@ def update_storage_class( :attr:`~google.cloud.storage.constants.ARCHIVE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.STANDARD_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.STANDARD_ENTERPRISE_STORAGE_CLASS`, + :attr:`~google.cloud.storage.constants.STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.LR_STANDARD_ENTERPRISE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.MULTI_REGIONAL_LEGACY_STORAGE_CLASS`, or @@ -4964,6 +4967,7 @@ def kms_key_name(self, value): If set, one of :attr:`~google.cloud.storage.constants.STANDARD_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.STANDARD_ENTERPRISE_STORAGE_CLASS`, + :attr:`~google.cloud.storage.constants.STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.NEARLINE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.COLDLINE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.ARCHIVE_STORAGE_CLASS`, diff --git a/packages/google-cloud-storage/google/cloud/storage/bucket.py b/packages/google-cloud-storage/google/cloud/storage/bucket.py index 3f19e61faa6e..41d50e6881d9 100644 --- a/packages/google-cloud-storage/google/cloud/storage/bucket.py +++ b/packages/google-cloud-storage/google/cloud/storage/bucket.py @@ -58,6 +58,7 @@ REGION_LOCATION_TYPE, REGIONAL_LEGACY_STORAGE_CLASS, STANDARD_ENTERPRISE_STORAGE_CLASS, + STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS, STANDARD_STORAGE_CLASS, ) from google.cloud.storage.ip_filter import IPFilter @@ -653,6 +654,7 @@ class Bucket(_PropertyMixin): STORAGE_CLASSES = ( STANDARD_STORAGE_CLASS, STANDARD_ENTERPRISE_STORAGE_CLASS, + STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS, NEARLINE_STORAGE_CLASS, COLDLINE_STORAGE_CLASS, ARCHIVE_STORAGE_CLASS, @@ -3086,6 +3088,7 @@ def storage_class(self): :attr:`~google.cloud.storage.constants.ARCHIVE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.STANDARD_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.STANDARD_ENTERPRISE_STORAGE_CLASS`, + :attr:`~google.cloud.storage.constants.STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.LR_STANDARD_ENTERPRISE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.MULTI_REGIONAL_LEGACY_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.REGIONAL_LEGACY_STORAGE_CLASS`, @@ -3109,6 +3112,7 @@ def storage_class(self, value): :attr:`~google.cloud.storage.constants.ARCHIVE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.STANDARD_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.STANDARD_ENTERPRISE_STORAGE_CLASS`, + :attr:`~google.cloud.storage.constants.STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.LR_STANDARD_ENTERPRISE_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.MULTI_REGIONAL_LEGACY_STORAGE_CLASS`, :attr:`~google.cloud.storage.constants.REGIONAL_LEGACY_STORAGE_CLASS`, diff --git a/packages/google-cloud-storage/google/cloud/storage/constants.py b/packages/google-cloud-storage/google/cloud/storage/constants.py index 14119c36dd26..cecf8ddcd4b9 100644 --- a/packages/google-cloud-storage/google/cloud/storage/constants.py +++ b/packages/google-cloud-storage/google/cloud/storage/constants.py @@ -33,6 +33,12 @@ See: https://cloud.google.com/storage/docs/storage-classes """ +STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS = "STANDARD_FLEXBACKUP_ENTERPRISE" +"""Enterprise storage class for standard flexbackup storage. + +See: https://cloud.google.com/storage/docs/storage-classes +""" + NEARLINE_STORAGE_CLASS = "NEARLINE" """Storage class for objects accessed at most once per month. diff --git a/packages/google-cloud-storage/tests/system/test_bucket.py b/packages/google-cloud-storage/tests/system/test_bucket.py index 4b6323aa847e..e8cec3f2da4b 100644 --- a/packages/google-cloud-storage/tests/system/test_bucket.py +++ b/packages/google-cloud-storage/tests/system/test_bucket.py @@ -52,9 +52,10 @@ def test_bucket_create_w_alt_storage_class(storage_client, buckets_to_delete): def test_bucket_create_w_enterprise_storage_class(storage_client, buckets_to_delete): from google.cloud.storage import constants - for storage_class, suffix in ( - (constants.STANDARD_ENTERPRISE_STORAGE_CLASS, "std-ent"), - (constants.LR_STANDARD_ENTERPRISE_STORAGE_CLASS, "lr-std-ent"), + for storage_class, suffix, location in ( + (constants.STANDARD_ENTERPRISE_STORAGE_CLASS, "std-ent", "us-central1"), + (constants.LR_STANDARD_ENTERPRISE_STORAGE_CLASS, "lr-std-ent", "us-central1"), + (constants.STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS, "fb-ent", "us"), ): bucket_name = _helpers.unique_name(f"bucket-w-{suffix}") @@ -65,11 +66,16 @@ def test_bucket_create_w_enterprise_storage_class(storage_client, buckets_to_del bucket.storage_class = storage_class try: - _helpers.retry_429_503(bucket.create)(location="us-central1") + _helpers.retry_429_503(bucket.create)(location=location) except exceptions.BadRequest as exc: if "is not allowed for project" in str( exc ) or "may not create storageClass" in str(exc): + if ( + storage_class + == constants.STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS + ): + continue pytest.skip( f"Project not allowlisted for enterprise storage class: {exc}" ) diff --git a/packages/google-cloud-storage/tests/unit/test_blob.py b/packages/google-cloud-storage/tests/unit/test_blob.py index fa8cb89cd0ca..73844ccdc9e4 100644 --- a/packages/google-cloud-storage/tests/unit/test_blob.py +++ b/packages/google-cloud-storage/tests/unit/test_blob.py @@ -6201,15 +6201,20 @@ def test_storage_class_enterprise_constants(self): from google.cloud.storage.constants import ( LR_STANDARD_ENTERPRISE_STORAGE_CLASS, STANDARD_ENTERPRISE_STORAGE_CLASS, + STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS, ) blob_name = "blob-name" bucket = _Bucket() blob = self._make_one(blob_name, bucket=bucket) self.assertIn(STANDARD_ENTERPRISE_STORAGE_CLASS, blob.STORAGE_CLASSES) + self.assertIn( + STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS, blob.STORAGE_CLASSES + ) self.assertIn(LR_STANDARD_ENTERPRISE_STORAGE_CLASS, blob.STORAGE_CLASSES) for storage_class in ( STANDARD_ENTERPRISE_STORAGE_CLASS, + STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS, LR_STANDARD_ENTERPRISE_STORAGE_CLASS, ): blob.storage_class = storage_class diff --git a/packages/google-cloud-storage/tests/unit/test_bucket.py b/packages/google-cloud-storage/tests/unit/test_bucket.py index 33cb2fd49328..418db478a035 100644 --- a/packages/google-cloud-storage/tests/unit/test_bucket.py +++ b/packages/google-cloud-storage/tests/unit/test_bucket.py @@ -3289,6 +3289,22 @@ def test_storage_class_setter_STANDARD_ENTERPRISE(self): self.assertEqual(bucket.storage_class, STANDARD_ENTERPRISE_STORAGE_CLASS) self.assertTrue("storageClass" in bucket._changes) + def test_storage_class_setter_STANDARD_FLEXBACKUP_ENTERPRISE(self): + from google.cloud.storage.constants import ( + STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS, + ) + + NAME = "name" + bucket = self._make_one(name=NAME) + self.assertIn( + STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS, bucket.STORAGE_CLASSES + ) + bucket.storage_class = STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS + self.assertEqual( + bucket.storage_class, STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS + ) + self.assertTrue("storageClass" in bucket._changes) + def test_storage_class_setter_LR_STANDARD_ENTERPRISE(self): from google.cloud.storage.constants import LR_STANDARD_ENTERPRISE_STORAGE_CLASS From 41f139b6bf8d8d17c07e35925d9f1d2a61a56349 Mon Sep 17 00:00:00 2001 From: Chandra Sirimala Date: Mon, 2 Nov 2026 14:22:14 +0000 Subject: [PATCH 3/4] test(storage): use pytest.mark.parametrize for enterprise storage class tests --- .../tests/system/test_bucket.py | 71 ++++++++++--------- .../tests/unit/test_blob.py | 49 ++++++------- 2 files changed, 63 insertions(+), 57 deletions(-) diff --git a/packages/google-cloud-storage/tests/system/test_bucket.py b/packages/google-cloud-storage/tests/system/test_bucket.py index e8cec3f2da4b..815737415115 100644 --- a/packages/google-cloud-storage/tests/system/test_bucket.py +++ b/packages/google-cloud-storage/tests/system/test_bucket.py @@ -49,41 +49,46 @@ def test_bucket_create_w_alt_storage_class(storage_client, buckets_to_delete): assert created.storage_class == constants.ARCHIVE_STORAGE_CLASS -def test_bucket_create_w_enterprise_storage_class(storage_client, buckets_to_delete): +@pytest.mark.parametrize( + "storage_class,suffix,location", + [ + ("STANDARD_ENTERPRISE", "std-ent", "us-central1"), + ("LR_STANDARD_ENTERPRISE", "lr-std-ent", "us-central1"), + ("STANDARD_FLEXBACKUP_ENTERPRISE", "fb-ent", "us"), + ], +) +def test_bucket_create_w_enterprise_storage_class( + storage_client, buckets_to_delete, storage_class, suffix, location +): from google.cloud.storage import constants - for storage_class, suffix, location in ( - (constants.STANDARD_ENTERPRISE_STORAGE_CLASS, "std-ent", "us-central1"), - (constants.LR_STANDARD_ENTERPRISE_STORAGE_CLASS, "lr-std-ent", "us-central1"), - (constants.STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS, "fb-ent", "us"), - ): - bucket_name = _helpers.unique_name(f"bucket-w-{suffix}") - - with pytest.raises(exceptions.NotFound): - storage_client.get_bucket(bucket_name) - - bucket = storage_client.bucket(bucket_name) - bucket.storage_class = storage_class - - try: - _helpers.retry_429_503(bucket.create)(location=location) - except exceptions.BadRequest as exc: - if "is not allowed for project" in str( - exc - ) or "may not create storageClass" in str(exc): - if ( - storage_class - == constants.STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS - ): - continue - pytest.skip( - f"Project not allowlisted for enterprise storage class: {exc}" - ) - raise - buckets_to_delete.append(bucket) - - created = storage_client.get_bucket(bucket_name) - assert created.storage_class == storage_class + enterprise_constants = ( + constants.STANDARD_ENTERPRISE_STORAGE_CLASS, + constants.LR_STANDARD_ENTERPRISE_STORAGE_CLASS, + constants.STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS, + ) + assert storage_class in enterprise_constants + + bucket_name = _helpers.unique_name(f"bucket-w-{suffix}") + + with pytest.raises(exceptions.NotFound): + storage_client.get_bucket(bucket_name) + + bucket = storage_client.bucket(bucket_name) + bucket.storage_class = storage_class + + try: + _helpers.retry_429_503(bucket.create)(location=location) + except exceptions.BadRequest as exc: + if "is not allowed for project" in str( + exc + ) or "may not create storageClass" in str(exc): + pytest.skip(f"Project not allowlisted for enterprise storage class: {exc}") + raise + buckets_to_delete.append(bucket) + + created = storage_client.get_bucket(bucket_name) + assert created.storage_class == storage_class def test_bucket_lifecycle_rules(storage_client, buckets_to_delete): diff --git a/packages/google-cloud-storage/tests/unit/test_blob.py b/packages/google-cloud-storage/tests/unit/test_blob.py index 73844ccdc9e4..62d3f3a3ebd2 100644 --- a/packages/google-cloud-storage/tests/unit/test_blob.py +++ b/packages/google-cloud-storage/tests/unit/test_blob.py @@ -6197,30 +6197,6 @@ def test_storage_class_setter(self): self.assertEqual(blob.storage_class, storage_class) self.assertEqual(blob._properties, {"storageClass": storage_class}) - def test_storage_class_enterprise_constants(self): - from google.cloud.storage.constants import ( - LR_STANDARD_ENTERPRISE_STORAGE_CLASS, - STANDARD_ENTERPRISE_STORAGE_CLASS, - STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS, - ) - - blob_name = "blob-name" - bucket = _Bucket() - blob = self._make_one(blob_name, bucket=bucket) - self.assertIn(STANDARD_ENTERPRISE_STORAGE_CLASS, blob.STORAGE_CLASSES) - self.assertIn( - STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS, blob.STORAGE_CLASSES - ) - self.assertIn(LR_STANDARD_ENTERPRISE_STORAGE_CLASS, blob.STORAGE_CLASSES) - for storage_class in ( - STANDARD_ENTERPRISE_STORAGE_CLASS, - STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS, - LR_STANDARD_ENTERPRISE_STORAGE_CLASS, - ): - blob.storage_class = storage_class - self.assertEqual(blob.storage_class, storage_class) - self.assertEqual(blob._properties, {"storageClass": storage_class}) - def test_temporary_hold_getter_missing(self): BLOB_NAME = "blob-name" bucket = _Bucket() @@ -6812,6 +6788,31 @@ def test_w_existing_qs(self): self.assertEqual(self._call_fut(BASE_URL, NV_LIST), f"{BASE_URL}&{expected}") +@pytest.mark.parametrize( + "constant_name,expected_value", + [ + ("STANDARD_ENTERPRISE_STORAGE_CLASS", "STANDARD_ENTERPRISE"), + ( + "STANDARD_FLEXBACKUP_ENTERPRISE_STORAGE_CLASS", + "STANDARD_FLEXBACKUP_ENTERPRISE", + ), + ("LR_STANDARD_ENTERPRISE_STORAGE_CLASS", "LR_STANDARD_ENTERPRISE"), + ], +) +def test_blob_storage_class_enterprise_constants(constant_name, expected_value): + from google.cloud.storage import constants + from google.cloud.storage.blob import Blob + + storage_class = getattr(constants, constant_name) + assert storage_class == expected_value + bucket = _Bucket() + blob = Blob("blob-name", bucket=bucket) + assert storage_class in blob.STORAGE_CLASSES + blob.storage_class = storage_class + assert blob.storage_class == storage_class + assert blob._properties == {"storageClass": storage_class} + + class _Connection(object): API_BASE_URL = "http://example.com" USER_AGENT = "testing 1.2.3" From b5d1ec857e4efbe943886d1676a70be5e5898359 Mon Sep 17 00:00:00 2001 From: Chandra Sirimala Date: Tue, 3 Nov 2026 05:35:20 +0000 Subject: [PATCH 4/4] test(storage): remove pytest.skip from enterprise storage class system tests --- packages/google-cloud-storage/tests/system/test_blob.py | 9 +-------- .../google-cloud-storage/tests/system/test_bucket.py | 9 +-------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/packages/google-cloud-storage/tests/system/test_blob.py b/packages/google-cloud-storage/tests/system/test_blob.py index b028f9db8148..b284673ed577 100644 --- a/packages/google-cloud-storage/tests/system/test_blob.py +++ b/packages/google-cloud-storage/tests/system/test_blob.py @@ -1221,14 +1221,7 @@ def test_blob_update_storage_class_enterprise( bucket = storage_client.bucket(bucket_name) bucket.storage_class = constants.STANDARD_ENTERPRISE_STORAGE_CLASS - try: - _helpers.retry_429_503(bucket.create)(location="us-central1") - except exceptions.BadRequest as exc: - if "is not allowed for project" in str( - exc - ) or "may not create storageClass" in str(exc): - pytest.skip(f"Project not allowlisted for enterprise storage class: {exc}") - raise + _helpers.retry_429_503(bucket.create)(location="us-central1") buckets_to_delete.append(bucket) blob = bucket.blob("EnterpriseSmallFile") diff --git a/packages/google-cloud-storage/tests/system/test_bucket.py b/packages/google-cloud-storage/tests/system/test_bucket.py index 815737415115..e9c4bb5d392b 100644 --- a/packages/google-cloud-storage/tests/system/test_bucket.py +++ b/packages/google-cloud-storage/tests/system/test_bucket.py @@ -77,14 +77,7 @@ def test_bucket_create_w_enterprise_storage_class( bucket = storage_client.bucket(bucket_name) bucket.storage_class = storage_class - try: - _helpers.retry_429_503(bucket.create)(location=location) - except exceptions.BadRequest as exc: - if "is not allowed for project" in str( - exc - ) or "may not create storageClass" in str(exc): - pytest.skip(f"Project not allowlisted for enterprise storage class: {exc}") - raise + _helpers.retry_429_503(bucket.create)(location=location) buckets_to_delete.append(bucket) created = storage_client.get_bucket(bucket_name)