Skip to content

Commit c13a249

Browse files
authored
[Chore] Put date into test index and collection names (#399)
## Problem Sometimes indexes and collections aren't cleaned up properly after tests run. It's difficult to clean up orphaned resources without potentially impacting resources associated with tests that are currently running. ## Solution Modify generated names to include a timestamp. This will pave the way for automatically deleting orphaned resources after a certain period of time. ## Type of Change - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] This change requires a documentation update - [x] Infrastructure change (CI configs, etc) - [ ] Non-code change (docs, etc) - [ ] None of the above: (explain here) ## Test Plan Describe specific steps for validating this change.
1 parent 2389e1f commit c13a249

File tree

8 files changed

+74
-41
lines changed

8 files changed

+74
-41
lines changed

.github/workflows/lint.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: "Lint"
2-
on: [push, pull_request]
2+
on: [pull_request]
33

44
jobs:
55
lint:

scripts/create.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import os
2+
import re
23
import random
34
import string
5+
from datetime import datetime
46
from pinecone import Pinecone
57

68

@@ -20,9 +22,44 @@ def write_gh_output(name, value):
2022
print(f"{name}={value}", file=fh)
2123

2224

25+
def generate_index_name(test_name: str) -> str:
26+
github_actor = os.getenv("GITHUB_ACTOR", None)
27+
user = os.getenv("USER", None)
28+
index_owner = github_actor or user
29+
30+
formatted_date = datetime.now().strftime("%Y%m%d-%H%M%S%f")[:-3]
31+
32+
github_job = os.getenv("GITHUB_JOB", None)
33+
34+
if test_name.startswith("test_"):
35+
test_name = test_name[5:]
36+
37+
# Remove trailing underscore, if any
38+
if test_name.endswith("_"):
39+
test_name = test_name[:-1]
40+
41+
name_parts = [index_owner, formatted_date, github_job, test_name]
42+
index_name = "-".join([x for x in name_parts if x is not None])
43+
44+
# Remove invalid characters
45+
replace_with_hyphen = re.compile(r"[\[\(_,\s]")
46+
index_name = re.sub(replace_with_hyphen, "-", index_name)
47+
replace_with_empty = re.compile(r"[\]\)\.]")
48+
index_name = re.sub(replace_with_empty, "", index_name)
49+
50+
max_length = 45
51+
index_name = index_name[:max_length]
52+
53+
# Trim final character if it is not alphanumeric
54+
if index_name.endswith("_") or index_name.endswith("-"):
55+
index_name = index_name[:-1]
56+
57+
return index_name.lower()
58+
59+
2360
def main():
2461
pc = Pinecone(api_key=read_env_var("PINECONE_API_KEY"))
25-
index_name = read_env_var("NAME_PREFIX") + random_string(20)
62+
index_name = generate_index_name(read_env_var("NAME_PREFIX") + random_string(20))
2663
pc.create_index(
2764
name=index_name,
2865
metric=read_env_var("METRIC"),

tests/integration/control/pod/conftest.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import pytest
22
import random
3-
import string
43
import time
54
from pinecone import Pinecone, PodSpec
6-
from ...helpers import generate_index_name, get_environment_var
5+
from ...helpers import generate_index_name, generate_collection_name, get_environment_var
76

87

98
@pytest.fixture()
@@ -69,17 +68,13 @@ def index_exists(index_name, client):
6968
return index_name in client.list_indexes().names()
7069

7170

72-
def random_string():
73-
return "".join(random.choice(string.ascii_lowercase) for i in range(10))
74-
75-
7671
@pytest.fixture(scope="session")
7772
def reusable_collection():
7873
pc = Pinecone(
7974
api_key=get_environment_var("PINECONE_API_KEY"),
8075
additional_headers={"sdk-test-suite": "pinecone-python-client"},
8176
)
82-
index_name = "temp-index-" + random_string()
77+
index_name = generate_index_name("temp-index")
8378
dimension = int(get_environment_var("DIMENSION"))
8479
print(f"Creating index {index_name} to prepare a collection...")
8580
pc.create_index(
@@ -99,7 +94,7 @@ def reusable_collection():
9994
index = pc.Index(index_name)
10095
index.upsert(vectors=vectors)
10196

102-
collection_name = "reused-coll-" + random_string()
97+
collection_name = generate_collection_name("reused-coll")
10398
pc.create_collection(name=collection_name, source=index_name)
10499

105100
time_waited = 0

tests/integration/control/pod/test_collections.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
import string
21
import random
32
import pytest
43
import time
54
from pinecone import PodSpec
6-
7-
8-
def random_string():
9-
return "".join(random.choice(string.ascii_lowercase) for i in range(10))
5+
from ...helpers import generate_index_name, generate_collection_name
106

117

128
class TestCollectionsHappyPath:
@@ -18,7 +14,7 @@ def test_index_to_collection_to_index_happy_path(
1814
vectors = [(str(i), random_vector()) for i in range(num_vectors)]
1915
index.upsert(vectors=vectors)
2016

21-
collection_name = "coll1-" + random_string()
17+
collection_name = generate_collection_name("coll1")
2218
client.create_collection(name=collection_name, source=ready_index)
2319
desc = client.describe_collection(collection_name)
2420
assert desc["name"] == collection_name
@@ -51,7 +47,7 @@ def test_index_to_collection_to_index_happy_path(
5147
assert desc["size"] > 0
5248

5349
# Create index from collection
54-
index_name = "index-from-collection-" + collection_name
50+
index_name = generate_index_name("index-from-collection-" + collection_name)
5551
print(f"Creating index {index_name} from collection {collection_name}...")
5652
client.create_index(
5753
name=index_name,
@@ -91,7 +87,7 @@ def test_create_index_with_different_metric_from_orig_index(
9187
metrics = ["cosine", "euclidean", "dotproduct"]
9288
target_metric = random.choice([x for x in metrics if x != metric])
9389

94-
index_name = "from-coll-" + random_string()
90+
index_name = generate_index_name("from-" + reusable_collection)
9591
client.create_index(
9692
name=index_name,
9793
dimension=dimension,

tests/integration/control/pod/test_collections_errors.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
1-
import string
21
import random
32
import pytest
43
from pinecone import PodSpec
5-
6-
7-
def random_string():
8-
return "".join(random.choice(string.ascii_lowercase) for i in range(10))
4+
from ...helpers import generate_collection_name, generate_index_name, random_string
95

106

117
class TestCollectionErrorCases:
128
def test_create_index_with_nonexistent_source_collection(
139
self, client, dimension, metric, environment
1410
):
1511
with pytest.raises(Exception) as e:
16-
index_name = "from-nonexistent-coll-" + random_string()
12+
index_name = generate_index_name("from-nonexistent-coll-" + random_string(10))
1713
client.create_index(
1814
name=index_name,
1915
dimension=dimension,
@@ -43,7 +39,7 @@ def test_create_index_in_mismatched_environment(
4339
target_env = random.choice([x for x in envs if x != environment])
4440

4541
with pytest.raises(Exception) as e:
46-
index_name = "from-coll-" + random_string()
42+
index_name = generate_index_name("from-coll-" + random_string(10))
4743
client.create_index(
4844
name=index_name,
4945
dimension=dimension,
@@ -59,7 +55,7 @@ def test_create_index_with_mismatched_dimension(
5955
):
6056
with pytest.raises(Exception) as e:
6157
client.create_index(
62-
name="from-coll-" + random_string(),
58+
name=generate_index_name("from-coll-" + random_string(10)),
6359
dimension=dimension + 1,
6460
metric=metric,
6561
spec=PodSpec(environment=environment, source_collection=reusable_collection),
@@ -91,13 +87,13 @@ def test_create_index_with_mismatched_dimension(
9187
# assert 'Source collection is not ready' in str(e.value)
9288

9389
def test_create_collection_from_not_ready_index(self, client, notready_index):
94-
name = "coll3-" + random_string()
90+
name = generate_collection_name("coll3")
9591
with pytest.raises(Exception) as e:
9692
client.create_collection(name, notready_index)
9793
assert "Source index is not ready" in str(e.value)
9894

9995
def test_create_collection_with_invalid_index(self, client):
100-
name = "coll4-" + random_string()
96+
name = generate_collection_name("coll4")
10197
with pytest.raises(Exception) as e:
10298
client.create_collection(name, "invalid_index")
10399
assert "Resource invalid_index not found" in str(e.value)

tests/integration/data/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import os
33
import time
44
import json
5-
from ..helpers import get_environment_var, random_string
5+
from ..helpers import get_environment_var, random_string, generate_index_name
66
from .seed import setup_data, setup_list_data, setup_weird_ids_data
77

88
# Test matrix needs to consider the following dimensions:
@@ -57,7 +57,7 @@ def spec():
5757

5858
@pytest.fixture(scope="session")
5959
def index_name():
60-
return "dataplane-" + random_string(20)
60+
return generate_index_name("dataplane")
6161

6262

6363
@pytest.fixture(scope="session")

tests/integration/helpers/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
get_environment_var,
44
random_string,
55
generate_index_name,
6+
generate_collection_name,
67
poll_stats_for_namespace,
78
poll_fetch_for_ids_in_namespace,
89
)

tests/integration/helpers/helpers.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,34 @@
44
import random
55
import string
66
from typing import Any
7+
from datetime import datetime
78

89

910
def random_string(length):
1011
return "".join(random.choice(string.ascii_lowercase) for i in range(length))
1112

1213

13-
def generate_index_name(test_name: str) -> str:
14-
buildNumber = os.getenv("GITHUB_BUILD_NUMBER", None)
14+
def generate_collection_name(label):
15+
return generate_index_name(label)
1516

16-
if test_name.startswith("test_"):
17-
test_name = test_name[5:]
1817

19-
# Trim name length to save space for other info in name
20-
test_name = test_name[:20]
18+
def generate_index_name(label: str) -> str:
19+
github_actor = os.getenv("GITHUB_ACTOR", None)
20+
user = os.getenv("USER", None)
21+
index_owner = github_actor or user
22+
23+
formatted_date = datetime.now().strftime("%Y%m%d-%H%M%S%f")[:-3]
24+
25+
github_job = os.getenv("GITHUB_JOB", None)
26+
27+
if label.startswith("test_"):
28+
label = label[5:]
2129

2230
# Remove trailing underscore, if any
23-
if test_name.endswith("_"):
24-
test_name = test_name[:-1]
31+
if label.endswith("_"):
32+
label = label[:-1]
2533

26-
name_parts = [buildNumber, test_name, random_string(45)]
34+
name_parts = [index_owner, formatted_date, github_job, label]
2735
index_name = "-".join([x for x in name_parts if x is not None])
2836

2937
# Remove invalid characters
@@ -36,8 +44,8 @@ def generate_index_name(test_name: str) -> str:
3644
index_name = index_name[:max_length]
3745

3846
# Trim final character if it is not alphanumeric
39-
if test_name.endswith("_") or test_name.endswith("-"):
40-
test_name = test_name[:-1]
47+
if index_name.endswith("_") or index_name.endswith("-"):
48+
index_name = index_name[:-1]
4149

4250
return index_name.lower()
4351

0 commit comments

Comments
 (0)