test: system.service
This commit is contained in:
parent
aa518c660f
commit
ba0996a1f2
3 changed files with 82 additions and 17 deletions
|
@ -4,6 +4,9 @@ import Layout from '../components/Layout';
|
||||||
import { useLogoutMutation, useRestartMutation, useUpdateMutation, useVersionQuery } from '../generated/graphql';
|
import { useLogoutMutation, useRestartMutation, useUpdateMutation, useVersionQuery } from '../generated/graphql';
|
||||||
import { useRef, useState } from 'react';
|
import { useRef, useState } from 'react';
|
||||||
|
|
||||||
|
// Necessary to avoid flickering when initiating an update or restart
|
||||||
|
const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
|
||||||
const Settings: NextPage = () => {
|
const Settings: NextPage = () => {
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const restartDisclosure = useDisclosure();
|
const restartDisclosure = useDisclosure();
|
||||||
|
@ -51,11 +54,9 @@ const Settings: NextPage = () => {
|
||||||
const handleRestart = async () => {
|
const handleRestart = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
setTimeout(() => {
|
restart();
|
||||||
logout();
|
await wait(2000);
|
||||||
}, 2000);
|
logout();
|
||||||
|
|
||||||
await restart();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error);
|
handleError(error);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -66,11 +67,9 @@ const Settings: NextPage = () => {
|
||||||
const handleUpdate = async () => {
|
const handleUpdate = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
setTimeout(() => {
|
update();
|
||||||
logout();
|
await wait(2000);
|
||||||
}, 2000);
|
logout();
|
||||||
|
|
||||||
await update();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error);
|
handleError(error);
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import semver from 'semver';
|
import semver from 'semver';
|
||||||
|
import childProcess from 'child_process';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import SystemService from '../system.service';
|
import SystemService from '../system.service';
|
||||||
import { faker } from '@faker-js/faker';
|
import { faker } from '@faker-js/faker';
|
||||||
import TipiCache from '../../../config/TipiCache';
|
import TipiCache from '../../../config/TipiCache';
|
||||||
import { setConfig } from '../../../core/config/TipiConfig';
|
import { setConfig } from '../../../core/config/TipiConfig';
|
||||||
|
import logger from '../../../config/logger/logger';
|
||||||
|
|
||||||
jest.mock('fs-extra');
|
jest.mock('fs-extra');
|
||||||
jest.mock('child_process');
|
jest.mock('child_process');
|
||||||
|
@ -110,6 +112,22 @@ describe('Test: restart', () => {
|
||||||
|
|
||||||
expect(restart).toBeTruthy();
|
expect(restart).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should log error if fails', async () => {
|
||||||
|
// @ts-ignore
|
||||||
|
const spy = jest.spyOn(childProcess, 'execFile').mockImplementation((_path, _args, _, cb) => {
|
||||||
|
// @ts-ignore
|
||||||
|
if (cb) cb('error', null, null);
|
||||||
|
});
|
||||||
|
const log = jest.spyOn(logger, 'error');
|
||||||
|
|
||||||
|
const restart = await SystemService.restart();
|
||||||
|
|
||||||
|
expect(restart).toBeTruthy();
|
||||||
|
expect(log).toHaveBeenCalledWith('Error restarting: error');
|
||||||
|
|
||||||
|
spy.mockRestore();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Test: update', () => {
|
describe('Test: update', () => {
|
||||||
|
@ -121,4 +139,57 @@ describe('Test: update', () => {
|
||||||
|
|
||||||
expect(update).toBeTruthy();
|
expect(update).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should throw an error if latest version is not set', async () => {
|
||||||
|
TipiCache.del('latestVersion');
|
||||||
|
const spy = jest.spyOn(axios, 'get').mockResolvedValue({
|
||||||
|
data: { name: null },
|
||||||
|
});
|
||||||
|
|
||||||
|
setConfig('version', '0.0.1');
|
||||||
|
|
||||||
|
await expect(SystemService.update()).rejects.toThrow('Could not get latest version');
|
||||||
|
|
||||||
|
spy.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should throw if current version is higher than latest', async () => {
|
||||||
|
setConfig('version', '0.0.2');
|
||||||
|
TipiCache.set('latestVersion', '0.0.1');
|
||||||
|
|
||||||
|
await expect(SystemService.update()).rejects.toThrow('Current version is newer than latest version');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should throw if current version is equal to latest', async () => {
|
||||||
|
setConfig('version', '0.0.1');
|
||||||
|
TipiCache.set('latestVersion', '0.0.1');
|
||||||
|
|
||||||
|
await expect(SystemService.update()).rejects.toThrow('Current version is already up to date');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should throw an error if there is a major version difference', async () => {
|
||||||
|
setConfig('version', '0.0.1');
|
||||||
|
TipiCache.set('latestVersion', '1.0.0');
|
||||||
|
|
||||||
|
await expect(SystemService.update()).rejects.toThrow('The major version has changed. Please update manually');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should log error if fails', async () => {
|
||||||
|
// @ts-ignore
|
||||||
|
const spy = jest.spyOn(childProcess, 'execFile').mockImplementation((_path, _args, _, cb) => {
|
||||||
|
// @ts-ignore
|
||||||
|
if (cb) cb('error', null, null);
|
||||||
|
});
|
||||||
|
const log = jest.spyOn(logger, 'error');
|
||||||
|
|
||||||
|
setConfig('version', '0.0.1');
|
||||||
|
TipiCache.set('latestVersion', '0.0.2');
|
||||||
|
|
||||||
|
const update = await SystemService.update();
|
||||||
|
|
||||||
|
expect(update).toBeTruthy();
|
||||||
|
expect(log).toHaveBeenCalledWith('Error updating: error');
|
||||||
|
|
||||||
|
spy.mockRestore();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -22,8 +22,6 @@ const systemInfoSchema = z.object({
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
||||||
|
|
||||||
const systemInfo = (): z.infer<typeof systemInfoSchema> => {
|
const systemInfo = (): z.infer<typeof systemInfoSchema> => {
|
||||||
const info = systemInfoSchema.safeParse(readJsonFile('/state/system-info.json'));
|
const info = systemInfoSchema.safeParse(readJsonFile('/state/system-info.json'));
|
||||||
|
|
||||||
|
@ -59,8 +57,6 @@ const getVersion = async (): Promise<{ current: string; latest?: string }> => {
|
||||||
const restart = async (): Promise<boolean> => {
|
const restart = async (): Promise<boolean> => {
|
||||||
setConfig('status', 'RESTARTING');
|
setConfig('status', 'RESTARTING');
|
||||||
|
|
||||||
await wait(2000);
|
|
||||||
|
|
||||||
runScript('/scripts/system.sh', ['restart'], (err: string) => {
|
runScript('/scripts/system.sh', ['restart'], (err: string) => {
|
||||||
setConfig('status', 'RUNNING');
|
setConfig('status', 'RUNNING');
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -68,15 +64,14 @@ const restart = async (): Promise<boolean> => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setConfig('status', 'RUNNING');
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const update = async (): Promise<boolean> => {
|
const update = async (): Promise<boolean> => {
|
||||||
const { current, latest } = await getVersion();
|
const { current, latest } = await getVersion();
|
||||||
|
|
||||||
console.log(current, latest);
|
|
||||||
await wait(2000);
|
|
||||||
|
|
||||||
if (!latest) {
|
if (!latest) {
|
||||||
throw new Error('Could not get latest version');
|
throw new Error('Could not get latest version');
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue