Skip to content

Commit 3899df8

Browse files
PYCBC-1712: Use server default for replicaNumber when creating bucket
Changes ======= - Change num_replicas default from 0 to None in CreateBucketSettings - When num_replicas is unspecified, SDK now defers to server default (typically 1 replica) - Add check_multi_node fixture to bucket management tests to skip on single-node clusters - Add test_bucket_create_zero_replicas test that explicitly sets num_replicas=0 for single-node coverage - Apply same changes to acouchbase and txcouchbase test suites This is a breaking change from the perspective that buckets created without specifying num_replicas will now have 1 replica (server default) instead of 0. Change-Id: Idf3ae4b78b478fa4d52c30019081947bec79a5ac Reviewed-on: https://review.couchbase.org/c/couchbase-python-client/+/238229 Tested-by: Build Bot <build@couchbase.com> Reviewed-by: Jared Casey <jared.casey@couchbase.com>
1 parent 3a99496 commit 3899df8

File tree

4 files changed

+131
-6
lines changed

4 files changed

+131
-6
lines changed

acouchbase/tests/bucketmgmt_t.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,15 @@ def check_custom_conflict_resolution_supported(self, cb_env):
7878
def check_non_deduped_history_supported(self, cb_env):
7979
cb_env.check_if_feature_supported('non_deduped_history')
8080

81+
@pytest.fixture(scope="class")
82+
def num_nodes(self, cb_env):
83+
return len(cb_env.cluster._cluster_info.nodes)
84+
85+
@pytest.fixture(scope="class")
86+
def check_multi_node(self, num_nodes):
87+
if num_nodes == 1:
88+
pytest.skip("Test only for clusters with more than a single node.")
89+
8190
@pytest.fixture()
8291
def test_bucket(self, test_buckets):
8392
return choice(test_buckets)
@@ -97,6 +106,7 @@ async def purge_buckets(self, cb_env, test_buckets):
97106
await cb_env.purge_buckets(test_buckets)
98107

