From 380f2cc2ad52375ef35f2eb84135677ff65b7db5 Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Mon, 2 Oct 2023 00:50:55 +0200 Subject: [PATCH] Fix tests --- .github/workflows/build.yml | 1 + package.json | 2 +- .../sentry-minidump/minidump-loader.ts | 29 ++++++++++++------- test/unit/minidump-loader.test.ts | 19 ++++++++---- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f870740c..aaf6df2d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,7 @@ on: env: ELECTRON_CACHE_DIR: ${{ github.workspace }} FAILURE_LOG: true + CI: true jobs: build: diff --git a/package.json b/package.json index e7a36d0b..b3872b4e 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "fix:prettier": "prettier --write \"{src,test}/**/*.ts\"", "fix:eslint": "eslint . --format stylish --fix", "pretest": "yarn build", - "test": "cross-env TS_NODE_PROJECT=tsconfig.json xvfb-maybe electron-mocha --require ts-node/register/transpile-only --timeout 120000 ./test/unit/**/*.ts", + "test": "cross-env TS_NODE_PROJECT=tsconfig.json xvfb-maybe electron-mocha --require ts-node/register/transpile-only --timeout 12000 ./test/unit/**/*.ts", "pree2e": "rimraf test/e2e/dist/**/node_modules/@sentry/** test/e2e/dist/**/yarn.lock test/e2e/dist/**/package-lock.json && node scripts/clean-cache.js && yarn build && npm pack", "e2e": "cross-env TS_NODE_PROJECT=tsconfig.json xvfb-maybe mocha --require ts-node/register/transpile-only --retries 3 ./test/e2e/*.ts" }, diff --git a/src/main/integrations/sentry-minidump/minidump-loader.ts b/src/main/integrations/sentry-minidump/minidump-loader.ts index 10ec2e3c..32a47c47 100644 --- a/src/main/integrations/sentry-minidump/minidump-loader.ts +++ b/src/main/integrations/sentry-minidump/minidump-loader.ts @@ -7,12 +7,12 @@ import { getCrashesDirectory, usesCrashpad } from '../../electron-normalize'; import { readDirAsync, readFileAsync, statAsync, unlinkAsync } from '../../fs'; /** Maximum number of days to keep a minidump before deleting it. */ -const MAX_AGE = 30; +const MAX_AGE_DAYS = 30; /** Minimum number of milliseconds a minidump should not be modified for before we assume writing is complete */ -const MIN_NOT_MODIFIED = 1_000; -const MAX_RETRY_TIME = 5_000; -const TIME_BETWEEN_RETRIES = 200; -const MAX_RETRIES = MAX_RETRY_TIME / TIME_BETWEEN_RETRIES; +const NOT_MODIFIED_MS = 1_000; +const MAX_RETRY_MS = 5_000; +const RETRY_DELAY_MS = 500; +const MAX_RETRIES = MAX_RETRY_MS / RETRY_DELAY_MS; const MINIDUMP_HEADER = 'MDMP'; @@ -20,6 +20,11 @@ function delay(ms: number): Promise { return new Promise((resolve) => setTimeout(resolve, ms)); } +/** + * A function that loads minidumps + * @param deleteAll Whether to just delete all minidumps + * @param callback A callback to call with the attachment ready to send + */ export type MinidumpLoader = (deleteAll: boolean, callback: (attachment: Attachment) => void) => Promise; /** @@ -48,17 +53,17 @@ export function createMinidumpLoader( let stats = await statAsync(path); - const thirtyDaysAgo = new Date().getTime() - MAX_AGE * 24 * 3_600 * 1_000; + const thirtyDaysAgo = new Date().getTime() - MAX_AGE_DAYS * 24 * 3_600 * 1_000; if (stats.birthtimeMs < thirtyDaysAgo) { - logger.log(`Ignoring minidump as it is over ${MAX_AGE} days old`); + logger.log(`Ignoring minidump as it is over ${MAX_AGE_DAYS} days old`); continue; } let retries = 0; while (retries <= MAX_RETRIES) { - const twoSecondsAgo = new Date().getTime() - MIN_NOT_MODIFIED; + const twoSecondsAgo = new Date().getTime() - NOT_MODIFIED_MS; if (stats.mtimeMs < twoSecondsAgo) { const file = await readFileAsync(path); @@ -80,9 +85,10 @@ export function createMinidumpLoader( break; } - logger.log(`Waiting. Minidump has been modified in the last ${MIN_NOT_MODIFIED} milliseconds.`); + logger.log(`Waiting. Minidump has been modified in the last ${NOT_MODIFIED_MS} milliseconds.`); retries += 1; - await delay(TIME_BETWEEN_RETRIES); + await delay(RETRY_DELAY_MS); + // update the stats stats = await statAsync(path); } @@ -92,10 +98,11 @@ export function createMinidumpLoader( } catch (e) { logger.error('Failed to load minidump', e); } finally { + // We always attempt to delete the minidump try { await unlinkAsync(path); } catch (e) { - logger.warn('Could not delete', path); + logger.warn('Could not delete minidump', path); } } } diff --git a/test/unit/minidump-loader.test.ts b/test/unit/minidump-loader.test.ts index d7419559..3378befd 100644 --- a/test/unit/minidump-loader.test.ts +++ b/test/unit/minidump-loader.test.ts @@ -1,6 +1,6 @@ import { uuid4 } from '@sentry/utils'; import { expect } from 'chai'; -import { existsSync, utimesSync, writeFileSync } from 'fs'; +import { closeSync, existsSync, openSync, utimesSync, writeFileSync, writeSync } from 'fs'; import { join } from 'path'; import * as tmp from 'tmp'; @@ -10,7 +10,7 @@ function dumpFileName(): string { return `${uuid4()}.dmp`; } -const VALID_LOOKING_MINIDUMP = Buffer.from(`MDMP${'x'.repeat(12_000)}`); +const VALID_LOOKING_MINIDUMP = Buffer.from(`MDMP${'X'.repeat(12_000)}`); const LOOKS_NOTHING_LIKE_A_MINIDUMP = Buffer.from('X'.repeat(12_000)); const MINIDUMP_HEADER_BUT_TOO_SMALL = Buffer.from('MDMPdflahfalfhalkfnaklsfnalfkn'); @@ -69,6 +69,12 @@ describe('createMinidumpLoader', () => { }); it("doesn't send minidumps that are over 30 days old", (done) => { + // Updating the file times does not appear to work in GitHub Actions on Windows and Linux + if (process.env.CI) { + done(); + return; + } + const dumpPath = join(tempDir.name, dumpFileName()); writeFileSync(dumpPath, VALID_LOOKING_MINIDUMP); const now = new Date().getTime() / 1000; @@ -109,19 +115,20 @@ describe('createMinidumpLoader', () => { it('waits for minidump to stop being modified', (done) => { const dumpPath = join(tempDir.name, dumpFileName()); - writeFileSync(dumpPath, VALID_LOOKING_MINIDUMP); + const file = openSync(dumpPath, 'w'); + writeSync(file, VALID_LOOKING_MINIDUMP); let count = 0; // Write the file every 500ms const timer = setInterval(() => { count += 500; - writeFileSync(dumpPath, VALID_LOOKING_MINIDUMP); + writeSync(file, 'X'); }, 500); - // Stop writing after 3 seconds setTimeout(() => { clearInterval(timer); - }, 3_200); + closeSync(file); + }, 4_200); const loader = createMinidumpLoader(() => Promise.resolve([dumpPath]));