summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2020-11-23 12:55:29 +0100
committerOskar Nyberg <oskar@mullvad.net>2020-11-23 12:55:29 +0100
commit6b95ceead2b6712d05a836e50395b754cc8605ad (patch)
tree7d0cd5d27ab4f46208ef0979e0943a9f7bff18f8
parent410cf70afb817488233dce1018d38fe734665d53 (diff)
parent86af950a735ad5aef786a92fa0b0f26bb482c38e (diff)
downloadmullvadvpn-6b95ceead2b6712d05a836e50395b754cc8605ad.tar.xz
mullvadvpn-6b95ceead2b6712d05a836e50395b754cc8605ad.zip
Merge branch 'change-renderer-log-file-name'
-rw-r--r--gui/src/main/index.ts2
-rw-r--r--gui/src/shared/logging.ts46
-rw-r--r--gui/test/logging.spec.ts81
3 files changed, 119 insertions, 10 deletions
diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts
index 10f66b3f08..a5a437e099 100644
--- a/gui/src/main/index.ts
+++ b/gui/src/main/index.ts
@@ -31,6 +31,7 @@ import { SYSTEM_PREFERRED_LOCALE_KEY } from '../shared/gui-settings-state';
import { IpcMainEventChannel } from '../shared/ipc-event-channel';
import {
backupLogFile,
+ cleanUpLogDirectory,
getLogsDirectory,
getMainLogFile,
getRendererLogFile,
@@ -264,6 +265,7 @@ class ApplicationMain {
}
}
+ cleanUpLogDirectory();
setupLogging(mainLogFile);
}
diff --git a/gui/src/shared/logging.ts b/gui/src/shared/logging.ts
index c33f22a0b7..471fd758c8 100644
--- a/gui/src/shared/logging.ts
+++ b/gui/src/shared/logging.ts
@@ -28,7 +28,7 @@ export function getMainLogFile(): string {
}
export function getRendererLogFile(): string {
- return path.join(getLogsDirectory(), 'frontend-renderer.log');
+ return path.join(getLogsDirectory(), 'renderer.log');
}
export function setupLogging(logFile: string) {
@@ -48,18 +48,44 @@ export function setupLogging(logFile: string) {
}
}
-export function backupLogFile(filePath: string): string | undefined {
- const ext = path.extname(filePath);
- const baseName = path.basename(filePath, ext);
- const backupFile = path.join(path.dirname(filePath), baseName + '.old' + ext);
+export function backupLogFile(filePath: string): boolean {
+ const exists = fileExists(filePath);
+ if (exists) {
+ const backupFilePath = getBackupFilePath(filePath);
+ fs.renameSync(filePath, backupFilePath);
+ }
+
+ return exists;
+}
+
+function getBackupFilePath(filePath: string): string {
+ const parsedPath = path.parse(filePath);
+ parsedPath.base = parsedPath.name + '.old' + parsedPath.ext;
+ return path.normalize(path.format(parsedPath));
+}
+function fileExists(filePath: string): boolean {
try {
fs.accessSync(filePath);
- fs.renameSync(filePath, backupFile);
+ return true;
+ } catch {
+ return false;
+ }
+}
+
+// When cleaning up old log files they are first backed up and the next time removed.
+export function cleanUpLogDirectory(): void {
+ const oldLogFileNames = ['frontend-renderer.log'];
+
+ oldLogFileNames.forEach((fileName) => {
+ const filePath = path.join(getLogsDirectory(), fileName);
+ rotateOrDeleteFile(filePath);
+ });
+}
- return backupFile;
- } catch (error) {
- // No previous log file exists
- return undefined;
+export function rotateOrDeleteFile(filePath: string) {
+ const backupFilePath = getBackupFilePath(filePath);
+ if (!backupLogFile(filePath) && fileExists(backupFilePath)) {
+ fs.unlinkSync(backupFilePath);
}
}
diff --git a/gui/test/logging.spec.ts b/gui/test/logging.spec.ts
new file mode 100644
index 0000000000..9572c6ed24
--- /dev/null
+++ b/gui/test/logging.spec.ts
@@ -0,0 +1,81 @@
+import { expect } from 'chai';
+import fs from 'fs';
+import sinon from 'sinon';
+import { it, describe, before, beforeEach, after } from 'mocha';
+import * as logging from '../src/shared/logging';
+
+const aPath = 'log-directory/a.log';
+const oldAPath = 'log-directory/a.old.log';
+const bPath = 'log-directory/b.log';
+const oldBPath = 'log-directory/b.old.log';
+
+const initialFileState = {
+ [aPath]: 'a',
+ [bPath]: 'b',
+ [oldBPath]: 'old b',
+};
+
+describe('Logging', () => {
+ let files: Record<string, string>;
+ let sandbox: sinon.SinonSandbox;
+
+ before(() => {
+ sandbox = sinon.createSandbox();
+
+ sandbox.stub(fs, 'accessSync').callsFake((path) => {
+ if (files[path as string] === undefined) {
+ throw Error('File not found');
+ }
+ });
+
+ sandbox.stub(fs, 'renameSync').callsFake((oldPath, newPath) => {
+ files[newPath as string] = files[oldPath as string];
+ fs.unlinkSync(oldPath);
+ });
+
+ sandbox.stub(fs, 'unlinkSync').callsFake((path) => {
+ delete files[path as string];
+ });
+
+ sandbox.stub(fs, 'readFileSync').callsFake((path) => {
+ return files[path as string] ?? '';
+ });
+ });
+
+ after(() => {
+ sandbox.restore();
+ });
+
+ beforeEach(() => {
+ files = { ...initialFileState };
+ });
+
+ it('should backup log file', () => {
+ logging.backupLogFile(aPath);
+ const oldA = fs.readFileSync(oldAPath).toString();
+
+ expect(fs.accessSync.bind(null, aPath)).to.throw();
+ expect(oldA).to.equal(initialFileState[aPath]);
+ });
+
+ it('should replace backup file', () => {
+ logging.backupLogFile(bPath);
+ const oldB = fs.readFileSync(oldBPath).toString();
+
+ expect(fs.accessSync.bind(null, bPath)).to.throw();
+ expect(oldB).to.equal(initialFileState[bPath]);
+ });
+
+ it('should clean up old log files', () => {
+ logging.rotateOrDeleteFile(bPath);
+ const oldB = fs.readFileSync(oldBPath).toString();
+
+ expect(fs.accessSync.bind(null, bPath)).to.throw();
+ expect(oldB).to.equal(initialFileState[bPath]);
+
+ logging.rotateOrDeleteFile(bPath);
+
+ expect(fs.accessSync.bind(null, bPath)).to.throw();
+ expect(fs.accessSync.bind(null, oldBPath)).to.throw();
+ });
+});