Skip to content

Commit

Permalink
fix integration tests and load async
Browse files Browse the repository at this point in the history
  • Loading branch information
gonzalojaubert committed Nov 27, 2023
1 parent 49898d2 commit 437d0f9
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 11 deletions.
2 changes: 2 additions & 0 deletions common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ before(async () => {
throw new Error('Pid not found')
}
storePIDFor(sandboxPath, serverProcess.pid) //store pid to kill process on stop
await sleep(2000)
await sleep(10000)
console.log('local server ready')
})
5 changes: 3 additions & 2 deletions packages/framework-integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"graphql": "^16.6.0",
"tslib": "^2.4.0",
"@effect-ts/core": "^0.60.4",
"express-unless": "2.1.3"
"express-unless": "2.1.3",
"express": "^4.17.1"
},
"devDependencies": {
"@boostercloud/eslint-config": "workspace:^2.2.0",
Expand Down Expand Up @@ -102,7 +103,7 @@
"integration/aws-nuke": "TS_NODE_PROJECT=\"./tsconfig.integration.json\" AWS_SDK_LOAD_CONFIG=true BOOSTER_ENV=production mocha --forbid-only --exit --config \"integration/provider-specific/aws/nuke/.mocharc.yml\" \"integration/provider-specific/aws/nuke/**/*.integration.ts\"",
"integration/local": "TS_NODE_PROJECT=\"./tsconfig.integration.json\" npm run integration/local-start && npm run integration/local-end-to-end && npm run integration/local-stop",
"integration/local-ongoing": "TS_NODE_PROJECT=\"./tsconfig.integration.json\" npm run integration/local-start && npm run integration/local-stop",
"integration/local-start": "TS_NODE_PROJECT=\"./tsconfig.integration.json\" BOOSTER_ENV=local mocha --forbid-only --config \"integration/provider-specific/local/start/.mocharc.yml\" \"integration/provider-specific/local/start/*.integration.ts\"",
"integration/local-start": "TS_NODE_PROJECT=\"./tsconfig.integration.json\" BOOSTER_ENV=local mocha --forbid-only --exit --config \"integration/provider-specific/local/start/.mocharc.yml\" \"integration/provider-specific/local/start/*.integration.ts\"",
"integration/local-func": "TS_NODE_PROJECT=\"./tsconfig.integration.json\" TESTED_PROVIDER=LOCAL BOOSTER_ENV=local mocha --forbid-only --exit --config \"integration/provider-unaware/functionality/.mocharc.yml\" \"integration/provider-unaware/functionality/**/*.integration.ts\"",
"integration/local-end-to-end": "TS_NODE_PROJECT=\"./tsconfig.integration.json\" TESTED_PROVIDER=LOCAL BOOSTER_ENV=local mocha --forbid-only --exit --config \"integration/provider-unaware/end-to-end/.mocharc.yml\" \"integration/provider-unaware/end-to-end/**/*.integration.ts\"",
"integration/local-stop": "TS_NODE_PROJECT=\"./tsconfig.integration.json\" BOOSTER_ENV=local mocha --forbid-only --exit --config \"integration/provider-specific/local/stop/.mocharc.yml\" \"integration/provider-specific/local/stop/*.integration.ts\"",
Expand Down
31 changes: 31 additions & 0 deletions packages/framework-integration-tests/src/common/my-logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Logger } from '@boostercloud/framework-types'