99108
@pytest.mark.usefixtures("check_bucket_mgmt_supported")
109+
@pytest.mark.usefixtures("check_multi_node")
100110
@pytest.mark.usefixtures("purge_buckets")
101111
@pytest.mark.asyncio
102112
async def test_bucket_create(self, cb_env, test_bucket):
@@ -112,6 +122,20 @@ async def test_bucket_create(self, cb_env, test_bucket):
112122
@pytest.mark.usefixtures("check_bucket_mgmt_supported")
113123
@pytest.mark.usefixtures("purge_buckets")
114124
@pytest.mark.asyncio
125+
async def test_bucket_create_zero_replicas(self, cb_env, test_bucket):
126+
await cb_env.bm.create_bucket(
127+
CreateBucketSettings(
128+
name=test_bucket,
129+
bucket_type=BucketType.COUCHBASE,
130+
ram_quota_mb=100,
131+
num_replicas=0))
132+
bucket = await cb_env.try_n_times(10, 1, cb_env.bm.get_bucket, test_bucket)
133+
assert bucket.get("num_replicas") == 0
134+
135+
@pytest.mark.usefixtures("check_bucket_mgmt_supported")
136+
@pytest.mark.usefixtures("check_multi_node")
137+
@pytest.mark.usefixtures("purge_buckets")
138+
@pytest.mark.asyncio
115139
async def test_bucket_create_replica_index_true(self, cb_env, test_bucket):
116140
await cb_env.bm.create_bucket(
117141
CreateBucketSettings(
@@ -124,6 +148,7 @@ async def test_bucket_create_replica_index_true(self, cb_env, test_bucket):
124148
assert bucket.replica_index is True
125149

126150
@pytest.mark.usefixtures("check_bucket_mgmt_supported")
151+
@pytest.mark.usefixtures("check_multi_node")
127152
@pytest.mark.usefixtures("purge_buckets")
128153
@pytest.mark.asyncio
129154
async def test_bucket_create_replica_index_false(self, cb_env, test_bucket):
@@ -138,6 +163,7 @@ async def test_bucket_create_replica_index_false(self, cb_env, test_bucket):
138163
assert bucket.replica_index is False
139164

140165
@pytest.mark.usefixtures("check_bucket_min_durability_supported")
166+
@pytest.mark.usefixtures("check_multi_node")
141167
@pytest.mark.usefixtures("purge_buckets")
142168
@pytest.mark.asyncio
143169
async def test_bucket_create_durability(self, cb_env, test_bucket):
@@ -150,6 +176,7 @@ async def test_bucket_create_durability(self, cb_env, test_bucket):
150176
assert bucket["minimum_durability_level"] == min_durability
151177

152178
@pytest.mark.usefixtures("check_bucket_mgmt_supported")
179+
@pytest.mark.usefixtures("check_multi_node")
153180
@pytest.mark.usefixtures("purge_buckets")
154181
@pytest.mark.asyncio
155182
async def test_bucket_create_fail(self, cb_env, test_bucket):
@@ -162,6 +189,7 @@ async def test_bucket_create_fail(self, cb_env, test_bucket):
162189
await cb_env.bm.create_bucket(settings)
163190

164191
@pytest.mark.usefixtures("check_bucket_mgmt_supported")
192+
@pytest.mark.usefixtures("check_multi_node")
165193
@pytest.mark.asyncio
166194
async def test_bucket_drop_fail(self, cb_env, test_bucket):
167195
settings = CreateBucketSettings(
@@ -174,6 +202,7 @@ async def test_bucket_drop_fail(self, cb_env, test_bucket):
174202
await cb_env.bm.drop_bucket(test_bucket)
175203

176204
@pytest.mark.usefixtures("check_bucket_mgmt_supported")
205+
@pytest.mark.usefixtures("check_multi_node")
177206
@pytest.mark.usefixtures("purge_buckets")
178207
@pytest.mark.asyncio
179208
async def test_bucket_list(self, cb_env, test_buckets):
@@ -189,6 +218,7 @@ async def test_bucket_list(self, cb_env, test_buckets):
189218
set(map(lambda b: b.name, buckets)))
190219

191220
@pytest.mark.usefixtures("check_bucket_mgmt_supported")
221+
@pytest.mark.usefixtures("check_multi_node")
192222
@pytest.mark.usefixtures("purge_buckets")
193223
@pytest.mark.asyncio
194224
async def test_cluster_sees_bucket(self, cb_env, test_bucket):
@@ -203,6 +233,7 @@ async def test_cluster_sees_bucket(self, cb_env, test_bucket):
203233
await cb_env.try_n_times(10, 1, b.on_connect)
204234

205235
@pytest.mark.usefixtures("check_bucket_mgmt_supported")
236+
@pytest.mark.usefixtures("check_multi_node")
206237
@pytest.mark.usefixtures("purge_buckets")
207238
@pytest.mark.asyncio
208239
async def test_change_expiry(self, cb_env, test_bucket):
@@ -226,6 +257,7 @@ async def get_bucket_expiry_equal(name, expiry):
226257
await cb_env.try_n_times(10, 3, get_bucket_expiry_equal, test_bucket, timedelta(seconds=500))
227258

228259
@pytest.mark.usefixtures("check_bucket_mgmt_supported")
260+
@pytest.mark.usefixtures("check_multi_node")
229261
@pytest.mark.usefixtures("purge_buckets")
230262
@pytest.mark.asyncio
231263
async def test_bucket_flush(self, cb_env, test_bucket):
@@ -241,6 +273,7 @@ async def test_bucket_flush(self, cb_env, test_bucket):
241273
await cb_env.try_n_times(10, 3, cb_env.bm.flush_bucket, bucket.name)
242274

243275
@pytest.mark.usefixtures("check_bucket_mgmt_supported")
276+
@pytest.mark.usefixtures("check_multi_node")
244277
@pytest.mark.usefixtures("purge_buckets")
245278
@pytest.mark.asyncio
246279
async def test_bucket_flush_fail(self, cb_env, test_bucket):
@@ -257,6 +290,7 @@ async def test_bucket_flush_fail(self, cb_env, test_bucket):
257290
await cb_env.bm.flush_bucket(test_bucket)
258291

259292
@pytest.mark.usefixtures("check_bucket_storage_backend_supported")
293+
@pytest.mark.usefixtures("check_multi_node")
260294
@pytest.mark.usefixtures("purge_buckets")
261295
@pytest.mark.asyncio
262296
async def test_bucket_backend_default(self, cb_env, test_bucket):
@@ -273,6 +307,7 @@ async def test_bucket_backend_default(self, cb_env, test_bucket):
273307
assert bucket.storage_backend == StorageBackend.COUCHSTORE
274308

275309
@pytest.mark.usefixtures("check_bucket_storage_backend_supported")
310+
@pytest.mark.usefixtures("check_multi_node")
276311
@pytest.mark.usefixtures("purge_buckets")
277312
@pytest.mark.asyncio
278313
async def test_bucket_backend_magma(self, cb_env, test_bucket):
@@ -287,6 +322,7 @@ async def test_bucket_backend_magma(self, cb_env, test_bucket):
287322
assert bucket.storage_backend == StorageBackend.MAGMA
288323

289324
@pytest.mark.usefixtures("check_bucket_storage_backend_supported")
325+
@pytest.mark.usefixtures("check_multi_node")
290326
@pytest.mark.usefixtures("purge_buckets")
291327
@pytest.mark.asyncio
292328
async def test_bucket_backend_couchstore(self, cb_env, test_bucket):
@@ -301,6 +337,7 @@ async def test_bucket_backend_couchstore(self, cb_env, test_bucket):
301337
assert bucket.storage_backend == StorageBackend.COUCHSTORE
302338

303339
@pytest.mark.usefixtures("check_bucket_storage_backend_supported")
340+
@pytest.mark.usefixtures("check_multi_node")
304341
@pytest.mark.usefixtures("purge_buckets")
305342
@pytest.mark.asyncio
306343
async def test_bucket_backend_ephemeral(self, cb_env, test_bucket):
@@ -315,6 +352,7 @@ async def test_bucket_backend_ephemeral(self, cb_env, test_bucket):
315352
assert bucket.storage_backend == StorageBackend.UNDEFINED
316353

317354
@pytest.mark.usefixtures("check_custom_conflict_resolution_supported")
355+
@pytest.mark.usefixtures("check_multi_node")
318356
@pytest.mark.usefixtures("purge_buckets")
319357
@pytest.mark.asyncio
320358
async def test_bucket_custom_conflict_resolution(self, cb_env, test_bucket):
@@ -338,6 +376,7 @@ async def test_bucket_custom_conflict_resolution(self, cb_env, test_bucket):
338376
flush_enabled=False))
339377

