Skip to content

Commit

Permalink
Create subdirectory before creating service account JSON (#187)
Browse files Browse the repository at this point in the history
* Update socket tests (#185)

* Update socket tests

* Remove unused type

* Update comment in socketio.test.ts

---------

Co-authored-by: Phoenix <[email protected]>

* Create subdirectory before creating service account JSON

---------

Co-authored-by: Phoenix <[email protected]>
  • Loading branch information
aaditkamat and h1divp authored Feb 26, 2024
1 parent e21e357 commit 473fed4
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 128 deletions.
10 changes: 8 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@ jobs:
run: npm ci
working-directory: server/

- name: Create subdirectory for service account JSON
run: |
mkdir private_key
working-directory: server/src

- name: Create service account JSON
id: create-service-acount-json
id: create-service-account-json
uses: jsdaniell/[email protected]
with:
name: "server/src/private_key/private.json"
name: "private.json"
json: ${{ secrets.SERVICE_ACCOUNT_SECRET }}
dir: 'server/src/private_key/'

- name: Compile TypeScript files
run: npx tsc
Expand Down
294 changes: 168 additions & 126 deletions server/src/tests/socketio.test.ts
Original file line number Diff line number Diff line change
@@ -1,146 +1,188 @@
// Testing for socket.io endpoints

import { io as io } from 'socket.io-client'
import { v4 as uuidv4 } from 'uuid';
import { Message } from '../types/Message';
import { createServer } from "node:http";
import { io as ioc } from "socket.io-client";
import { Server } from "socket.io";
import { v4 as uuidv4 } from "uuid";

const socket_test_client_port = process.env.socket_test_client_port;
console.log("Socket clients are listening on port", socket_test_client_port)

const SECONDS_TIMEOUT = 10;
const SECONDS_MULTIPLIER = 1000;
const NUM_CLIENTS = 3; // Adjust the number of clients as needed. Do not go over 300 to prevent being blocked by Firebase.
const exampleMsg: Message = {
uid: uuidv4(), // random Ids; not a real UID
msgId: uuidv4(),
msgContent: "MESSAGE CONTENT",
timeSent: 9999,
location: {
lat: 10,
lon: 10
// Geohash will be calculated by the server since it is not included with the message.
jest.setTimeout(60 * SECONDS_MULTIPLIER);

describe("socket-load-tests", () => {
let clientSockets = [];
let httpServer;
let httpServerAddr;
let ioServer;
const numClients = 100; // Adjust the number of clients as needed. Do not go over 300 to prevent being blocked by Firebase.

beforeAll((done) => {
httpServer = createServer().listen();
httpServerAddr = httpServer.address();
ioServer = new Server(httpServer);
for (let i = 0; i < numClients; i++) {
let clientSocket = ioc(
`http://[${httpServerAddr.address}]:${httpServerAddr.port}`,
{
forceNew: true,
reconnectionDelay: 0,
transports: ["websocket"],
}
);
clientSocket.on("connect", () => {
done();
});
clientSockets.push(clientSocket);
}
}

jest.setTimeout(SECONDS_TIMEOUT * SECONDS_MULTIPLIER);

const sleep = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms));
};

const connectClients = async () => {
const clients = [];

for (let i = 0; i < NUM_CLIENTS; i++) {
const client = io(`http://localhost:${socket_test_client_port}`);
await new Promise<void>(resolve => client.on('connect', resolve)); // Why is this an error? IDK
clients.push(client);
}

return clients;
};
done();
});

const disconnectClients = (clients) => {
clients.forEach(client => client.disconnect());
};
afterAll((done) => {
ioServer.close();
httpServer.close();
for (let i = 0; i < numClients; i++) {
clientSockets[i].disconnect();
}
done();
});

describe('socket-load-tests', () => {
let clients;
test("Simultaneous Ping", (done) => {
ioServer.on("ping", (cb) => {
cb("pong");
});
for (let i = 0; i < numClients; i++) {
clientSockets[i].emit("ping", (response) => {
expect(response).toBe("pong");
});
}
done();
});

beforeAll(async () => {
clients = await connectClients();
test("Simultaneous Message", async () => {
ioServer.on("ping", (cb) => {
cb("pong");
});
for (let i = 0; i < numClients; i++) {
clientSockets[i].emit(
"message",
{
userId: "userId",
msgId: uuidv4(),
msgContent: `This is message ${i}`,
lat: 10,
lon: 10,
timeSent: 99999999,
},
(response) => {
expect(response).toBe("message recieved");
}
);
}
});
});

afterAll(() => {
disconnectClients(clients);
describe("socket-tests", () => {
let clientSockets = [];
let httpServer;
let httpServerAddr;
let ioServer;
const numClients = 5;

beforeAll((done) => {
httpServer = createServer().listen();
httpServerAddr = httpServer.address();
ioServer = new Server(httpServer);
for (let i = 0; i < numClients; i++) {
let clientSocket = ioc(
`http://[${httpServerAddr.address}]:${httpServerAddr.port}`,
{
reconnectionDelay: 0,
forceNew: true,
transports: ["websocket"],
}
);
clientSocket.on("connect", () => {
done();
});
clientSockets.push(clientSocket);
}
done();
});

test('Simultaneous Ping', async () => {
const pingPromises = clients.map(client => new Promise(resolve => client.emit('ping', resolve)));
const responses = await Promise.all(pingPromises);
afterAll((done) => {
ioServer.close();
httpServer.close();
for (let i = 0; i < numClients; i++) {
clientSockets[i].disconnect();
}
done();
});

responses.forEach(response => {
expect(response).toBe('pong');
test("Ping", (done) => {
ioServer.on("ping", (cb) => {
cb("pong");
});
clientSockets[0].emit("ping", (response) => {
expect(response).toBe("pong");
});
done();
});

test('Simultaneous Message', async () => {
let count = 0;
const messagePromises = clients.map(client => {
return new Promise(async resolve => {
client.emit('message', exampleMsg, resolve);
count++;
await sleep(200)
});
test("Send message", (done) => {
ioServer.on("ping", (cb) => {
cb("pong");
});

const responses = await Promise.all(messagePromises);
responses.forEach(response => {
expect(response).toBe('message recieved');
const msgObject = {
userId: "userId",
msgId: "hiii 33 :3",
msgContent: "messageContent",
lat: 10,
lon: 10,
timeSent: 99999999,
};
clientSockets[0].emit("message", msgObject, (response) => {
expect(response).toBe("message recieved");
});
})
});

describe("socket-tests", () => {
let user1, user2

beforeAll((done) => {
user1 = io(`http://localhost:${socket_test_client_port}`)
user1.on('connect', done)
user2 = io(`http://localhost:${socket_test_client_port}`)
user2.on('connect', done)
})
done();
});

afterAll(() => {
user1.disconnect()
user2.disconnect()
})
test("Update locations", (done) => {
const userCoords = [
{ lat: 29.64888, lon: -82.3442 }, // Turlington Hall pin on Google Maps
{ lat: 29.64881, lon: -82.34429 }, // 8.65 meters SW of user 1
{ lat: 29.64881, lon: -82.34429 }, // 8.65 meters SW of user 1
{ lat: 29.64881, lon: -82.34429 }, // 8.65 meters SW of user 1
{ lat: 29.64881, lon: -82.34429 }, // 8.65 meters SW of user 1
];

for (let i = 0; i < userCoords.length; i++) {
clientSockets[i].emit("updateLocation", userCoords[0], (response) => {
expect(response).toBe("location updated");
});
}
done();
});

test('Ping', (done) => {
user1.emit('ping', (response) => {
expect(response).toBe('pong')
done()
})
})
test('Send message', (done) => {
user1.emit('message', exampleMsg, (response) => {
expect(response).toBe('message recieved')
done()
})
})
test('Update locations', (done) => {
const user1Coords = { lat: 29.64888, lon: -82.34420 } // Turlington Hall pin on Google Maps
const user2Coords = { lat: 29.64881, lon: -82.34429 } // 8.65 meters SW of user 1
user1.emit('updateLocation', user1Coords, (response) => {
expect(response).toBe("location updated")
})
user2.emit('updateLocation', user2Coords, (response) => {
expect(response).toBe("location updated")
})
sleep(5000)
done()
})
// test('Send message to user', async (done) => {
// // const user2Coords = { lat: 29.64881, lon: -82.34429 } // 8.65 meters SW of user 1
// const user2Coords = { lat: 29.6489940, lon: -82.344096 } // 8.65 meters SW of user 1
// const user2Message: Message = {
// uid: user2.id, // a socket id
// msgId: uuidv4(),
// msgContent: "omggg hi!!!! :3",
// timeSent: 9999,
// location: {
// lat: user2Coords.lat,
// lon: user2Coords.lon
// // Geohash will be calculated by the server since it is not included with the message.
// }
// }
// user1.on('message', (message: Message) => {
// console.log(`User 2 recieved message: ${message}`)
// expect(message.msgContent).toBe("omggg hi!!!! :3")
// })
// await sleep(200) // use sleep if test case doesn't work for some reason
// user2.emit('message', user2Message)
// })
// IMPORTANT: The returned messages should appear in console. The correct way to use expect() has not been figured out yet for this test.
// TODO: Find a way for expect() to be verified after messages return.
})
test("Send message to user", (done) => {
const user2Coords = { lat: 29.64881, lon: -82.34429 }; // 8.65 meters SW of user 1
const user2Message = {
userId: clientSockets[1].id,
msgId: "testid",
msgContent: "omggg hi!!!! :3",
lat: user2Coords.lat,
lon: user2Coords.lon,
timeSent: 999999,
};
for (let i = 0; i < clientSockets.length; i++) {
if (i != 1) {
clientSockets[i].on("message", (message) => {
console.log(`User 2 recieved message ${message}`);
expect(message).toBe("omggg hi!!!! :3");
});
}
}
clientSockets[1].emit("message", user2Message);
done();
// TODO: This test case will return true, but the sent message is actually never verified.
// The real verification of this message to lead to a pass/fail should be worked on.
});
});

0 comments on commit 473fed4

Please sign in to comment.