export class MyLogger implements Logger {
debug(message?: any, ...optionalParams: any[]): void {
console.log(`[DEBUG] ${message?.toString()}`)
optionalParams.forEach((param) => {
console.log(`[DEBUG] ${param?.toString()}`)
})
}

info(message?: any, ...optionalParams: any[]): void {
console.log(`[INFO] ${message?.toString()}`)
optionalParams.forEach((param) => {
console.log(`[INFO] ${param?.toString()}`)
})
}

warn(message?: any, ...optionalParams: any[]): void {
console.log(`[WARN] ${message?.toString()}`)
optionalParams.forEach((param) => {
console.log(`[WARN] ${param?.toString()}`)
})
}

error(message?: any, ...optionalParams: any[]): void {
console.log(`[ERROR] ${message?.toString()}`)
optionalParams.forEach((param) => {
console.log(`[ERROR] ${param?.toString()}`)
})
}
}
1 change: 1 addition & 0 deletions packages/framework-integration-tests/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ function configureEventHub(config: BoosterConfig) {
Booster.configure('local', (config: BoosterConfig): void => {
config.appName = 'my-store'
config.providerPackage = '@boostercloud/framework-provider-local'
config.logger = new MyLogger()
config.tokenVerifiers = [
new PublicKeyTokenVerifier(
'booster',
Expand Down
17 changes: 15 additions & 2 deletions packages/framework-provider-local/src/services/event-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@ import { eventsDatabase } from '../paths'
const DataStore = require('@seald-io/nedb')

export class EventRegistry {
private readonly events
public readonly events
public isLoaded = false

constructor() {
this.events = new DataStore({ filename: eventsDatabase, autoload: true })
this.events = new DataStore({ filename: eventsDatabase })
}

async loadDatabaseIfNeeded(): Promise<void> {
if (!this.isLoaded) {
this.isLoaded = true
await this.events.loadDatabaseAsync()
}
}

getCursor(query: object, createdAt = 1, projections?: unknown) {
Expand All @@ -21,6 +29,7 @@ export class EventRegistry {
limit?: number,
projections?: unknown
): Promise<EventStoreEntryEnvelope[]> {
await this.loadDatabaseIfNeeded()
let cursor = this.getCursor(query, createdAt, projections)
if (limit) {
cursor = cursor.limit(Number(limit))
Expand All @@ -29,6 +38,7 @@ export class EventRegistry {
}

public async queryLatestSnapshot(query: object): Promise<EntitySnapshotEnvelope | undefined> {
await this.loadDatabaseIfNeeded()
const cursor = this.events.findAsync({ ...query, kind: 'snapshot' }).sort({ snapshottedEventCreatedAt: -1 }) // Sort in descending order (newer timestamps first)
const results = await cursor.execAsync()
if (results.length <= 0) {
Expand All @@ -38,14 +48,17 @@ export class EventRegistry {
}

public async store(storableObject: EventEnvelope | EntitySnapshotEnvelope): Promise<void> {
await this.loadDatabaseIfNeeded()
await this.events.insertAsync(storableObject)
}

public async deleteAll(): Promise<number> {
await this.loadDatabaseIfNeeded()
return await this.events.removeAsync({}, { multi: true })
}

public async count(query?: object): Promise<number> {
await this.loadDatabaseIfNeeded()
return await this.events.countAsync(query)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,18 @@ export const UNIQUE_VIOLATED_ERROR_TYPE = 'uniqueViolated'

export class ReadModelRegistry {
public readonly readModels
public isLoaded = false

constructor() {
this.readModels = new DataStore({ filename: readModelsDatabase, autoload: true })
this.readModels.ensureIndex({ fieldName: 'uniqueKey', unique: true, sparse: true })
this.readModels = new DataStore({ filename: readModelsDatabase })
}

async loadDatabaseIfNeeded(): Promise<void> {
if (!this.isLoaded) {
this.isLoaded = true
await this.readModels.loadDatabaseAsync()
await this.readModels.ensureIndexAsync({ fieldName: 'uniqueKey', unique: true, sparse: true })
}
}

public async query(
Expand All @@ -23,6 +32,7 @@ export class ReadModelRegistry {
skip?: number,
limit?: number
): Promise<Array<ReadModelEnvelope>> {
await this.loadDatabaseIfNeeded()
let cursor = this.readModels.findAsync(query)
const sortByList = this.toLocalSortFor(sortBy)
if (sortByList) {
Expand All @@ -38,6 +48,7 @@ export class ReadModelRegistry {
}

public async store(readModel: ReadModelEnvelope, expectedCurrentVersion: number): Promise<void> {
await this.loadDatabaseIfNeeded()
const uniqueReadModel: ReadModelEnvelope & { uniqueKey?: string } = readModel
uniqueReadModel.uniqueKey = `${readModel.typeName}_${readModel.value.id}_${readModel.value.boosterMetadata?.version}`
if (uniqueReadModel.value.boosterMetadata?.version === 1) {
Expand All @@ -47,10 +58,12 @@ export class ReadModelRegistry {
}

private async insert(readModel: ReadModelEnvelope): Promise<void> {
await this.loadDatabaseIfNeeded()
await this.readModels.insertAsync(readModel)
}

private async update(readModel: ReadModelEnvelope, expectedCurrentVersion: number): Promise<void> {
await this.loadDatabaseIfNeeded()
const { numAffected } = await this.readModels.updateAsync(
{
typeName: readModel.typeName,
Expand All @@ -72,6 +85,7 @@ export class ReadModelRegistry {
}

public async deleteById(id: UUID, typeName: string): Promise<number> {
await this.loadDatabaseIfNeeded()
return await this.readModels.removeAsync({ typeName: typeName, 'value.id': id }, { multi: false })
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,31 @@ export type SimpleRegistryTypes = ConnectionData | SubscriptionEnvelope

export class WebSocketRegistry {
public datastore
public isLoaded = false

constructor(connectionsDatabase: string) {
this.datastore = new DataStore({ filename: connectionsDatabase, autoload: true })
this.addIndexes()
this.datastore = new DataStore({ filename: connectionsDatabase })
}

addIndexes(): void {
async loadDatabaseIfNeeded(): Promise<void> {
if (!this.isLoaded) {
this.isLoaded = true
await this.datastore.loadDatabaseAsync()
await this.addIndexes()
}
}

async addIndexes(): Promise<void> {
const maxDurationInSeconds = 2 * 24 * 60 * 60 // 2 days
this.datastore.ensureIndex({ fieldName: 'expirationTime', expireAfterSeconds: maxDurationInSeconds })
this.datastore.ensureIndexAsync({ fieldName: 'expirationTime', expireAfterSeconds: maxDurationInSeconds })
}

getCursor(query: object, createdAt = 1, projections?: unknown) {
return this.datastore.findAsync(query, projections).sort({ createdAt: createdAt })
}

public async query(query: object, createdAt = 1, limit?: number, projections?: unknown): Promise<unknown> {
await this.loadDatabaseIfNeeded()
let cursor = this.getCursor(query, createdAt, projections)
if (limit) {
cursor = cursor.limit(Number(limit))
Expand All @@ -34,18 +43,22 @@ export class WebSocketRegistry {
}

public async store(envelope: SimpleRegistryTypes): Promise<void> {
await this.loadDatabaseIfNeeded()
await this.datastore.insertAsync(envelope)
}

public async delete(query: unknown): Promise<number> {
await this.loadDatabaseIfNeeded()
return await this.datastore.removeAsync(query, { multi: true })
}

public async deleteAll(): Promise<number> {
await this.loadDatabaseIfNeeded()
return await this.datastore.removeAsync({}, { multi: true })
}

public async count(query?: object): Promise<number> {
await this.loadDatabaseIfNeeded()
return await this.datastore.countAsync(query)
}
}

0 comments on commit 437d0f9

Please sign in to comment.