From fefc6d920f6605018c3c0b0fdd5e78236b91a3a1 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 27 Feb 2023 14:41:28 +0000 Subject: [PATCH] Fixing open handle issue - now that the worker has access to queues needs to shut them down. --- packages/backend-core/src/queue/queue.ts | 4 +- .../api/routes/global/tests/auditLogs.spec.ts | 222 +++++++++--------- packages/worker/src/index.ts | 5 +- 3 files changed, 117 insertions(+), 114 deletions(-) diff --git a/packages/backend-core/src/queue/queue.ts b/packages/backend-core/src/queue/queue.ts index 8e1fc1fbf3..c57ebafb1f 100644 --- a/packages/backend-core/src/queue/queue.ts +++ b/packages/backend-core/src/queue/queue.ts @@ -40,8 +40,10 @@ export function createQueue( } export async function shutdown() { - if (QUEUES.length) { + if (cleanupInterval) { clearInterval(cleanupInterval) + } + if (QUEUES.length) { for (let queue of QUEUES) { await queue.close() } diff --git a/packages/worker/src/api/routes/global/tests/auditLogs.spec.ts b/packages/worker/src/api/routes/global/tests/auditLogs.spec.ts index 0b9bf367cc..19e3cd64b4 100644 --- a/packages/worker/src/api/routes/global/tests/auditLogs.spec.ts +++ b/packages/worker/src/api/routes/global/tests/auditLogs.spec.ts @@ -1,111 +1,111 @@ -// import { mocks, structures } from "@budibase/backend-core/tests" -// import { context, events } from "@budibase/backend-core" -// import { Event, IdentityType } from "@budibase/types" -// import { TestConfiguration } from "../../../../tests" -// -// mocks.licenses.useAuditLogs() -// -// const BASE_IDENTITY = { -// account: undefined, -// type: IdentityType.USER, -// } -// const USER_AUDIT_LOG_COUNT = 3 -// const APP_ID = "app_1" -// -// describe("/api/global/auditlogs", () => { -// const config = new TestConfiguration() -// -// beforeAll(async () => { -// await config.beforeAll() -// }) -// -// afterAll(async () => { -// await config.afterAll() -// }) -// -// describe("POST /api/global/auditlogs/search", () => { -// it("should be able to fire some events (create audit logs)", async () => { -// await context.doInTenant(config.tenantId, async () => { -// const userId = config.user!._id! -// const identity = { -// ...BASE_IDENTITY, -// _id: userId, -// tenantId: config.tenantId, -// } -// await context.doInIdentityContext(identity, async () => { -// for (let i = 0; i < USER_AUDIT_LOG_COUNT; i++) { -// await events.user.created(structures.users.user()) -// } -// await context.doInAppContext(APP_ID, async () => { -// await events.app.created(structures.apps.app(APP_ID)) -// }) -// // fetch the user created events -// const response = await config.api.auditLogs.search({ -// events: [Event.USER_CREATED], -// }) -// expect(response.data).toBeDefined() -// // there will be an initial event which comes from the default user creation -// expect(response.data.length).toBe(USER_AUDIT_LOG_COUNT + 1) -// }) -// }) -// }) -// -// it("should be able to search by event", async () => { -// const response = await config.api.auditLogs.search({ -// events: [Event.USER_CREATED], -// }) -// expect(response.data.length).toBeGreaterThan(0) -// for (let log of response.data) { -// expect(log.event).toBe(Event.USER_CREATED) -// } -// }) -// -// it("should be able to search by time range (frozen)", async () => { -// // this is frozen, only need to add 1 and minus 1 -// const now = new Date() -// const start = new Date() -// start.setSeconds(now.getSeconds() - 1) -// const end = new Date() -// end.setSeconds(now.getSeconds() + 1) -// const response = await config.api.auditLogs.search({ -// startDate: start.toISOString(), -// endDate: end.toISOString(), -// }) -// expect(response.data.length).toBeGreaterThan(0) -// for (let log of response.data) { -// expect(log.timestamp).toBe(now.toISOString()) -// } -// }) -// -// it("should be able to search by user ID", async () => { -// const userId = config.user!._id! -// const response = await config.api.auditLogs.search({ -// userIds: [userId], -// }) -// expect(response.data.length).toBeGreaterThan(0) -// for (let log of response.data) { -// expect(log.user._id).toBe(userId) -// } -// }) -// -// it("should be able to search by app ID", async () => { -// const response = await config.api.auditLogs.search({ -// appIds: [APP_ID], -// }) -// expect(response.data.length).toBeGreaterThan(0) -// for (let log of response.data) { -// expect(log.app?._id).toBe(APP_ID) -// } -// }) -// -// it("should be able to search by full string", async () => { -// const response = await config.api.auditLogs.search({ -// fullSearch: "User", -// }) -// expect(response.data.length).toBeGreaterThan(0) -// for (let log of response.data) { -// expect(log.name.includes("User")).toBe(true) -// } -// }) -// }) -// }) +import { mocks, structures } from "@budibase/backend-core/tests" +import { context, events } from "@budibase/backend-core" +import { Event, IdentityType } from "@budibase/types" +import { TestConfiguration } from "../../../../tests" + +mocks.licenses.useAuditLogs() + +const BASE_IDENTITY = { + account: undefined, + type: IdentityType.USER, +} +const USER_AUDIT_LOG_COUNT = 3 +const APP_ID = "app_1" + +describe("/api/global/auditlogs", () => { + const config = new TestConfiguration() + + beforeAll(async () => { + await config.beforeAll() + }) + + afterAll(async () => { + await config.afterAll() + }) + + describe("POST /api/global/auditlogs/search", () => { + it("should be able to fire some events (create audit logs)", async () => { + await context.doInTenant(config.tenantId, async () => { + const userId = config.user!._id! + const identity = { + ...BASE_IDENTITY, + _id: userId, + tenantId: config.tenantId, + } + await context.doInIdentityContext(identity, async () => { + for (let i = 0; i < USER_AUDIT_LOG_COUNT; i++) { + await events.user.created(structures.users.user()) + } + await context.doInAppContext(APP_ID, async () => { + await events.app.created(structures.apps.app(APP_ID)) + }) + // fetch the user created events + const response = await config.api.auditLogs.search({ + events: [Event.USER_CREATED], + }) + expect(response.data).toBeDefined() + // there will be an initial event which comes from the default user creation + expect(response.data.length).toBe(USER_AUDIT_LOG_COUNT + 1) + }) + }) + }) + + it("should be able to search by event", async () => { + const response = await config.api.auditLogs.search({ + events: [Event.USER_CREATED], + }) + expect(response.data.length).toBeGreaterThan(0) + for (let log of response.data) { + expect(log.event).toBe(Event.USER_CREATED) + } + }) + + it("should be able to search by time range (frozen)", async () => { + // this is frozen, only need to add 1 and minus 1 + const now = new Date() + const start = new Date() + start.setSeconds(now.getSeconds() - 1) + const end = new Date() + end.setSeconds(now.getSeconds() + 1) + const response = await config.api.auditLogs.search({ + startDate: start.toISOString(), + endDate: end.toISOString(), + }) + expect(response.data.length).toBeGreaterThan(0) + for (let log of response.data) { + expect(log.timestamp).toBe(now.toISOString()) + } + }) + + it("should be able to search by user ID", async () => { + const userId = config.user!._id! + const response = await config.api.auditLogs.search({ + userIds: [userId], + }) + expect(response.data.length).toBeGreaterThan(0) + for (let log of response.data) { + expect(log.user._id).toBe(userId) + } + }) + + it("should be able to search by app ID", async () => { + const response = await config.api.auditLogs.search({ + appIds: [APP_ID], + }) + expect(response.data.length).toBeGreaterThan(0) + for (let log of response.data) { + expect(log.app?._id).toBe(APP_ID) + } + }) + + it("should be able to search by full string", async () => { + const response = await config.api.auditLogs.search({ + fullSearch: "User", + }) + expect(response.data.length).toBeGreaterThan(0) + for (let log of response.data) { + expect(log.name.includes("User")).toBe(true) + } + }) + }) +}) diff --git a/packages/worker/src/index.ts b/packages/worker/src/index.ts index ac28ead30a..ec6a44cc3a 100644 --- a/packages/worker/src/index.ts +++ b/packages/worker/src/index.ts @@ -13,8 +13,8 @@ import { Event } from "@sentry/types/dist/event" import Application from "koa" import { bootstrap } from "global-agent" import * as db from "./db" -import { auth, logging, events, middleware } from "@budibase/backend-core" -import { sdk as proSdk, sdk } from "@budibase/pro" +import { auth, logging, events, middleware, queue } from "@budibase/backend-core" +import { sdk as proSdk } from "@budibase/pro" db.init() import Koa from "koa" import koaBody from "koa-body" @@ -86,6 +86,7 @@ server.on("close", async () => { console.log("Server Closed") await redis.shutdown() await events.shutdown() + await queue.shutdown() if (!env.isTest()) { process.exit(errCode) }