Skip to content

Commit

Permalink
[Chore] Put date into test index and collection names (#399)
Browse files Browse the repository at this point in the history
## 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.
  • Loading branch information
jhamon authored Oct 21, 2024
1 parent 2389e1f commit c13a249
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 41 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: "Lint"
on: [push, pull_request]
on: [pull_request]

jobs:
lint:
Expand Down
39 changes: 38 additions & 1 deletion scripts/create.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os
import re
import random
import string
from datetime import datetime
from pinecone import Pinecone


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


def generate_index_name(test_name: str) -> str:
github_actor = os.getenv("GITHUB_ACTOR", None)
user = os.getenv("USER", None)
index_owner = github_actor or user

formatted_date = datetime.now().strftime("%Y%m%d-%H%M%S%f")[:-3]

github_job = os.getenv("GITHUB_JOB", None)

if test_name.startswith("test_"):
test_name = test_name[5:]

# Remove trailing underscore, if any
if test_name.endswith("_"):
test_name = test_name[:-1]

name_parts = [index_owner, formatted_date, github_job, test_name]
index_name = "-".join([x for x in name_parts if x is not None])

# Remove invalid characters
replace_with_hyphen = re.compile(r"[\[\(_,\s]")
index_name = re.sub(replace_with_hyphen, "-", index_name)
replace_with_empty = re.compile(r"[\]\)\.]")
index_name = re.sub(replace_with_empty, "", index_name)

max_length = 45
index_name = index_name[:max_length]

# Trim final character if it is not alphanumeric
if index_name.endswith("_") or index_name.endswith("-"):
index_name = index_name[:-1]

return index_name.lower()


def main():
pc = Pinecone(api_key=read_env_var("PINECONE_API_KEY"))
index_name = read_env_var("NAME_PREFIX") + random_string(20)
index_name = generate_index_name(read_env_var("NAME_PREFIX") + random_string(20))
pc.create_index(
name=index_name,
metric=read_env_var("METRIC"),
Expand Down
11 changes: 3 additions & 8 deletions tests/integration/control/pod/conftest.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import pytest
import random
import string
import time
from pinecone import Pinecone, PodSpec
from ...helpers import generate_index_name, get_environment_var
from ...helpers import generate_index_name, generate_collection_name, get_environment_var


@pytest.fixture()
Expand Down Expand Up @@ -69,17 +68,13 @@ def index_exists(index_name, client):
return index_name in client.list_indexes().names()


def random_string():
return "".join(random.choice(string.ascii_lowercase) for i in range(10))


@pytest.fixture(scope="session")
def reusable_collection():
pc = Pinecone(
api_key=get_environment_var("PINECONE_API_KEY"),
additional_headers={"sdk-test-suite": "pinecone-python-client"},
)
index_name = "temp-index-" + random_string()
index_name = generate_index_name("temp-index")
dimension = int(get_environment_var("DIMENSION"))
print(f"Creating index {index_name} to prepare a collection...")
pc.create_index(
Expand All @@ -99,7 +94,7 @@ def reusable_collection():
index = pc.Index(index_name)
index.upsert(vectors=vectors)

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

time_waited = 0
Expand Down
12 changes: 4 additions & 8 deletions tests/integration/control/pod/test_collections.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import string
import random
import pytest
import time
from pinecone import PodSpec


def random_string():
return "".join(random.choice(string.ascii_lowercase) for i in range(10))
from ...helpers import generate_index_name, generate_collection_name


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

collection_name = "coll1-" + random_string()
collection_name = generate_collection_name("coll1")
client.create_collection(name=collection_name, source=ready_index)
desc = client.describe_collection(collection_name)
assert desc["name"] == collection_name
Expand Down Expand Up @@ -51,7 +47,7 @@ def test_index_to_collection_to_index_happy_path(
assert desc["size"] > 0

# Create index from collection
index_name = "index-from-collection-" + collection_name
index_name = generate_index_name("index-from-collection-" + collection_name)
print(f"Creating index {index_name} from collection {collection_name}...")
client.create_index(
name=index_name,
Expand Down Expand Up @@ -91,7 +87,7 @@ def test_create_index_with_different_metric_from_orig_index(
metrics = ["cosine", "euclidean", "dotproduct"]
target_metric = random.choice([x for x in metrics if x != metric])

index_name = "from-coll-" + random_string()
index_name = generate_index_name("from-" + reusable_collection)
client.create_index(
name=index_name,
dimension=dimension,
Expand Down
16 changes: 6 additions & 10 deletions tests/integration/control/pod/test_collections_errors.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
import string
import random
import pytest
from pinecone import PodSpec


def random_string():
return "".join(random.choice(string.ascii_lowercase) for i in range(10))
from ...helpers import generate_collection_name, generate_index_name, random_string


class TestCollectionErrorCases:
def test_create_index_with_nonexistent_source_collection(
self, client, dimension, metric, environment
):
with pytest.raises(Exception) as e:
index_name = "from-nonexistent-coll-" + random_string()
index_name = generate_index_name("from-nonexistent-coll-" + random_string(10))
client.create_index(
name=index_name,
dimension=dimension,
Expand Down Expand Up @@ -43,7 +39,7 @@ def test_create_index_in_mismatched_environment(
target_env = random.choice([x for x in envs if x != environment])

with pytest.raises(Exception) as e:
index_name = "from-coll-" + random_string()
index_name = generate_index_name("from-coll-" + random_string(10))
client.create_index(
name=index_name,
dimension=dimension,
Expand All @@ -59,7 +55,7 @@ def test_create_index_with_mismatched_dimension(
):
with pytest.raises(Exception) as e:
client.create_index(
name="from-coll-" + random_string(),
name=generate_index_name("from-coll-" + random_string(10)),
dimension=dimension + 1,
metric=metric,
spec=PodSpec(environment=environment, source_collection=reusable_collection),
Expand Down Expand Up @@ -91,13 +87,13 @@ def test_create_index_with_mismatched_dimension(
# assert 'Source collection is not ready' in str(e.value)

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

def test_create_collection_with_invalid_index(self, client):
name = "coll4-" + random_string()
name = generate_collection_name("coll4")
with pytest.raises(Exception) as e:
client.create_collection(name, "invalid_index")
assert "Resource invalid_index not found" in str(e.value)
4 changes: 2 additions & 2 deletions tests/integration/data/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import os
import time
import json
from ..helpers import get_environment_var, random_string
from ..helpers import get_environment_var, random_string, generate_index_name
from .seed import setup_data, setup_list_data, setup_weird_ids_data

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

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


@pytest.fixture(scope="session")
Expand Down
1 change: 1 addition & 0 deletions tests/integration/helpers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
get_environment_var,
random_string,
generate_index_name,
generate_collection_name,
poll_stats_for_namespace,
poll_fetch_for_ids_in_namespace,
)
30 changes: 19 additions & 11 deletions tests/integration/helpers/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,34 @@
import random
import string
from typing import Any
from datetime import datetime


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


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

if test_name.startswith("test_"):
test_name = test_name[5:]

# Trim name length to save space for other info in name
test_name = test_name[:20]
def generate_index_name(label: str) -> str:
github_actor = os.getenv("GITHUB_ACTOR", None)
user = os.getenv("USER", None)
index_owner = github_actor or user

formatted_date = datetime.now().strftime("%Y%m%d-%H%M%S%f")[:-3]

github_job = os.getenv("GITHUB_JOB", None)

if label.startswith("test_"):
label = label[5:]

# Remove trailing underscore, if any
if test_name.endswith("_"):
test_name = test_name[:-1]
if label.endswith("_"):
label = label[:-1]

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

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

# Trim final character if it is not alphanumeric
if test_name.endswith("_") or test_name.endswith("-"):
test_name = test_name[:-1]
if index_name.endswith("_") or index_name.endswith("-"):
index_name = index_name[:-1]

return index_name.lower()

Expand Down

0 comments on commit c13a249

Please sign in to comment.