mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2026-04-16 19:39:19 +01:00
Fix playwright tests (#2325)
* Fix cleanupDBs.js: use async iteration for Azure SDK paged results * update node version * fix cleanup script to use new Cosmos SDK APIs correctly * get rid of global crypto * fix flakiness * revert DE pipeline to use Node 18 * nit --------- Co-authored-by: Asier Isayas <aisayas@microsoft.com>
This commit is contained in:
10
.github/workflows/cleanup.yml
vendored
10
.github/workflows/cleanup.yml
vendored
@@ -22,18 +22,18 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: "Az CLI login"
|
- name: "Az CLI login"
|
||||||
uses: azure/login@v1
|
uses: azure/login@v2
|
||||||
with:
|
with:
|
||||||
client-id: ${{ secrets.E2E_TESTS_CLIENT_ID }}
|
client-id: ${{ secrets.E2E_TESTS_CLIENT_ID }}
|
||||||
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
|
||||||
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||||
|
|
||||||
- name: Use Node.js 18.x
|
- name: Use Node.js 20.x
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18.x
|
node-version: 20.x
|
||||||
- run: npm ci
|
- run: npm ci
|
||||||
- run: node utils/cleanupDBs.js
|
- run: node utils/cleanupDBs.js
|
||||||
@@ -24,6 +24,14 @@ test.describe("Vector Policy under Scale & Settings", () => {
|
|||||||
await vectorPolicyTab.click();
|
await vectorPolicyTab.click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test.afterEach("Clear vector policies", async () => {
|
||||||
|
const { resource: containerDef } = await context.container.read();
|
||||||
|
if (containerDef.vectorEmbeddingPolicy?.vectorEmbeddings?.length) {
|
||||||
|
containerDef.vectorEmbeddingPolicy.vectorEmbeddings = [];
|
||||||
|
await context.container.replace(containerDef);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test.afterAll("Delete Test Database", async () => {
|
test.afterAll("Delete Test Database", async () => {
|
||||||
await context?.dispose();
|
await context?.dispose();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,65 +18,66 @@ function friendlyTime(date) {
|
|||||||
async function main() {
|
async function main() {
|
||||||
const credentials = new AzureCliCredential();
|
const credentials = new AzureCliCredential();
|
||||||
const client = new CosmosDBManagementClient(credentials, subscriptionId);
|
const client = new CosmosDBManagementClient(credentials, subscriptionId);
|
||||||
const accounts = await client.databaseAccounts.list(resourceGroupName);
|
const accounts = client.databaseAccounts.listByResourceGroup(resourceGroupName);
|
||||||
for (const account of accounts) {
|
for await (const account of accounts) {
|
||||||
if (account.name.endsWith("-readonly")) {
|
if (account.name.endsWith("-readonly")) {
|
||||||
console.log(`SKIPPED: ${account.name}`);
|
console.log(`SKIPPED: ${account.name}`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (account.kind === "MongoDB") {
|
if (account.kind === "MongoDB") {
|
||||||
const mongoDatabases = await client.mongoDBResources.listMongoDBDatabases(resourceGroupName, account.name);
|
const mongoDatabases = client.mongoDBResources.listMongoDBDatabases(resourceGroupName, account.name);
|
||||||
for (const database of mongoDatabases) {
|
for await (const database of mongoDatabases) {
|
||||||
// Unfortunately Mongo does not provide a timestamp in ARM. There is no way to tell how old the DB is other thn encoding it in the ID :(
|
// Unfortunately Mongo does not provide a timestamp in ARM. There is no way to tell how old the DB is other thn encoding it in the ID :(
|
||||||
const timestamp = Number(database.name.split("_").pop());
|
const timestamp = Number(database.name.split("_").pop());
|
||||||
if (timestamp && timestamp < thirtyMinutesAgo) {
|
if (timestamp && timestamp < thirtyMinutesAgo) {
|
||||||
await client.mongoDBResources.deleteMongoDBDatabase(resourceGroupName, account.name, database.name);
|
await client.mongoDBResources.beginDeleteMongoDBDatabaseAndWait(resourceGroupName, account.name, database.name);
|
||||||
console.log(`DELETED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
console.log(`DELETED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
||||||
} else {
|
} else {
|
||||||
console.log(`SKIPPED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
console.log(`SKIPPED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (account.capabilities.find((c) => c.name === "EnableCassandra")) {
|
} else if (account.capabilities.find((c) => c.name === "EnableCassandra")) {
|
||||||
const cassandraDatabases = await client.cassandraResources.listCassandraKeyspaces(
|
const cassandraDatabases = client.cassandraResources.listCassandraKeyspaces(
|
||||||
resourceGroupName,
|
resourceGroupName,
|
||||||
account.name,
|
account.name,
|
||||||
);
|
);
|
||||||
for (const database of cassandraDatabases) {
|
for await (const database of cassandraDatabases) {
|
||||||
const timestamp = Number(database.resource._ts) * 1000;
|
const timestamp = Number(database.resource.ts) * 1000;
|
||||||
if (timestamp && timestamp < thirtyMinutesAgo) {
|
if (timestamp && timestamp < thirtyMinutesAgo) {
|
||||||
await client.cassandraResources.deleteCassandraKeyspace(resourceGroupName, account.name, database.name);
|
await client.cassandraResources.beginDeleteCassandraKeyspaceAndWait(resourceGroupName, account.name, database.name);
|
||||||
console.log(`DELETED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
console.log(`DELETED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
||||||
} else {
|
} else {
|
||||||
console.log(`SKIPPED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
console.log(`SKIPPED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (account.capabilities.find((c) => c.name === "EnableTable")) {
|
} else if (account.capabilities.find((c) => c.name === "EnableTable")) {
|
||||||
const tablesDatabase = await client.tableResources.listTables(resourceGroupName, account.name);
|
const tablesDatabase = client.tableResources.listTables(resourceGroupName, account.name);
|
||||||
for (const database of tablesDatabase) {
|
for await (const database of tablesDatabase) {
|
||||||
const timestamp = Number(database.resource._ts) * 1000;
|
const timestamp = Number(database.resource.ts) * 1000;
|
||||||
if (timestamp && timestamp < thirtyMinutesAgo) {
|
if (timestamp && timestamp < thirtyMinutesAgo) {
|
||||||
await client.tableResources.deleteTable(resourceGroupName, account.name, database.name);
|
await client.tableResources.beginDeleteTableAndWait(resourceGroupName, account.name, database.name);
|
||||||
console.log(`DELETED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
console.log(`DELETED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
||||||
} else {
|
} else {
|
||||||
console.log(`SKIPPED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
console.log(`SKIPPED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (account.capabilities.find((c) => c.name === "EnableGremlin")) {
|
} else if (account.capabilities.find((c) => c.name === "EnableGremlin")) {
|
||||||
const graphDatabases = await client.gremlinResources.listGremlinDatabases(resourceGroupName, account.name);
|
const graphDatabases = client.gremlinResources.listGremlinDatabases(resourceGroupName, account.name);
|
||||||
for (const database of graphDatabases) {
|
for await (const database of graphDatabases) {
|
||||||
const timestamp = Number(database.resource._ts) * 1000;
|
const timestamp = Number(database.resource.ts) * 1000;
|
||||||
if (timestamp && timestamp < thirtyMinutesAgo) {
|
if (timestamp && timestamp < thirtyMinutesAgo) {
|
||||||
await client.gremlinResources.deleteGremlinDatabase(resourceGroupName, account.name, database.name);
|
await client.gremlinResources.beginDeleteGremlinDatabaseAndWait(resourceGroupName, account.name, database.name);
|
||||||
console.log(`DELETED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
console.log(`DELETED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
||||||
} else {
|
} else {
|
||||||
console.log(`SKIPPED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
console.log(`SKIPPED: ${account.name} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (account.kind === "GlobalDocumentDB") {
|
} else if (account.kind === "GlobalDocumentDB") {
|
||||||
const sqlDatabases = await client.sqlResources.listSqlDatabases(resourceGroupName, account.name);
|
const sqlDatabases = client.sqlResources.listSqlDatabases(resourceGroupName, account.name);
|
||||||
const sqlDatabasesToDelete = sqlDatabases.map(async (database) => {
|
const sqlDatabasesToDelete = [];
|
||||||
await deleteWithRetry(client, database, account.name);
|
for await (const database of sqlDatabases) {
|
||||||
});
|
sqlDatabasesToDelete.push(deleteWithRetry(client, database, account.name));
|
||||||
|
}
|
||||||
await Promise.all(sqlDatabasesToDelete);
|
await Promise.all(sqlDatabasesToDelete);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,9 +91,9 @@ async function deleteWithRetry(client, database, accountName) {
|
|||||||
|
|
||||||
while (attempt < maxRetries) {
|
while (attempt < maxRetries) {
|
||||||
try {
|
try {
|
||||||
const timestamp = Number(database.resource._ts) * 1000;
|
const timestamp = Number(database.resource.ts) * 1000;
|
||||||
if (timestamp && timestamp < thirtyMinutesAgo) {
|
if (timestamp && timestamp < thirtyMinutesAgo) {
|
||||||
await client.sqlResources.deleteSqlDatabase(resourceGroupName, accountName, database.name);
|
await client.sqlResources.beginDeleteSqlDatabaseAndWait(resourceGroupName, accountName, database.name);
|
||||||
console.log(`DELETED: ${accountName} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
console.log(`DELETED: ${accountName} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
||||||
} else {
|
} else {
|
||||||
console.log(`SKIPPED: ${accountName} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
console.log(`SKIPPED: ${accountName} | ${database.name} | Age: ${friendlyTime(Date.now() - timestamp)}`);
|
||||||
@@ -126,7 +127,6 @@ main()
|
|||||||
process.exit(0);
|
process.exit(0);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err);
|
console.error(err);
|
||||||
console.log("Cleanup failed! Exiting with success. Cleanup should always fail safe.");
|
process.exit(1);
|
||||||
process.exit(0);
|
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user