Skip to content

Commit cfadc54

Browse files
committed
test(smoke): wait for namespace visibility after create_namespace
create_namespace returns synchronously, but describe_namespace and the list_namespaces variants briefly return 404 against the just-created namespace while metadata propagates to the read path. The dense-sync and dense-async smoke tests called describe_namespace immediately after create and consistently failed with `pinecone.errors.exceptions.NotFoundError: [404] No namespace: 'smoke-gamma'`, making them unusable as a release-readiness gate. Add wait_for_namespace_visible / async_wait_for_namespace_visible helpers (30s timeout, 1s interval) that retry describe_namespace until it succeeds, then raise TimeoutError if the namespace never becomes visible. Wrap the failing describe call in both tests with these helpers — wait briefly for consistency, but never block the suite indefinitely.
1 parent ae44bf8 commit cfadc54

3 files changed

Lines changed: 67 additions & 4 deletions

File tree

‎tests/smoke/helpers.py‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from pinecone.async_client.async_index import AsyncIndex
2626
from pinecone.grpc import GrpcIndex
2727
from pinecone.index import Index
28+
from pinecone.models.namespaces.models import NamespaceDescription
2829

2930

3031
# ---------------------------------------------------------------------------
@@ -99,6 +100,64 @@ async def async_wait_for_vector_count(
99100
)
100101

101102

103+
# ---------------------------------------------------------------------------
104+
# Namespace visibility polling
105+
# ---------------------------------------------------------------------------
106+
#
107+
# create_namespace returns synchronously, but describe/list calls against the
108+
# new namespace can briefly return 404 while the metadata propagates to the
109+
# read path. These helpers retry describe_namespace until it succeeds or a
110+
# bounded timeout expires — never block the suite indefinitely.
111+
112+
113+
def wait_for_namespace_visible(
114+
idx: Index,
115+
name: str,
116+
*,
117+
timeout: int = 30,
118+
interval: int = 1,
119+
) -> NamespaceDescription:
120+
"""Poll ``describe_namespace`` until it returns successfully.
121+
122+
Returns the ``NamespaceDescription`` from the first successful call. Raises
123+
:class:`TimeoutError` if the namespace is not visible within ``timeout``.
124+
"""
125+
start = time.monotonic()
126+
last_exc: Exception | None = None
127+
while time.monotonic() - start < timeout:
128+
try:
129+
return idx.describe_namespace(name=name)
130+
except Exception as exc:
131+
last_exc = exc
132+
time.sleep(interval)
133+
raise TimeoutError(
134+
f"Namespace {name!r} not visible to describe_namespace within "
135+
f"{timeout}s (last error: {last_exc!r})"
136+
)
137+
138+
139+
async def async_wait_for_namespace_visible(
140+
idx: AsyncIndex,
141+
name: str,
142+
*,
143+
timeout: int = 30,
144+
interval: int = 1,
145+
) -> NamespaceDescription:
146+
"""Async version of :func:`wait_for_namespace_visible`."""
147+
start = time.monotonic()
148+
last_exc: Exception | None = None
149+
while time.monotonic() - start < timeout:
150+
try:
151+
return await idx.describe_namespace(name=name)
152+
except Exception as exc:
153+
last_exc = exc
154+
await asyncio.sleep(interval)
155+
raise TimeoutError(
156+
f"Namespace {name!r} not visible to describe_namespace within "
157+
f"{timeout}s (last error: {last_exc!r})"
158+
)
159+
160+
102161
# ---------------------------------------------------------------------------
103162
# Pod-index warmup polling
104163
# ---------------------------------------------------------------------------

‎tests/smoke/test_serverless_dense_async.py‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
async_ensure_index_deleted,
2222
unique_name,
2323
)
24-
from tests.smoke.helpers import async_wait_for_vector_count
24+
from tests.smoke.helpers import async_wait_for_namespace_visible, async_wait_for_vector_count
2525

2626
CLOUD = "aws"
2727
REGION = "us-east-1"
@@ -149,7 +149,9 @@ async def test_serverless_dense_smoke_async(api_key: str) -> None:
149149
ns_name = "smoke-gamma-async"
150150
created_ns = await idx.create_namespace(name=ns_name)
151151
assert created_ns.name == ns_name
152-
described_ns = await idx.describe_namespace(name=ns_name)
152+
# describe/list briefly return 404 after create_namespace returns
153+
# 200 — wait for visibility before asserting.
154+
described_ns = await async_wait_for_namespace_visible(idx, ns_name)
153155
assert described_ns.name == ns_name
154156
ns_page = await idx.list_namespaces_paginated(limit=10)
155157
ns_names = {ns.name for ns in ns_page.namespaces}

‎tests/smoke/test_serverless_dense_sync.py‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
ensure_index_deleted,
2828
unique_name,
2929
)
30-
from tests.smoke.helpers import wait_for_vector_count
30+
from tests.smoke.helpers import wait_for_namespace_visible, wait_for_vector_count
3131

3232
CLOUD = "aws"
3333
REGION = "us-east-1"
@@ -166,7 +166,9 @@ def test_serverless_dense_smoke(client: Pinecone) -> None:
166166
ns_name = "smoke-gamma"
167167
created_ns = idx.create_namespace(name=ns_name)
168168
assert created_ns.name == ns_name
169-
described_ns = idx.describe_namespace(name=ns_name)
169+
# describe/list briefly return 404 after create_namespace returns
170+
# 200 — wait for visibility before asserting.
171+
described_ns = wait_for_namespace_visible(idx, ns_name)
170172
assert described_ns.name == ns_name
171173
ns_page = idx.list_namespaces_paginated(limit=10)
172174
ns_names = {ns.name for ns in ns_page.namespaces}

0 commit comments

Comments
 (0)