Skip to content

Commit d6ef6c5

Browse files
test: improve memory management
1 parent d61d554 commit d6ef6c5

File tree

192 files changed

+635
-882
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

192 files changed

+635
-882
lines changed

apps/ledger-live-desktop/tests/fixtures/common.ts

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import { captureArtifacts } from "tests/utils/allureUtils";
1414
import { randomUUID } from "crypto";
1515
import { AppInfos } from "@ledgerhq/live-common/e2e/enum/AppInfos";
1616
import { lastValueFrom, Observable } from "rxjs";
17-
import { CLI } from "../utils/cliUtils";
1817

1918
type TestFixtures = {
2019
lang: string;

apps/ledger-live-mobile/detox.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ module.exports = {
2525
},
2626
launchApp: "auto",
2727
cleanup: {
28-
shutdownDevice: false,
28+
shutdownDevice: process.env.CI ? true : false,
2929
},
3030
},
3131
apps: {

apps/ledger-live-mobile/e2e/bridge/proxy.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable global-require */
21
import { log, listen } from "@ledgerhq/logs";
32
import { open, registerTransportModule, TransportModule } from "@ledgerhq/live-common/hw/index";
43
import http from "http";
@@ -7,7 +6,7 @@ import cors from "cors";
76
import WebSocket from "ws";
87
import bodyParser from "body-parser";
98
import os from "os";
10-
import { Observable, Subscription } from "rxjs";
9+
import { Observable } from "rxjs";
1110
import SpeculosHttpTransport, {
1211
SpeculosHttpTransportOpts,
1312
} from "@ledgerhq/hw-transport-node-speculos-http";
@@ -16,8 +15,6 @@ import { Buffer } from "buffer";
1615
import { getEnv } from "@ledgerhq/live-env";
1716
import invariant from "invariant";
1817

19-
const proxySubscriptions = new Map<number, { port: number; subscription: Subscription }>();
20-
2118
let transport: TransportModule;
2219

2320
interface ProxyOptions {

apps/ledger-live-mobile/e2e/bridge/server.ts

+39-20
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { Server, WebSocket } from "ws";
1+
import { Server } from "ws";
22
import path from "path";
33
import fs from "fs";
44
import net from "net";
55
import merge from "lodash/merge";
6-
import { toAccountRaw } from "@ledgerhq/live-common/account/index";
6+
77
import { NavigatorName } from "../../src/const";
88
import { Subject } from "rxjs";
99
import { BleState, DeviceLike } from "../../src/reducers/types";
@@ -12,12 +12,10 @@ import { DeviceUSB, nanoSP_USB, nanoS_USB, nanoX_USB } from "../models/devices";
1212
import { MessageData, MockDeviceEvent, ServerData } from "./types";
1313
import { getDeviceModel } from "@ledgerhq/devices";
1414
import { SettingsSetOverriddenFeatureFlagsPlayload } from "~/actions/types";
15+
import { log as detoxLog } from "detox";
1516

1617
export const e2eBridgeServer = new Subject<ServerData>();
17-
18-
let wss: Server;
19-
let webSocket: WebSocket;
20-
const lastMessages: { [id: string]: MessageData } = {}; // Store the last messages not sent
18+
let lastMessages: { [id: string]: MessageData } = {}; // Store the last messages not sent
2119
let clientResponse: (data: string) => void;
2220
const RESPONSE_TIMEOUT = 10000;
2321

@@ -52,16 +50,20 @@ function uniqueId(): string {
5250
return timestamp + randomString; // Concatenate timestamp and random string
5351
}
5452

55-
// eslint-disable-next-line @typescript-eslint/no-empty-function
56-
export function init(port = 8099, onConnection = () => {}) {
57-
wss = new Server({ port });
53+
export function init(port = 8099, onConnection?: () => void) {
54+
webSocket.wss = new Server({ port });
5855
log(`Start listening on localhost:${port}`);
5956

60-
wss.on("connection", ws => {
57+
webSocket.wss.on("connection", ws => {
6158
log(`Client connected`);
62-
onConnection();
63-
webSocket = ws;
59+
onConnection && onConnection();
60+
webSocket.ws?.close();
61+
webSocket.ws = ws;
6462
ws.on("message", onMessage);
63+
ws.on("close", () => {
64+
log("Client disconnected");
65+
webSocket.ws = undefined; // Free memory
66+
});
6567
if (Object.keys(lastMessages).length !== 0) {
6668
log(`Sending unsent messages`);
6769
Object.values(lastMessages).forEach(message => {
@@ -72,8 +74,24 @@ export function init(port = 8099, onConnection = () => {}) {
7274
}
7375

7476
export function close() {
75-
webSocket?.close();
76-
wss?.close();
77+
if (webSocket.ws) {
78+
webSocket.ws.removeAllListeners();
79+
webSocket.ws.close();
80+
webSocket.ws = undefined;
81+
}
82+
83+
if (webSocket.wss) {
84+
webSocket.wss.clients.forEach(client => {
85+
client.removeAllListeners();
86+
client.terminate();
87+
});
88+
89+
webSocket.wss.close(() => {
90+
log("WebSocket server closed");
91+
webSocket.wss = undefined;
92+
});
93+
}
94+
lastMessages = {};
7795
}
7896

7997
export async function loadConfig(fileName: string, agreed: true = true): Promise<void> {
@@ -86,12 +104,12 @@ export async function loadConfig(fileName: string, agreed: true = true): Promise
86104
const { data } = JSON.parse(f.toString());
87105

88106
const defaultSettings = { shareAnalytics: true, hasSeenAnalyticsOptInPrompt: true };
89-
const settings = merge(defaultSettings, data.settings);
107+
const settings = merge(defaultSettings, data.settings || {});
90108
await postMessage({ type: "importSettings", id: uniqueId(), payload: settings });
91109

92110
navigate(NavigatorName.Base);
93111

94-
if (data.accounts.length) {
112+
if (data.accounts?.length) {
95113
await postMessage({ type: "importAccounts", id: uniqueId(), payload: data.accounts });
96114
}
97115
}
@@ -118,6 +136,8 @@ export async function loadAccountsRaw(
118136
}
119137

120138
export async function loadAccounts(accounts: Account[]) {
139+
delete require.cache[require.resolve("@ledgerhq/live-common/account/index")]; // Clear cache
140+
const toAccountRaw = require("@ledgerhq/live-common/account/index").toAccountRaw;
121141
await postMessage({
122142
type: "importAccounts",
123143
id: uniqueId(),
@@ -244,8 +264,7 @@ function onMessage(messageStr: string) {
244264
}
245265

246266
function log(message: string) {
247-
// eslint-disable-next-line no-console
248-
console.log(`[E2E Bridge Server]: ${message}`);
267+
detoxLog.info(`[E2E Bridge Server]: ${message}`);
249268
}
250269

251270
async function acceptTerms() {
@@ -256,8 +275,8 @@ async function postMessage(message: MessageData) {
256275
log(`Message sending ${message.type}: ${message.id}`);
257276
try {
258277
lastMessages[message.id] = message;
259-
if (webSocket) {
260-
webSocket.send(JSON.stringify(message));
278+
if (webSocket.ws) {
279+
webSocket.ws.send(JSON.stringify(message));
261280
} else {
262281
log("WebSocket connection is not open. Message not sent.");
263282
}

apps/ledger-live-mobile/e2e/bridge/start-server.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ https://ledgerhq.atlassian.net/wiki/spaces/PTX/pages/4295000160/Switch+devices+w
1414

1515
import { access, constants } from "fs";
1616
import path from "path";
17-
import * as serverBridge from "./server";
17+
import { init, loadConfig } from "./server";
1818

1919
const filePath = process.argv[2];
2020

@@ -25,9 +25,9 @@ access(fullFilePath, constants.F_OK, err => {
2525
throw new Error(`${fullFilePath} does not exist`);
2626
} else {
2727
// starts the server
28-
serverBridge.init(undefined, () => {
28+
init(undefined, () => {
2929
// this is run when the server receives a connection - in this case when the app finishes loading and calls the bridge client `init` function
30-
serverBridge.loadConfig(filePath, true);
30+
loadConfig(filePath, true);
3131
});
3232
}
3333
});

0 commit comments

Comments
 (0)