340378
@pytest.mark.usefixtures("check_non_deduped_history_supported")
379+
@pytest.mark.usefixtures("check_multi_node")
341380
@pytest.mark.usefixtures("purge_buckets")
342381
@pytest.mark.asyncio
343382
async def test_bucket_create_history_retention(self, cb_env, test_bucket):
@@ -358,6 +397,7 @@ async def test_bucket_create_history_retention(self, cb_env, test_bucket):
358397
assert bucket.history_retention_duration == timedelta(days=1)
359398

360399
@pytest.mark.usefixtures("check_non_deduped_history_supported")
400+
@pytest.mark.usefixtures("check_multi_node")
361401
@pytest.mark.usefixtures("purge_buckets")
362402
@pytest.mark.asyncio
363403
async def test_bucket_create_history_retention_unsupported(self, cb_env, test_bucket):
@@ -375,6 +415,7 @@ async def test_bucket_create_history_retention_unsupported(self, cb_env, test_bu
375415
)
376416

377417
@pytest.mark.usefixtures("check_non_deduped_history_supported")
418+
@pytest.mark.usefixtures("check_multi_node")
378419
@pytest.mark.usefixtures("purge_buckets")
379420
@pytest.mark.asyncio
380421
async def test_bucket_update_history_retention(self, cb_env, test_bucket):
@@ -409,6 +450,7 @@ async def test_bucket_update_history_retention(self, cb_env, test_bucket):
409450
assert bucket.history_retention_duration == timedelta(minutes=10)
410451

411452
@pytest.mark.usefixtures("check_non_deduped_history_supported")
453+
@pytest.mark.usefixtures("check_multi_node")
412454
@pytest.mark.usefixtures("purge_buckets")
413455
@pytest.mark.asyncio
414456
async def test_bucket_update_history_retention_unsupported(self, cb_env, test_bucket):

couchbase/management/logic/buckets_logic.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,7 @@ class BucketSettings(dict):
350350
ParamTransform("flushEnabled", Identity(bool))),
351351
BidirectionalTransform("num_replicas",
352352
ParamTransform("numReplicas", Identity(int)),
353-
ParamTransform("numReplicas", Identity(int)),
354-
default=0),
353+
ParamTransform("numReplicas", Identity(int))),
355354
BidirectionalTransform("ram_quota_mb",
356355
ParamTransform("ramQuotaMB", Identity(int)),
357356
ParamTransform("ramQuotaMB", Identity(int))),
@@ -418,7 +417,7 @@ def __init__(self,
418417
name=None, # type: str
419418
flush_enabled=None, # type: bool
420419
ram_quota_mb=None, # type: int
421-
num_replicas=0, # type: int
420+
num_replicas=None, # type: Optional[int]
422421
replica_index=None, # type: bool
423422
bucket_type=None, # type: BucketType
424423
eviction_policy=None, # type: EvictionPolicyType
@@ -458,7 +457,7 @@ def flush_enabled(self) -> bool:
458457

459458
@property
460459
def num_replicas(self):
461-
# type: (...) -> int
460+
# type: (...) -> Optional[int]
462461
"""NumReplicas (int) - The number of replicas for documents."""
463462
return self.get('replica_number')
464463

@@ -572,7 +571,7 @@ def __init__(self, # nosec
572571
name=None, # type: str
573572
flush_enabled=False, # type: bool
574573
ram_quota_mb=None, # type: int
575-
num_replicas=0, # type: int
574+
num_replicas=None, # type: Optional[int]
576575
replica_index=None, # type: bool
577576
bucket_type=None, # type: BucketType
578577
eviction_policy=None, # type: EvictionPolicyType
@@ -594,7 +593,8 @@ def __init__(self, # nosec
594593
:param name: name of the bucket
595594
:param flush_enabled: whether flush is enabled
596595
:param ram_quota_mb: raw quota in megabytes
597-
:param num_replicas: number of replicas
596+
:param num_replicas: number of replicas. If not specified (None), the server's default
597+
replica count will be used (typically 1).
598598
:param replica_index: whether this is a replica index
599599
:param bucket_type: type of bucket
600600
:param eviction_policy: policy for eviction

0 commit comments

Comments
 (0)