Skip to content

Commit 998e46b

Browse files
Add BucketTrackingMixin class for tracking buckets created by B2Api instances
1 parent 2339a81 commit 998e46b

File tree

4 files changed

+53
-4
lines changed

4 files changed

+53
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
* Additional tests for listing files/versions
1515
* Ensured that changelog validation only happens on pull requests
1616
* Upgraded GitHub actions checkout to v3, python-setup to v4
17+
* Add `BucketTrackingMixin` class for tracking buckets created by `B2Api` instances
1718

1819
## [1.18.0] - 2022-09-20
1920

b2sdk/_v3/__init__.py

Lines changed: 1 addition & 1 deletion
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

b2sdk/api.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,3 +617,26 @@ def _populate_bucket_cache_from_key(self):
617617
raise RestrictedBucketMissing()
618618

619619
self.cache.save_bucket(self.BUCKET_CLASS(self, allowed_bucket_id, name=allowed_bucket_name))
620+
621+
622+
class BucketTrackingMixin:
623+
"""
624+
Mixin class for B2Api, which enables bucket tracking.
625+
626+
This mixin will add a `buckets` member to the B2Api instance and will use it track created and
627+
deleted buckets. The main purpose of this are tests -- the `buckets` member can be used in test
628+
teardown to ensure proper bucket cleanup.
629+
"""
630+
631+
def __init__(self, *args, **kwargs):
632+
self.buckets = []
633+
super().__init__(*args, **kwargs)
634+
635+
def create_bucket(self, name, *args, **kwargs):
636+
bucket = super().create_bucket(name, *args, **kwargs)
637+
self.buckets.append(bucket)
638+
return bucket
639+
640+
def delete_bucket(self, bucket):
641+
super().delete_bucket(bucket)
642+
self.buckets = [b for b in self.buckets if b.id_ != bucket.id_]

test/unit/v_all/test_api.py

Lines changed: 28 additions & 3 deletions
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)