Skip to content

Commit 7109c9c

Browse files
committed
test: limits total number of test DBs allowed
1 parent bd7bfbf commit 7109c9c

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

packages/sqlalchemy-spanner/create_test_database.py

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,28 +68,74 @@ def delete_stale_test_instances():
6868

6969

7070
def delete_stale_test_databases():
71-
"""Delete test databases that are older than four hours."""
71+
"""Delete stale or excessive test databases.
72+
73+
Deletes stale test databases that are older than 4 hours and
74+
ensures we don't hit the 100 database limit per spanner instance by
75+
deleting the oldest databases if we are near the limit.
76+
"""
7277
cutoff = (int(time.time()) - 4 * 60 * 60) * 1000
7378
instance = CLIENT.instance("sqlalchemy-dialect-test")
7479
if not instance.exists():
7580
return
76-
database_pbs = instance.list_databases()
81+
82+
# Convert iterator to list to allow multiple passes and length check
83+
database_pbs = list(instance.list_databases())
84+
85+
# First pass: Delete stale databases
86+
remaining_dbs = []
7787
for database_pb in database_pbs:
7888
database = Database.from_pb(database_pb, instance)
7989
# The emulator does not return a create_time for databases.
8090
if database.create_time is None:
91+
remaining_dbs.append(database_pb)
8192
continue
93+
8294
create_time = datetime_helpers.to_milliseconds(database_pb.create_time)
8395
if create_time > cutoff:
96+
remaining_dbs.append(database_pb)
8497
continue
98+
8599
try:
86100
database.drop()
101+
print(f"Dropped stale database '{database.database_id}'")
87102
except ResourceExhausted:
88103
print(
89104
"Unable to drop stale database '{}'. May need manual delete.".format(
90105
database.database_id
91106
)
92107
)
108+
remaining_dbs.append(database_pb) # Still there
109+
110+
# Second pass: If we are still near the limit (e.g., 90+ databases),
111+
# delete the oldest ones regardless of age to free up slots.
112+
# Spanner instances have a hard limit of 100 databases.
113+
LIMIT = 90
114+
if len(remaining_dbs) >= LIMIT:
115+
print(f"Database count ({len(remaining_dbs)}) is near limit. Cleaning up oldest databases.")
116+
117+
# Sort by creation time
118+
dbs_with_time = []
119+
for db_pb in remaining_dbs:
120+
if db_pb.create_time:
121+
dbs_with_time.append((db_pb.create_time, db_pb.name))
122+
123+
dbs_with_time.sort() # Sorts by time ascending (oldest first)
124+
125+
# Delete enough to get below the limit
126+
to_delete = len(remaining_dbs) - (LIMIT - 10) # Aim for 80
127+
deleted_count = 0
128+
129+
for create_time, full_name in dbs_with_time:
130+
if deleted_count >= to_delete:
131+
break
132+
db_id = full_name.split('/')[-1]
133+
try:
134+
instance.database(db_id).drop()
135+
print(f"Dropped oldest database '{db_id}' to prevent resource exhaustion.")
136+
deleted_count += 1
137+
except Exception as e:
138+
print(f"Failed to drop database '{db_id}': {e}")
93139

94140

95141
def create_test_instance():

0 commit comments

Comments
 (0)