Skip to content

Commit

Permalink
refactor: create an isolated test env for each test instead of test s…
Browse files Browse the repository at this point in the history
…uite

The reason behind these change is that test were failing on a faster machine
(probably due to the implementation of KafkaJS and Kafka itself). The clean up
of topics were failing and consequently also the tests. An easier solution
is not to clean up the environment but to have a true isolated environment
for each test.
  • Loading branch information
giovannibaratta committed Mar 11, 2024
1 parent db14bba commit c57b65b
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 79 deletions.
33 changes: 1 addition & 32 deletions service/libs/testing/src/kafka.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@ import {KafkaConfig} from "@libs/external/config/config"
import {randomUUID} from "crypto"
import {Kafka, logLevel} from "kafkajs"

export async function prepareKafka(): Promise<KafkaConfig> {
export async function generateIsolatedKafkaConfig(): Promise<KafkaConfig> {
const rawKafkaBrokers = process.env.KAFKA_BROKERS

if (rawKafkaBrokers === undefined)
throw new Error("KAFKA_BROKERS is not defined")

const rawKafkaTopicRunStatusChanged = `run-status-changed-${randomUUID()}`

await createTopic(rawKafkaBrokers, rawKafkaTopicRunStatusChanged)

return {
brokers: rawKafkaBrokers.split(","),
topics: {
Expand All @@ -20,35 +18,6 @@ export async function prepareKafka(): Promise<KafkaConfig> {
}
}

async function createTopic(brokers: string, topic: string) {
const client = new Kafka({
brokers: brokers.split(",")
})

const admin = client.admin()
await admin.connect()
await admin.createTopics({
topics: [{topic}],
waitForLeaders: true
})
await admin.disconnect()
}

export async function cleanKafka(config: KafkaConfig): Promise<void> {
const client = new Kafka({
brokers: config.brokers,
logLevel: logLevel.ERROR
})

const admin = client.admin()
await admin.connect()
await admin.deleteTopics({
topics: [config.topics.runStatusChanged]
})
await createTopic(config.brokers.join(","), config.topics.runStatusChanged)
await admin.disconnect()
}

export async function readMessagesFromKafka(
config: KafkaConfig,
topic: string
Expand Down
19 changes: 6 additions & 13 deletions service/main/test/controller/plan.controller.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@ import * as request from "supertest"

import {NestApplication} from "@nestjs/core"
// eslint-disable-next-line node/no-unpublished-import
import {Test, TestingModule} from "@nestjs/testing"
import {AppModule} from "@app/app.module"
import {PrismaClient} from "@prisma/client"
import {CreatePlanRefRequestBody} from "@app/controller/plan-models"
import {cleanDatabase, prepareDatabase} from "@libs/testing/database"
import {Config, KafkaConfig} from "@libs/external/config/config"
import {DatabaseClient} from "@libs/external/db/database-client"
import {cleanKafka, prepareKafka} from "@libs/testing/kafka"
import {prepareDatabase} from "@libs/testing/database"
import {generateIsolatedKafkaConfig} from "@libs/testing/kafka"
import {Test, TestingModule} from "@nestjs/testing"
import {PrismaClient} from "@prisma/client"

describe("POST /plan-refs", () => {
let app: NestApplication
const endpoint = "/plan-refs"
let prisma: PrismaClient
let kafkaConfig: KafkaConfig

beforeAll(async () => {
beforeEach(async () => {
const isolatedDb = await prepareDatabase()
kafkaConfig = await prepareKafka()
kafkaConfig = await generateIsolatedKafkaConfig()

const module: TestingModule = await Test.createTestingModule({
imports: [AppModule]
Expand All @@ -38,11 +38,6 @@ describe("POST /plan-refs", () => {
prisma = module.get(DatabaseClient)
})

beforeEach(async () => {
await cleanKafka(kafkaConfig)
await cleanDatabase(prisma)
})

it("should create a record in the plan table and return the uuid", async () => {
// Given
const requestBody: CreatePlanRefRequestBody = {
Expand Down Expand Up @@ -116,8 +111,6 @@ describe("POST /plan-refs", () => {
})

afterAll(async () => {
await cleanKafka(kafkaConfig)
await cleanDatabase(prisma)
await prisma.$disconnect()
await app.close()
})
Expand Down
27 changes: 9 additions & 18 deletions service/main/test/controller/run.controller.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,21 @@ import {AppModule} from "@app/app.module"
import {CreateRunRequestBody} from "@app/controller/run-models"
import {Config, KafkaConfig} from "@libs/external/config/config"
import {DatabaseClient} from "@libs/external/db/database-client"
import {cleanDatabase, prepareDatabase} from "@libs/testing/database"
import {persistPlanMock} from "@libs/testing"
import {persistSourceCodeMock} from "@libs/testing"
import {persistPlanMock, persistSourceCodeMock} from "@libs/testing"
import {prepareDatabase} from "@libs/testing/database"
import {NestApplication} from "@nestjs/core"
import {TestingModule, Test} from "@nestjs/testing"
import {Test, TestingModule} from "@nestjs/testing"
import {PrismaClient} from "@prisma/client"
// eslint-disable-next-line node/no-unpublished-import
import * as request from "supertest"
import "expect-more-jest"
import {randomUUID} from "crypto"
import {globalValidationPipe} from "@app/validation-pipe"
import {
cleanKafka,
prepareKafka,
generateIsolatedKafkaConfig,
readMessagesFromKafka
} from "@libs/testing/kafka"
import {HttpStatus} from "@nestjs/common"
import {randomUUID} from "crypto"
import "expect-more-jest"
import * as request from "supertest"

describe("POST /runs", () => {
let app: NestApplication
Expand All @@ -27,9 +25,9 @@ describe("POST /runs", () => {

const endpoint = "/runs"

beforeAll(async () => {
beforeEach(async () => {
const isolatedDb = await prepareDatabase()
kafkaConfig = await prepareKafka()
kafkaConfig = await generateIsolatedKafkaConfig()

const module: TestingModule = await Test.createTestingModule({
imports: [AppModule]
Expand All @@ -47,11 +45,6 @@ describe("POST /runs", () => {
prisma = module.get(DatabaseClient)
})

beforeEach(async () => {
await cleanKafka(kafkaConfig)
await cleanDatabase(prisma)
})

it("should persist the run, emit a run-status-changed event and return the uuid", async () => {
// Given
const sourceCode = await persistSourceCodeMock(prisma)
Expand Down Expand Up @@ -200,8 +193,6 @@ describe("POST /runs", () => {
})

afterAll(async () => {
await cleanKafka(kafkaConfig)
await cleanDatabase(prisma)
await prisma.$disconnect()
await app.close()
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
// eslint-disable-next-line node/no-unpublished-import
import * as request from "supertest"
import {NestApplication} from "@nestjs/core"
import * as request from "supertest"
// eslint-disable-next-line node/no-unpublished-import
import {Test, TestingModule} from "@nestjs/testing"
import {AppModule} from "@app/app.module"
import {operations} from "@apis/apis"
import {PrismaClient} from "@prisma/client"
import {cleanDatabase, prepareDatabase} from "@libs/testing/database"
import {AppModule} from "@app/app.module"
import {Config, KafkaConfig} from "@libs/external/config/config"
import {DatabaseClient} from "@libs/external/db/database-client"
import {cleanKafka, prepareKafka} from "@libs/testing/kafka"
import {prepareDatabase} from "@libs/testing/database"
import {generateIsolatedKafkaConfig} from "@libs/testing/kafka"
import {Test, TestingModule} from "@nestjs/testing"
import {PrismaClient} from "@prisma/client"

describe("POST /source-code-refs", () => {
let kafkaConfig: KafkaConfig
let app: NestApplication
let prisma: PrismaClient

beforeAll(async () => {
beforeEach(async () => {
const isolatedDb = await prepareDatabase()
kafkaConfig = await prepareKafka()
kafkaConfig = await generateIsolatedKafkaConfig()

const module: TestingModule = await Test.createTestingModule({
imports: [AppModule]
Expand All @@ -36,11 +36,6 @@ describe("POST /source-code-refs", () => {
prisma = module.get(DatabaseClient)
})

beforeEach(async () => {
await cleanKafka(kafkaConfig)
await cleanDatabase(prisma)
})

it("should create a record in the SourceCode table and return the uuid", async () => {
// Given
const requestBody: operations["createSourceCodeRef"]["requestBody"]["content"]["application/json"] =
Expand Down Expand Up @@ -116,9 +111,7 @@ describe("POST /source-code-refs", () => {
})
})

afterAll(async () => {
await cleanKafka(kafkaConfig)
await cleanDatabase(prisma)
afterEach(async () => {
await prisma.$disconnect()
await app.close()
})
Expand Down

0 comments on commit c57b65b

Please sign in to comment.