Skip to content

Commit 28fae54

Browse files
Add BucketTrackingMixin class for tracking buckets created by B2Api instances
1 parent 96aa9ea commit 28fae54

File tree

4 files changed

+53
-4
lines changed

4 files changed

+53
-4
lines changed

Diff for: CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
* Logging performance summary of parallel download threads
1313
* Add `max_download_streams_per_file` parameter to B2Api class and underlying structures
1414
* Add `is_file_lock_enabled` parameter to `Bucket.update()` and related methods
15+
* Add `BucketTrackingMixin` class for tracking buckets created by `B2Api` instances
1516

1617
### Fixed
1718
* Replace `ReplicationScanResult.source_has_sse_c_enabled` with `source_encryption_mode`

Diff for: b2sdk/_v3/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
# core
1515

16-
from b2sdk.api import B2Api
16+
from b2sdk.api import B2Api, BucketTrackingMixin
1717
from b2sdk.api import Services
1818
from b2sdk.bucket import Bucket
1919
from b2sdk.bucket import BucketFactory

Diff for: b2sdk/api.py

+23
Original file line numberDiff line numberDiff line change
@@ -595,3 +595,26 @@ def _check_bucket_restrictions(self, key, value):
595595
if allowed_bucket_identifier is not None:
596596
if allowed_bucket_identifier != value:
597597
raise RestrictedBucket(allowed_bucket_identifier)
598+
599+
600+
class BucketTrackingMixin:
601+
"""
602+
Mixin class for B2Api, which enables bucket tracking.
603+
604+
This mixin will add a `buckets` member to the B2Api instance and will use it track created and
605+
deleted buckets. The main purpose of this are tests -- the `buckets` member can be used in test
606+
teardown to ensure proper bucket cleanup.
607+
"""
608+
609+
def __init__(self, *args, **kwargs):
610+
self.buckets = []
611+
super().__init__(*args, **kwargs)
612+
613+
def create_bucket(self, name, *args, **kwargs):
614+
bucket = super().create_bucket(name, *args, **kwargs)
615+
self.buckets.append(bucket)
616+
return bucket
617+
618+
def delete_bucket(self, bucket):
619+
super().delete_bucket(bucket)
620+
self.buckets = [b for b in self.buckets if b.id_ != bucket.id_]

Diff for: test/unit/v_all/test_api.py

+28-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
import pytest
1212

13-
from apiver_deps import B2Api
13+
from apiver_deps import B2Api, BucketTrackingMixin
1414
from apiver_deps import B2HttpApiConfig
1515
from apiver_deps import Bucket
1616
from apiver_deps import InMemoryCache
@@ -102,11 +102,13 @@ def test_api_initialization(self, kwargs, _raw_api_class):
102102
assert download_manager.strategies[0].max_streams == kwargs['max_download_streams_per_file']
103103

104104

105-
class TestApi(TestBase):
105+
class TestApiBase(TestBase):
106+
B2_API_CLASS = B2Api
107+
106108
def setUp(self):
107109
self.account_info = InMemoryAccountInfo()
108110
self.cache = InMemoryCache()
109-
self.api = B2Api(
111+
self.api = self.B2_API_CLASS(
110112
self.account_info, self.cache, api_config=B2HttpApiConfig(_raw_api_class=RawSimulator)
111113
)
112114
self.raw_api = self.api.session.raw_api
@@ -115,6 +117,8 @@ def setUp(self):
115117
def _authorize_account(self):
116118
self.api.authorize_account('production', self.application_key_id, self.master_key)
117119

120+
121+
class TestApi(TestApiBase):
118122
@pytest.mark.apiver(to_ver=1)
119123
def test_get_bucket_by_id_up_to_v1(self):
120124
bucket = self.api.get_bucket_by_id("this id doesn't even exist")
@@ -158,3 +162,24 @@ def test_get_download_url_for_fileid(self):
158162
download_url = self.api.get_download_url_for_fileid('file-id')
159163

160164
assert download_url == 'http://download.example.com/b2api/v2/b2_download_file_by_id?fileId=file-id'
165+
166+
167+
class TestBucketTrackingMixin(TestApiBase):
168+
class BucketTrackingApi(BucketTrackingMixin, B2Api):
169+
pass
170+
171+
B2_API_CLASS = BucketTrackingApi
172+
173+
def test_bucket_tracking(self):
174+
self._authorize_account()
175+
176+
bucket_1, bucket_2, bucket_3 = [
177+
self.api.create_bucket(f'bucket-{i + 1}', 'allPrivate') for i in range(3)
178+
]
179+
180+
self.api.delete_bucket(bucket_2)
181+
self.api.delete_bucket(bucket_3)
182+
183+
bucket_4 = self.api.create_bucket('bucket-4', 'allPrivate')
184+
185+
assert {bucket.id_ for bucket in self.api.buckets} == {bucket_1.id_, bucket_4.id_}

0 commit comments

Comments
 (0)