Skip to content

Commit

Permalink
fix(ci): fix ci test stability (#1185)
Browse files Browse the repository at this point in the history
  • Loading branch information
garrappachc authored Aug 23, 2021
1 parent bf384f5 commit d7132d0
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 35 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"prod": "node dist/src/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\"",
"test": "jest --watch",
"test:ci": "jest --ci --maxWorkers 4",
"test:ci": "NODE_ENV=test node --trace-warnings node_modules/.bin/jest --ci --runInBand --forceExit",
"test:e2e": "NODE_ENV=test jest --config e2e.jest.config.ts --runInBand --forceExit",
"release": "release-it"
},
Expand Down
5 changes: 4 additions & 1 deletion src/games/services/game-event-handler.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ describe('GameEventHandlerService', () => {
});

afterEach(async () => {
service.onModuleDestroy();
// @ts-expect-error
await gamesService._reset();
// @ts-expect-error
Expand Down Expand Up @@ -167,7 +168,9 @@ describe('GameEventHandlerService', () => {
// eslint-disable-next-line jest/expect-expect
it('should emit the substituteRequestsChange event', async () =>
new Promise<void>((resolve) => {
events.substituteRequestsChange.subscribe(resolve);
events.substituteRequestsChange.subscribe(() =>
setImmediate(resolve),
);
service.onMatchEnded(mockGame.id);
}));
});
Expand Down
21 changes: 14 additions & 7 deletions src/games/services/game-event-handler.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Injectable, Logger } from '@nestjs/common';
import { Injectable, Logger, OnModuleDestroy } from '@nestjs/common';
import { PlayersService } from '@/players/services/players.service';
import { PlayerConnectionStatus } from '../models/player-connection-status';
import { GameRuntimeService } from './game-runtime.service';
Expand All @@ -12,8 +12,9 @@ import { Model, Types } from 'mongoose';
import { Tf2ClassName } from '@/shared/models/tf2-class-name';

@Injectable()
export class GameEventHandlerService {
export class GameEventHandlerService implements OnModuleDestroy {
private logger = new Logger(GameEventHandlerService.name);
private timers: NodeJS.Timer[] = [];

constructor(
@InjectModel(Game.name) private gameModel: Model<GameDocument>,
Expand All @@ -22,6 +23,10 @@ export class GameEventHandlerService {
private events: Events,
) {}

onModuleDestroy() {
this.timers.forEach((t) => clearTimeout(t));
}

async onMatchStarted(gameId: string) {
const game = await this.gameModel.findOneAndUpdate(
{ _id: new Types.ObjectId(gameId), state: GameState.launching },
Expand Down Expand Up @@ -55,11 +60,13 @@ export class GameEventHandlerService {
this.events.substituteRequestsChange.next();

await this.freeAllMedics(game.id);
setTimeout(() => this.freeAllPlayers(game.id), 5000);

setTimeout(
() => this.gameRuntimeService.cleanupServer(game.gameServer.toString()),
serverCleanupDelay,
this.timers.push(setTimeout(() => this.freeAllPlayers(game.id), 5000));
this.timers.push(
setTimeout(
() =>
this.gameRuntimeService.cleanupServer(game.gameServer.toString()),
serverCleanupDelay,
),
);
} else {
this.logger.warn(`no such game: ${gameId}`);
Expand Down
4 changes: 2 additions & 2 deletions src/games/services/game-launcher.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Injectable, Logger, Inject, forwardRef } from '@nestjs/common';
import { GamesService } from './games.service';
import { GameServersService } from '@/game-servers/services/game-servers.service';
import { ServerConfiguratorService } from './server-configurator.service';
import { Cron } from '@nestjs/schedule';
import { Cron, CronExpression } from '@nestjs/schedule';
import { Events } from '@/events/events';
import { GameState } from '../models/game-state';
import { ConfigurationService } from '@/configuration/services/configuration.service';
Expand Down Expand Up @@ -82,7 +82,7 @@ export class GameLauncherService {
}
}

@Cron('30 * * * * *') // every minute
@Cron(CronExpression.EVERY_MINUTE) // every minute
async launchOrphanedGames() {
const orphanedGames = await this.gamesService.getOrphanedGames();
for (const game of orphanedGames) {
Expand Down
6 changes: 3 additions & 3 deletions src/games/services/game-runtime.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ describe('GameRuntimeService', () => {
describe('when an rcon error occurs', () => {
beforeEach(() => {
serverConfiguratorService.configureServer = () =>
Promise.reject('FAKE_RCON_ERROR');
Promise.reject(new Error('FAKE_RCON_ERROR'));
});

it('should handle the error', async () => {
Expand Down Expand Up @@ -222,7 +222,7 @@ describe('GameRuntimeService', () => {
describe('when an rcon error occurs', () => {
beforeEach(() => {
serverConfiguratorService.configureServer = () =>
Promise.reject('FAKE_RCON_ERROR');
Promise.reject(new Error('FAKE_RCON_ERROR'));
});

it('should handle the error', async () => {
Expand Down Expand Up @@ -341,7 +341,7 @@ describe('GameRuntimeService', () => {

describe('when an rcon error occurs', () => {
beforeEach(() => {
rcon.send = () => Promise.reject('fake rcon error');
rcon.send = () => Promise.reject(new Error('fake rcon error'));
});

it('should close the RCON connection', async () => {
Expand Down
1 change: 1 addition & 0 deletions src/players/services/online-players.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ describe('OnlinePlayersService', () => {
afterEach(() => jest.useRealTimers());

beforeEach(() => service.onModuleInit());
afterEach(() => service.onModuleDestroy());

it('should be defined', () => {
expect(service).toBeDefined();
Expand Down
22 changes: 17 additions & 5 deletions src/players/services/online-players.service.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { Events } from '@/events/events';
import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import {
Injectable,
Logger,
OnModuleDestroy,
OnModuleInit,
} from '@nestjs/common';
import { Socket } from 'socket.io';
import { PlayersGateway } from '../gateways/players.gateway';

type SocketList = Socket[];

@Injectable()
export class OnlinePlayersService implements OnModuleInit {
export class OnlinePlayersService implements OnModuleInit, OnModuleDestroy {
private readonly verifyPlayerTimeout = 10 * 1000; // 10 seconds
private logger = new Logger(OnlinePlayersService.name);
private sockets = new Map<string, SocketList>();
private timers: NodeJS.Timeout[] = [];

constructor(private playersGateway: PlayersGateway, private events: Events) {}

Expand All @@ -34,14 +40,20 @@ export class OnlinePlayersService implements OnModuleInit {
player.id,
sockets.filter((s) => s !== socket),
);
setTimeout(
() => this.verifyPlayer(player.id),
this.verifyPlayerTimeout,
this.timers.push(
setTimeout(
() => this.verifyPlayer(player.id),
this.verifyPlayerTimeout,
),
);
}
});
}

onModuleDestroy() {
this.timers.forEach((t) => clearTimeout(t));
}

getSocketsForPlayer(playerId: string) {
return this.sockets.get(playerId) ?? [];
}
Expand Down
4 changes: 0 additions & 4 deletions src/players/services/player-skill.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,8 @@ import {
playerSkillSchema,
} from '../models/player-skill';
import { ObjectId } from 'mongodb';
import { QueueConfigService } from '@/queue/services/queue-config.service';
import { FuturePlayerSkillService } from './future-player-skill.service';
import { Etf2lProfileService } from './etf2l-profile.service';
import { Player, PlayerDocument, playerSchema } from '../models/player';
import { DiscordService } from '@/plugins/discord/services/discord.service';
import { Environment } from '@/environment/environment';
import { Events } from '@/events/events';
import { Tf2ClassName } from '@/shared/models/tf2-class-name';
import { Model } from 'mongoose';
Expand Down
18 changes: 6 additions & 12 deletions src/utils/testing-mongoose-module.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import { MongooseModule } from '@nestjs/mongoose';
import { MongoMemoryServer } from 'mongodb-memory-server';

export const mongooseTestingModule = (mongod?: MongoMemoryServer) =>
MongooseModule.forRootAsync({
useFactory: async () => {
mongod = mongod ?? (await MongoMemoryServer.create());
return {
uri: mongod.getUri(),
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true,
};
},
export const mongooseTestingModule = (mongod: MongoMemoryServer) =>
MongooseModule.forRoot(mongod.getUri(), {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true,
});

0 comments on commit d7132d0

Please sign in to comment.