Skip to content

Commit

Permalink
Fix: tests don't trample over each other
Browse files Browse the repository at this point in the history
  • Loading branch information
stephhuynh18 committed Mar 12, 2024
1 parent 95e995b commit 765c936
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 43 deletions.
55 changes: 22 additions & 33 deletions src/services/__tests__/task-scheduler-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,32 @@ import 'reflect-metadata'
import { jest, describe, test, expect } from '@jest/globals'
import { TaskSchedulerService } from '../task-scheduler-service.js'
import { Utils } from '../../utils.js'
import { TestUtils } from '@ceramicnetwork/common'

describe('scheduler service', () => {
jest.setTimeout(20000)

test('will run the task repeatedly', (done) => {
test('will run the task repeatedly', async () => {
const numberOfRunsBeforeDone = 3

const task = jest.fn()
const testScheduler = new TaskSchedulerService()

const runChecks = () => {
// the task runs once right at the start before running every X seconds
expect(task.mock.calls.length).toEqual(numberOfRunsBeforeDone + 1)
done()
}

let count = 0
task.mockImplementation(async () => {
if (count === numberOfRunsBeforeDone) {
testScheduler.stop()
runChecks()
}

count = count + 1
return Promise.resolve()
})

testScheduler.start(task as any, 1000)
// test doesn't complete until 'done()' is called
await TestUtils.delay(1000 * numberOfRunsBeforeDone)
await testScheduler.stop()
expect(task.mock.calls.length).toBeGreaterThanOrEqual(numberOfRunsBeforeDone)
})

test('will stop if the task fails', (done) => {
test('will stop if the task fails', async () => {
const mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {})

const task = jest.fn()
const testScheduler = new TaskSchedulerService()

Expand All @@ -42,42 +36,37 @@ describe('scheduler service', () => {
count = count + 1

if (count === 2) {
return Promise.reject('test error')
throw Error('test error')
}

return Promise.resolve()
return
})

testScheduler.start(task as any, 1000)
// @ts-ignore
testScheduler._subscription?.add(() => {
expect(task.mock.calls.length).toEqual(2)
testScheduler.stop()
done()
await TestUtils.waitForConditionOrTimeout(async () => {
// @ts-ignore
return testScheduler._subscription?.closed || false
})
// test doesn't complete until 'done()' is called
expect(mockExit).toHaveBeenCalled()
})

test('Will complete current task if stop is called', (done) => {
test('Will complete current task if stop is called', async () => {
let calls = 0
const task = async () => {
await Utils.delay(2000)
calls = calls + 1
}

const testScheduler = new TaskSchedulerService()

testScheduler.start(task as any, 1000)
await Utils.delay(500)
// stop is called during the task
// stop should only return once the task completes
Utils.delay(1000).then(async () => {
await testScheduler.stop()
await Utils.delay(3000)
// task should have compelted once
expect(calls).toEqual(1)
done()
})

testScheduler.start(task as any, 1000)
// test doesn't complete until 'done()' is called
await testScheduler.stop()
await Utils.delay(3000)
// task should have completed once
expect(calls).toEqual(1)
})

test('Will run cbAfterNoOp after failure if set', async () => {
Expand Down
9 changes: 4 additions & 5 deletions src/services/task-scheduler-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import {
concatMap,
EMPTY,
} from 'rxjs'
import { ServiceMetrics as Metrics } from '@ceramicnetwork/observability'
import { METRIC_NAMES } from '../settings.js'

/**
* Repeatedly triggers a task to be run after a configured amount of ms
Expand Down Expand Up @@ -49,9 +47,6 @@ export class TaskSchedulerService {
return await task().then((result) => result === undefined || result)
}).pipe(
catchError((err: Error) => {
Metrics.count(METRIC_NAMES.SCHEDULER_TASK_UNCAUGHT_ERROR, 1)
logger.err(`Scheduler task failed: ${err}`)

if (this._controller.signal.aborted) {
return EMPTY
}
Expand Down Expand Up @@ -79,6 +74,10 @@ export class TaskSchedulerService {
complete: async () => {
if (cbAfterNoOp) await cbAfterNoOp()
},
error: (err) => {
logger.err(`Task scheduler exiting because of error: ${err}`)
process.exit(1)
},
})
}

Expand Down
5 changes: 0 additions & 5 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ export enum METRIC_NAMES {
WITNESS_CAR_CACHE_HIT = 'witness_car_cache_hit',
WITNESS_CAR_CACHE_MISS = 'witness_car_cache_miss',

// *******************************************************************//
// Scheduler Service
SCHEDULER_TASK_UNCAUGHT_ERROR = 'scheduler_task_uncaught_error',

// *******************************************************************//
// Ceramic Service
PIN_SUCCEEDED = 'pin_succeeded',
Expand All @@ -80,4 +76,3 @@ export enum METRIC_NAMES {
REQUEST_NOT_CREATED = 'request_not_created',
REQUEST_NOT_FOUND = 'request_not_found',
}

0 comments on commit 765c936

Please sign in to comment.