From a44af269ceee4af81d7bb2700ba134525fbea3a3 Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Tue, 16 Jul 2024 07:55:36 +0800 Subject: [PATCH] feat: Add tests for findServicePort and localService - Implement unit tests for findAvailablePort function - Add integration tests for startLocalService and stopLocalService - Include HTTP request test to verify local service functionality --- test/util/findServicePort.test.ts | 29 +++++++++++++ test/util/localService.test.ts | 72 +++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 test/util/findServicePort.test.ts create mode 100644 test/util/localService.test.ts diff --git a/test/util/findServicePort.test.ts b/test/util/findServicePort.test.ts new file mode 100644 index 0000000..8ff59e5 --- /dev/null +++ b/test/util/findServicePort.test.ts @@ -0,0 +1,29 @@ +// test/util/findServicePort.test.ts + +import { expect } from 'chai'; +import net from 'net'; +import { findAvailablePort } from '../../src/util/findServicePort'; + +describe('findAvailablePort', () => { + it('should return an available port when successful', async () => { + // Arrange + const expectedPort = await findAvailablePort(); + + // Act + const server = net.createServer(); + const isAvailable = await new Promise((resolve) => { + server.listen(expectedPort, () => { + server.close(); + resolve(true); + }); + server.on('error', () => { + resolve(false); + }); + }); + + // Assert + expect(isAvailable).to.be.true; + expect(expectedPort).to.be.a('number'); + expect(expectedPort).to.be.greaterThan(0); + }); +}); \ No newline at end of file diff --git a/test/util/localService.test.ts b/test/util/localService.test.ts new file mode 100644 index 0000000..1cd8cbc --- /dev/null +++ b/test/util/localService.test.ts @@ -0,0 +1,72 @@ +// test/util/localService.test.ts + +import { expect } from 'chai'; +import { startLocalService, stopLocalService } from '../../src/util/localService'; +import * as http from 'http'; + +describe('localService', () => { + let port: number; + + describe('startLocalService', () => { + it('should start the local service successfully', async () => { + const extensionPath = '.'; + const workspacePath = '.'; + + port = await startLocalService(extensionPath, workspacePath); + + expect(port).to.be.a('number'); + expect(process.env.DC_SVC_PORT).to.equal(port.toString()); + expect(process.env.DC_SVC_WORKSPACE).to.equal(workspacePath); + expect(process.env.DC_LOCALSERVICE_PORT).to.equal(port.toString()); + + // Verify that the service is running by sending a ping request + const response = await sendPingRequest(port); + expect(response).to.equal('{"message":"pong"}'); + }); + }); + + describe('stopLocalService', () => { + it('should stop the local service', async () => { + await stopLocalService(); + + // Wait a bit to ensure the service has fully stopped + await new Promise(resolve => setTimeout(resolve, 1000)); + + // Verify that the service is no longer running + try { + await sendPingRequest(port); + throw new Error('Service is still running'); + } catch (error) { + console.log('Error type:', typeof error); + console.log('Error:', error); + + if (error instanceof Error) { + expect(error.message).to.include('connect ECONNREFUSED'); + } else if (typeof error === 'object' && error !== null) { + // Check if the error object has a 'code' property + if ('code' in error) { + expect(error.code).to.equal('ECONNREFUSED'); + } else if ('errors' in error && Array.isArray(error.errors)) { + // Check if it's an AggregateError-like object + const hasConnectionRefused = error.errors.some((e: any) => e.code === 'ECONNREFUSED'); + expect(hasConnectionRefused).to.be.true; + } else { + throw new Error(`Unexpected error structure: ${JSON.stringify(error)}`); + } + } else { + throw new Error(`Unexpected error type: ${typeof error}`); + } + } + }); +}); +}); + +function sendPingRequest(port: number): Promise { + return new Promise((resolve, reject) => { + http.get(`http://localhost:${port}/ping`, (res) => { + let data = ''; + res.on('data', (chunk) => data += chunk); + res.on('end', () => resolve(data)); + }).on('error', reject); + }); +} \ No newline at end of file