genlayer 0.18.1 → 0.18.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/index.js +49 -29
- package/package.json +1 -1
- package/src/commands/contracts/call.ts +7 -49
- package/src/commands/contracts/deploy.ts +3 -2
- package/src/commands/contracts/index.ts +36 -11
- package/src/commands/contracts/write.ts +49 -0
- package/src/commands/general/init.ts +15 -20
- package/src/commands/general/start.ts +14 -10
- package/src/commands/keygen/create.ts +2 -2
- package/tests/actions/call.test.ts +22 -86
- package/tests/actions/create.test.ts +8 -8
- package/tests/actions/init.test.ts +173 -102
- package/tests/actions/start.test.ts +48 -24
- package/tests/actions/write.test.ts +102 -0
- package/tests/commands/write.test.ts +76 -0
- package/tests/libs/baseAction.test.ts +37 -26
- package/tests/services/simulator.test.ts +98 -102
|
@@ -1,29 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {describe, beforeEach, test, expect, vi, Mock} from "vitest";
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import * as fs from "fs";
|
|
4
4
|
import * as dotenv from "dotenv";
|
|
5
5
|
import simulatorService from "../../src/lib/services/simulator";
|
|
6
|
-
import {
|
|
7
|
-
getVersion,
|
|
8
|
-
executeCommand,
|
|
9
|
-
openUrl,
|
|
10
|
-
checkCommand,
|
|
11
|
-
} from "../../src/lib/clients/system";
|
|
6
|
+
import {getVersion, executeCommand, openUrl, checkCommand} from "../../src/lib/clients/system";
|
|
12
7
|
import {
|
|
13
8
|
CONTAINERS_NAME_PREFIX,
|
|
14
9
|
VERSION_REQUIREMENTS,
|
|
15
10
|
STARTING_TIMEOUT_ATTEMPTS,
|
|
16
|
-
DEFAULT_RUN_SIMULATOR_COMMAND,
|
|
17
|
-
|
|
11
|
+
DEFAULT_RUN_SIMULATOR_COMMAND,
|
|
12
|
+
localnetCompatibleVersion,
|
|
13
|
+
IMAGES_NAME_PREFIX,
|
|
14
|
+
AiProviders,
|
|
15
|
+
GENLAYER_REQUIRED_CONTAINERS,
|
|
18
16
|
} from "../../src/lib/config/simulator";
|
|
19
|
-
import {
|
|
17
|
+
import {rpcClient} from "../../src/lib/clients/jsonRpcClient";
|
|
20
18
|
import * as semver from "semver";
|
|
21
19
|
import Docker from "dockerode";
|
|
22
20
|
import {VersionRequiredError} from "../../src/lib/errors/versionRequired";
|
|
23
21
|
import updateCheck from "update-check";
|
|
24
22
|
|
|
25
23
|
vi.mock("../../package.json", () => ({
|
|
26
|
-
default: {
|
|
24
|
+
default: {version: "1.0.0", name: "genlayer"},
|
|
27
25
|
}));
|
|
28
26
|
|
|
29
27
|
vi.mock("update-check", () => ({
|
|
@@ -58,10 +56,9 @@ describe("SimulatorService - Basic Tests", () => {
|
|
|
58
56
|
vi.mocked(path.join).mockImplementation((...args) => args.join("/"));
|
|
59
57
|
});
|
|
60
58
|
|
|
61
|
-
|
|
62
59
|
test("should read the correct frontend URL from .env config", () => {
|
|
63
60
|
const mockEnvContent = "FRONTEND_PORT=8080";
|
|
64
|
-
const mockEnvConfig = {
|
|
61
|
+
const mockEnvConfig = {FRONTEND_PORT: "8080"};
|
|
65
62
|
vi.mocked(fs.readFileSync).mockReturnValue(mockEnvContent);
|
|
66
63
|
vi.mocked(dotenv.parse).mockReturnValue(mockEnvConfig);
|
|
67
64
|
const frontendUrl = simulatorService.getFrontendUrl();
|
|
@@ -85,39 +82,38 @@ describe("SimulatorService - Basic Tests", () => {
|
|
|
85
82
|
await expect(simulatorService.checkVersion("14.0.0", "node")).rejects.toThrow();
|
|
86
83
|
});
|
|
87
84
|
|
|
88
|
-
|
|
89
85
|
test("should return initialized true when simulator responds with OK (result.status = OK)", async () => {
|
|
90
|
-
vi.mocked(rpcClient.request).mockResolvedValueOnce({
|
|
86
|
+
vi.mocked(rpcClient.request).mockResolvedValueOnce({result: {status: "OK"}});
|
|
91
87
|
const result = await simulatorService.waitForSimulatorToBeReady(STARTING_TIMEOUT_ATTEMPTS);
|
|
92
|
-
expect(result).toEqual({
|
|
93
|
-
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
88
|
+
expect(result).toEqual({initialized: true});
|
|
89
|
+
expect(rpcClient.request).toHaveBeenCalledWith({method: "ping", params: []});
|
|
94
90
|
});
|
|
95
91
|
|
|
96
92
|
test("should return initialized true when simulator responds with OK (result.data.status = OK)", async () => {
|
|
97
|
-
vi.mocked(rpcClient.request).mockResolvedValueOnce({
|
|
93
|
+
vi.mocked(rpcClient.request).mockResolvedValueOnce({result: {data: {status: "OK"}}});
|
|
98
94
|
const result = await simulatorService.waitForSimulatorToBeReady(STARTING_TIMEOUT_ATTEMPTS);
|
|
99
|
-
expect(result).toEqual({
|
|
100
|
-
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
95
|
+
expect(result).toEqual({initialized: true});
|
|
96
|
+
expect(rpcClient.request).toHaveBeenCalledWith({method: "ping", params: []});
|
|
101
97
|
});
|
|
102
98
|
|
|
103
99
|
test("should return initialized true when simulator responds with OK (result = OK)", async () => {
|
|
104
|
-
vi.mocked(rpcClient.request).mockResolvedValueOnce({
|
|
100
|
+
vi.mocked(rpcClient.request).mockResolvedValueOnce({result: "OK"});
|
|
105
101
|
const result = await simulatorService.waitForSimulatorToBeReady(STARTING_TIMEOUT_ATTEMPTS);
|
|
106
|
-
expect(result).toEqual({
|
|
107
|
-
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
102
|
+
expect(result).toEqual({initialized: true});
|
|
103
|
+
expect(rpcClient.request).toHaveBeenCalledWith({method: "ping", params: []});
|
|
108
104
|
});
|
|
109
105
|
|
|
110
106
|
test("should return initialized false with errorCode TIMEOUT after retries", async () => {
|
|
111
107
|
vi.mocked(rpcClient.request).mockResolvedValue(undefined);
|
|
112
108
|
const result = await simulatorService.waitForSimulatorToBeReady(1);
|
|
113
|
-
expect(result).toEqual({
|
|
109
|
+
expect(result).toEqual({initialized: false, errorCode: "TIMEOUT"});
|
|
114
110
|
});
|
|
115
111
|
|
|
116
112
|
test("should return initialized false with errorCode ERROR on non-retryable error", async () => {
|
|
117
113
|
const nonRetryableError = new Error("Unexpected error");
|
|
118
114
|
vi.mocked(rpcClient.request).mockRejectedValue(nonRetryableError);
|
|
119
115
|
const result = await simulatorService.waitForSimulatorToBeReady(STARTING_TIMEOUT_ATTEMPTS);
|
|
120
|
-
expect(result).toEqual({
|
|
116
|
+
expect(result).toEqual({initialized: false, errorCode: "ERROR", errorMessage: nonRetryableError.message});
|
|
121
117
|
});
|
|
122
118
|
|
|
123
119
|
test("should execute the correct run simulator command based on simulator location", async () => {
|
|
@@ -126,9 +122,9 @@ describe("SimulatorService - Basic Tests", () => {
|
|
|
126
122
|
stderr: "",
|
|
127
123
|
});
|
|
128
124
|
const result = await simulatorService.runSimulator();
|
|
129
|
-
const expectedCommand = DEFAULT_RUN_SIMULATOR_COMMAND(simulatorService.location,
|
|
125
|
+
const expectedCommand = DEFAULT_RUN_SIMULATOR_COMMAND(simulatorService.location, "");
|
|
130
126
|
expect(executeCommand).toHaveBeenCalledWith(expectedCommand);
|
|
131
|
-
expect(result).toEqual({
|
|
127
|
+
expect(result).toEqual({stdout: "Simulator started", stderr: ""});
|
|
132
128
|
});
|
|
133
129
|
|
|
134
130
|
test("should execute the correct run simulator command based on headless option", async () => {
|
|
@@ -136,12 +132,12 @@ describe("SimulatorService - Basic Tests", () => {
|
|
|
136
132
|
stdout: "Simulator started",
|
|
137
133
|
stderr: "",
|
|
138
134
|
});
|
|
139
|
-
simulatorService.setComposeOptions(true)
|
|
135
|
+
simulatorService.setComposeOptions(true);
|
|
140
136
|
const commandOption = simulatorService.getComposeOptions();
|
|
141
137
|
const result = await simulatorService.runSimulator();
|
|
142
138
|
const expectedCommand = DEFAULT_RUN_SIMULATOR_COMMAND(simulatorService.location, commandOption);
|
|
143
139
|
expect(executeCommand).toHaveBeenCalledWith(expectedCommand);
|
|
144
|
-
expect(result).toEqual({
|
|
140
|
+
expect(result).toEqual({stdout: "Simulator started", stderr: ""});
|
|
145
141
|
});
|
|
146
142
|
|
|
147
143
|
test("should execute the correct run simulator command based on ollama option", async () => {
|
|
@@ -174,8 +170,8 @@ describe("SimulatorService - Basic Tests", () => {
|
|
|
174
170
|
test("should create a backup of the .env file and add new config", () => {
|
|
175
171
|
const envFilePath = `/.env`;
|
|
176
172
|
const originalEnvContent = "KEY1=value1\nKEY2=value2";
|
|
177
|
-
const parsedEnvConfig = {
|
|
178
|
-
const newConfig = {
|
|
173
|
+
const parsedEnvConfig = {KEY1: "value1", KEY2: "value2"};
|
|
174
|
+
const newConfig = {KEY3: "value3", KEY2: "newValue2"};
|
|
179
175
|
|
|
180
176
|
vi.mocked(fs.readFileSync).mockImplementation((filePath: any) => {
|
|
181
177
|
if (filePath === envFilePath) return originalEnvContent;
|
|
@@ -193,7 +189,7 @@ describe("SimulatorService - Basic Tests", () => {
|
|
|
193
189
|
|
|
194
190
|
test("should handle empty .env file and add new config", () => {
|
|
195
191
|
const envFilePath = `/.env`;
|
|
196
|
-
const newConfig = {
|
|
192
|
+
const newConfig = {NEW_KEY: "newValue"};
|
|
197
193
|
|
|
198
194
|
vi.mocked(fs.readFileSync).mockReturnValue("");
|
|
199
195
|
vi.mocked(dotenv.parse).mockReturnValue({});
|
|
@@ -210,12 +206,9 @@ describe("SimulatorService - Basic Tests", () => {
|
|
|
210
206
|
throw new Error("File not found");
|
|
211
207
|
});
|
|
212
208
|
|
|
213
|
-
expect(() => simulatorService.addConfigToEnvFile({
|
|
214
|
-
"File not found"
|
|
215
|
-
);
|
|
209
|
+
expect(() => simulatorService.addConfigToEnvFile({KEY: "value"})).toThrow("File not found");
|
|
216
210
|
});
|
|
217
211
|
|
|
218
|
-
|
|
219
212
|
test("should open the frontend URL and return true", async () => {
|
|
220
213
|
vi.spyOn(simulatorService, "getFrontendUrl").mockReturnValue("http://localhost:8080");
|
|
221
214
|
const result = await simulatorService.openFrontend();
|
|
@@ -225,35 +218,31 @@ describe("SimulatorService - Basic Tests", () => {
|
|
|
225
218
|
});
|
|
226
219
|
|
|
227
220
|
test("should call rpcClient.request with correct parameters and return the response", async () => {
|
|
228
|
-
const mockResponse = {
|
|
221
|
+
const mockResponse = {success: true};
|
|
229
222
|
vi.mocked(rpcClient.request).mockResolvedValue(mockResponse);
|
|
230
223
|
const result = await simulatorService.deleteAllValidators();
|
|
231
|
-
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
224
|
+
expect(rpcClient.request).toHaveBeenCalledWith({method: "sim_deleteAllValidators", params: []});
|
|
232
225
|
expect(result).toBe(mockResponse);
|
|
233
226
|
});
|
|
234
227
|
|
|
235
228
|
test("should return node missing version", async () => {
|
|
236
|
-
const unexpectedError = new VersionRequiredError(
|
|
237
|
-
vi.spyOn(simulatorService, "checkVersion")
|
|
238
|
-
.mockRejectedValueOnce(unexpectedError)
|
|
239
|
-
.mockResolvedValueOnce();
|
|
229
|
+
const unexpectedError = new VersionRequiredError("node", VERSION_REQUIREMENTS.node);
|
|
230
|
+
vi.spyOn(simulatorService, "checkVersion").mockRejectedValueOnce(unexpectedError).mockResolvedValueOnce();
|
|
240
231
|
|
|
241
232
|
await expect(simulatorService.checkVersionRequirements()).resolves.toStrictEqual({
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
})
|
|
233
|
+
docker: "",
|
|
234
|
+
node: VERSION_REQUIREMENTS.node,
|
|
235
|
+
});
|
|
245
236
|
});
|
|
246
237
|
|
|
247
238
|
test("should return docker missing version", async () => {
|
|
248
|
-
const unexpectedError = new VersionRequiredError(
|
|
249
|
-
vi.spyOn(simulatorService, "checkVersion")
|
|
250
|
-
.mockResolvedValueOnce()
|
|
251
|
-
.mockRejectedValueOnce(unexpectedError)
|
|
239
|
+
const unexpectedError = new VersionRequiredError("node", VERSION_REQUIREMENTS.docker);
|
|
240
|
+
vi.spyOn(simulatorService, "checkVersion").mockResolvedValueOnce().mockRejectedValueOnce(unexpectedError);
|
|
252
241
|
|
|
253
242
|
await expect(simulatorService.checkVersionRequirements()).resolves.toStrictEqual({
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
})
|
|
243
|
+
docker: VERSION_REQUIREMENTS.docker,
|
|
244
|
+
node: "",
|
|
245
|
+
});
|
|
257
246
|
});
|
|
258
247
|
|
|
259
248
|
test("should throw an unexpected error when checking node version requirements", async () => {
|
|
@@ -272,14 +261,14 @@ describe("SimulatorService - Basic Tests", () => {
|
|
|
272
261
|
test("should throw an unexpected error when checking git installation requirement", async () => {
|
|
273
262
|
vi.mocked(checkCommand).mockRejectedValueOnce(new Error("Unexpected git error"));
|
|
274
263
|
await expect(simulatorService.checkInstallRequirements()).rejects.toThrow("Unexpected git error");
|
|
275
|
-
const requirementsInstalled = {
|
|
264
|
+
const requirementsInstalled = {git: false, docker: false};
|
|
276
265
|
expect(requirementsInstalled.git).toBe(false);
|
|
277
266
|
});
|
|
278
267
|
|
|
279
268
|
test("should retry when response is not 'OK' and reach sleep path", async () => {
|
|
280
|
-
vi.mocked(rpcClient.request).mockResolvedValue({
|
|
269
|
+
vi.mocked(rpcClient.request).mockResolvedValue({result: {status: "NOT_OK"}});
|
|
281
270
|
const result = await simulatorService.waitForSimulatorToBeReady(1);
|
|
282
|
-
expect(result).toEqual({
|
|
271
|
+
expect(result).toEqual({initialized: false, errorCode: "TIMEOUT"});
|
|
283
272
|
});
|
|
284
273
|
|
|
285
274
|
test("should retry on fetch error and reach sleep path", async () => {
|
|
@@ -287,18 +276,16 @@ describe("SimulatorService - Basic Tests", () => {
|
|
|
287
276
|
fetchError.name = "FetchError";
|
|
288
277
|
vi.mocked(rpcClient.request).mockRejectedValue(fetchError);
|
|
289
278
|
const result = await simulatorService.waitForSimulatorToBeReady(1);
|
|
290
|
-
expect(result).toEqual({
|
|
279
|
+
expect(result).toEqual({initialized: false, errorCode: "ERROR", errorMessage: fetchError.message});
|
|
291
280
|
});
|
|
292
281
|
|
|
293
282
|
test("should call executeCommand if docker ps command fails", async () => {
|
|
294
|
-
vi.mocked(checkCommand)
|
|
295
|
-
.mockResolvedValueOnce(undefined)
|
|
283
|
+
vi.mocked(checkCommand).mockResolvedValueOnce(undefined);
|
|
296
284
|
|
|
297
285
|
const result = await simulatorService.checkInstallRequirements();
|
|
298
286
|
expect(result.docker).toBe(true);
|
|
299
287
|
});
|
|
300
288
|
|
|
301
|
-
|
|
302
289
|
test("should return providers without errors", () => {
|
|
303
290
|
expect(simulatorService.getAiProvidersOptions(true)).toEqual(expect.any(Array));
|
|
304
291
|
expect(simulatorService.getAiProvidersOptions(false)).toEqual(expect.any(Array));
|
|
@@ -331,15 +318,18 @@ describe("SimulatorService - Basic Tests", () => {
|
|
|
331
318
|
});
|
|
332
319
|
|
|
333
320
|
test("clean simulator should success", async () => {
|
|
334
|
-
vi.mocked(rpcClient.request).mockResolvedValueOnce(
|
|
321
|
+
vi.mocked(rpcClient.request).mockResolvedValueOnce("Success");
|
|
335
322
|
await expect(simulatorService.cleanDatabase).not.toThrow();
|
|
336
|
-
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
323
|
+
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
324
|
+
method: "sim_clearDbTables",
|
|
325
|
+
params: [["current_state", "transactions"]],
|
|
326
|
+
});
|
|
337
327
|
});
|
|
338
328
|
|
|
339
329
|
test("should create random validators", async () => {
|
|
340
330
|
const numValidators = 5;
|
|
341
331
|
const llmProviders = ["openai", "ollama"] as AiProviders[];
|
|
342
|
-
const mockResponse = {
|
|
332
|
+
const mockResponse = {success: true};
|
|
343
333
|
vi.mocked(rpcClient.request).mockResolvedValue(mockResponse);
|
|
344
334
|
|
|
345
335
|
const result = await simulatorService.createRandomValidators(numValidators, llmProviders);
|
|
@@ -350,7 +340,6 @@ describe("SimulatorService - Basic Tests", () => {
|
|
|
350
340
|
});
|
|
351
341
|
expect(result).toEqual(mockResponse);
|
|
352
342
|
});
|
|
353
|
-
|
|
354
343
|
});
|
|
355
344
|
describe("SimulatorService - Docker Tests", () => {
|
|
356
345
|
let mockGetContainer: Mock;
|
|
@@ -370,11 +359,11 @@ describe("SimulatorService - Docker Tests", () => {
|
|
|
370
359
|
|
|
371
360
|
test("isLocalnetRunning should return true when all required containers are running", async () => {
|
|
372
361
|
const mockContainers = [
|
|
373
|
-
{
|
|
374
|
-
{
|
|
375
|
-
{
|
|
376
|
-
{
|
|
377
|
-
{
|
|
362
|
+
{Id: "container1", Names: ["/genlayer-jsonrpc1"], State: "running"},
|
|
363
|
+
{Id: "container2", Names: ["/genlayer-webrequest1"], State: "running"},
|
|
364
|
+
{Id: "container3", Names: ["/genlayer-postgres1"], State: "running"},
|
|
365
|
+
{Id: "container4", Names: ["/genlayer-other-container1"], State: "running"},
|
|
366
|
+
{Id: "container5", Names: ["/genlayer-another-container1"], State: "exited"},
|
|
378
367
|
];
|
|
379
368
|
|
|
380
369
|
mockListContainers.mockResolvedValue(mockContainers);
|
|
@@ -384,11 +373,11 @@ describe("SimulatorService - Docker Tests", () => {
|
|
|
384
373
|
|
|
385
374
|
test("isLocalnetRunning should return false when not all required containers are running", async () => {
|
|
386
375
|
const mockContainers = [
|
|
387
|
-
{
|
|
388
|
-
{
|
|
389
|
-
{
|
|
390
|
-
{
|
|
391
|
-
{
|
|
376
|
+
{Id: "container1", Names: ["/genlayer-jsonrpc2"], State: "running"},
|
|
377
|
+
{Id: "container2", Names: ["/genlayer-webrequest2"], State: "running"},
|
|
378
|
+
{Id: "container3", Names: ["/genlayer-postgres2"], State: "exited"},
|
|
379
|
+
{Id: "container4", Names: ["/genlayer-other-container2"], State: "running"},
|
|
380
|
+
{Id: "container5", Names: ["/unrelated-container2"], State: "running"},
|
|
392
381
|
];
|
|
393
382
|
|
|
394
383
|
mockListContainers.mockResolvedValue(mockContainers);
|
|
@@ -419,15 +408,18 @@ describe("SimulatorService - Docker Tests", () => {
|
|
|
419
408
|
|
|
420
409
|
const mockStop = vi.fn().mockResolvedValue(undefined);
|
|
421
410
|
const mockRemove = vi.fn().mockResolvedValue(undefined);
|
|
422
|
-
mockGetContainer.mockImplementation(
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
411
|
+
mockGetContainer.mockImplementation(
|
|
412
|
+
() =>
|
|
413
|
+
({
|
|
414
|
+
stop: mockStop,
|
|
415
|
+
remove: mockRemove,
|
|
416
|
+
}) as unknown as Docker.Container,
|
|
417
|
+
);
|
|
426
418
|
|
|
427
419
|
const result = await simulatorService.resetDockerContainers();
|
|
428
420
|
|
|
429
421
|
expect(result).toBe(undefined);
|
|
430
|
-
expect(mockListContainers).toHaveBeenCalledWith({
|
|
422
|
+
expect(mockListContainers).toHaveBeenCalledWith({all: true});
|
|
431
423
|
|
|
432
424
|
// Ensure only the relevant containers were stopped and removed
|
|
433
425
|
expect(mockGetContainer).toHaveBeenCalledWith("container1");
|
|
@@ -456,9 +448,12 @@ describe("SimulatorService - Docker Tests", () => {
|
|
|
456
448
|
|
|
457
449
|
const mockStop = vi.fn().mockResolvedValue(undefined);
|
|
458
450
|
const mockGetContainer = vi.mocked(Docker.prototype.getContainer);
|
|
459
|
-
mockGetContainer.mockImplementation(
|
|
460
|
-
|
|
461
|
-
|
|
451
|
+
mockGetContainer.mockImplementation(
|
|
452
|
+
() =>
|
|
453
|
+
({
|
|
454
|
+
stop: mockStop,
|
|
455
|
+
}) as unknown as Docker.Container,
|
|
456
|
+
);
|
|
462
457
|
|
|
463
458
|
await simulatorService.stopDockerContainers();
|
|
464
459
|
|
|
@@ -467,7 +462,6 @@ describe("SimulatorService - Docker Tests", () => {
|
|
|
467
462
|
expect(mockStop).toHaveBeenCalledTimes(1);
|
|
468
463
|
});
|
|
469
464
|
|
|
470
|
-
|
|
471
465
|
test("should remove Docker images with the specified prefix", async () => {
|
|
472
466
|
const mockImages = [
|
|
473
467
|
{
|
|
@@ -487,9 +481,12 @@ describe("SimulatorService - Docker Tests", () => {
|
|
|
487
481
|
mockListImages.mockResolvedValue(mockImages);
|
|
488
482
|
|
|
489
483
|
const mockRemove = vi.fn().mockResolvedValue(undefined);
|
|
490
|
-
mockGetImage.mockImplementation(
|
|
491
|
-
|
|
492
|
-
|
|
484
|
+
mockGetImage.mockImplementation(
|
|
485
|
+
() =>
|
|
486
|
+
({
|
|
487
|
+
remove: mockRemove,
|
|
488
|
+
}) as unknown as Docker.Image,
|
|
489
|
+
);
|
|
493
490
|
|
|
494
491
|
const result = await simulatorService.resetDockerImages();
|
|
495
492
|
|
|
@@ -499,12 +496,11 @@ describe("SimulatorService - Docker Tests", () => {
|
|
|
499
496
|
expect(mockGetImage).toHaveBeenCalledWith("image2");
|
|
500
497
|
expect(mockGetImage).not.toHaveBeenCalledWith("image3");
|
|
501
498
|
expect(mockRemove).toHaveBeenCalledTimes(2);
|
|
502
|
-
expect(mockRemove).toHaveBeenCalledWith({
|
|
499
|
+
expect(mockRemove).toHaveBeenCalledWith({force: true});
|
|
503
500
|
});
|
|
504
501
|
|
|
505
502
|
test("should execute command when docker is installed but is not available", async () => {
|
|
506
|
-
vi.mocked(checkCommand)
|
|
507
|
-
.mockResolvedValueOnce(undefined)
|
|
503
|
+
vi.mocked(checkCommand).mockResolvedValueOnce(undefined);
|
|
508
504
|
|
|
509
505
|
mockPing.mockRejectedValueOnce("");
|
|
510
506
|
await simulatorService.checkInstallRequirements();
|
|
@@ -512,15 +508,13 @@ describe("SimulatorService - Docker Tests", () => {
|
|
|
512
508
|
});
|
|
513
509
|
|
|
514
510
|
test("should call execute command again to start docker service", async () => {
|
|
515
|
-
vi.mocked(checkCommand)
|
|
516
|
-
.mockResolvedValueOnce(undefined)
|
|
517
|
-
.mockRejectedValue(undefined);
|
|
511
|
+
vi.mocked(checkCommand).mockResolvedValueOnce(undefined).mockRejectedValue(undefined);
|
|
518
512
|
mockPing.mockRejectedValueOnce("");
|
|
519
|
-
await expect(simulatorService.checkInstallRequirements()).resolves.toStrictEqual({
|
|
513
|
+
await expect(simulatorService.checkInstallRequirements()).resolves.toStrictEqual({docker: true});
|
|
520
514
|
});
|
|
521
515
|
|
|
522
516
|
test("should warn the user when an update is available", async () => {
|
|
523
|
-
const update = {
|
|
517
|
+
const update = {latest: "1.1.0"};
|
|
524
518
|
(updateCheck as any).mockResolvedValue(update);
|
|
525
519
|
|
|
526
520
|
const consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
@@ -528,14 +522,14 @@ describe("SimulatorService - Docker Tests", () => {
|
|
|
528
522
|
await simulatorService.checkCliVersion();
|
|
529
523
|
|
|
530
524
|
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
531
|
-
`\nA new version (${update.latest}) is available! You're using version 1.0.0.\nRun npm install -g genlayer to update\n
|
|
525
|
+
`\nA new version (${update.latest}) is available! You're using version 1.0.0.\nRun npm install -g genlayer to update\n`,
|
|
532
526
|
);
|
|
533
527
|
|
|
534
528
|
consoleWarnSpy.mockRestore();
|
|
535
529
|
});
|
|
536
530
|
|
|
537
531
|
test("should not warn the user when the CLI is up-to-date", async () => {
|
|
538
|
-
const update = {
|
|
532
|
+
const update = {latest: "1.0.0"};
|
|
539
533
|
(updateCheck as any).mockResolvedValue(update);
|
|
540
534
|
|
|
541
535
|
const consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
@@ -560,7 +554,7 @@ describe("SimulatorService - Docker Tests", () => {
|
|
|
560
554
|
});
|
|
561
555
|
});
|
|
562
556
|
|
|
563
|
-
describe(
|
|
557
|
+
describe("normalizeLocalnetVersion", () => {
|
|
564
558
|
test('should add "v" if not present', () => {
|
|
565
559
|
expect(simulatorService.normalizeLocalnetVersion("0.26.0")).toBe("v0.26.0");
|
|
566
560
|
});
|
|
@@ -574,18 +568,20 @@ describe('normalizeLocalnetVersion', () => {
|
|
|
574
568
|
expect(simulatorService.normalizeLocalnetVersion("v1.0.0-alpha")).toBe("v1.0.0-alpha");
|
|
575
569
|
});
|
|
576
570
|
|
|
577
|
-
test(
|
|
571
|
+
test("should handle versions with numbers only", () => {
|
|
578
572
|
expect(simulatorService.normalizeLocalnetVersion("1.0.0")).toBe("v1.0.0");
|
|
579
573
|
});
|
|
580
574
|
|
|
581
|
-
test(
|
|
582
|
-
const mockExit = vi.spyOn(process,
|
|
583
|
-
|
|
575
|
+
test("should throw an error and exit for invalid versions", () => {
|
|
576
|
+
const mockExit = vi.spyOn(process, "exit").mockImplementation(() => {
|
|
577
|
+
return undefined as never;
|
|
578
|
+
});
|
|
579
|
+
const mockConsoleError = vi.spyOn(console, "error").mockImplementation(() => {});
|
|
584
580
|
|
|
585
581
|
simulatorService.normalizeLocalnetVersion("invalid-version");
|
|
586
582
|
|
|
587
583
|
expect(mockConsoleError).toHaveBeenCalledWith(
|
|
588
|
-
|
|
584
|
+
"Invalid version format. Expected format: v0.0.0 or v0.0.0-suffix",
|
|
589
585
|
);
|
|
590
586
|
expect(mockExit).toHaveBeenCalledWith(1);
|
|
591
587
|
|
|
@@ -602,7 +598,7 @@ describe('normalizeLocalnetVersion', () => {
|
|
|
602
598
|
|
|
603
599
|
expect(rpcClient.request).toHaveBeenCalledWith({
|
|
604
600
|
method: "sim_clearDbTables",
|
|
605
|
-
params: [[
|
|
601
|
+
params: [["current_state", "transactions"]],
|
|
606
602
|
});
|
|
607
603
|
expect(console.error).toHaveBeenCalledWith(mockError);
|
|
608
604
|
});
|