From c39b5b4ed8ea4eb77d0d62e519b6a8d20032642c Mon Sep 17 00:00:00 2001 From: Kevin Scott <151596+thekevinscott@users.noreply.github.com> Date: Fri, 13 Oct 2023 07:13:47 -0400 Subject: [PATCH] Memory test should leverage bundler (#1215) --- .github/workflows/tests.yml | 9 +- internals/http-server/src/HttpServer.ts | 24 ++- .../test-runner/src/ClientsideTestRunner.ts | 2 +- package.json | 15 +- pnpm-lock.yaml | 5 +- scripts/package.json | 2 +- scripts/test.ts | 7 +- test/integration/browserstack.dependencies.ts | 9 - .../browserstack/tests/browser.mts | 9 - test/integration/memory.dependencies.ts | 9 - .../memory/tests/test.browser.mts} | 177 ++++++++++-------- test/integration/memory/vite.config.mts | 8 + test/integration/serverside/vite.config.mts | 2 +- test/misc/memory/jestconfig.js | 33 ---- 14 files changed, 145 insertions(+), 166 deletions(-) delete mode 100644 test/integration/browserstack.dependencies.ts delete mode 100644 test/integration/memory.dependencies.ts rename test/{misc/memory/test.browser.ts => integration/memory/tests/test.browser.mts} (77%) create mode 100644 test/integration/memory/vite.config.mts delete mode 100644 test/misc/memory/jestconfig.js diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a7c767cc5..b66a7d8f5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -272,8 +272,8 @@ jobs: - name: 'Integration Tests' run: pnpm test:model -- --platform node --ci --verbose --skip-bundle - memory-leaks: - name: 'Memory Leaks' + integration-memory-leaks: + name: 'Integration / Memory Leaks' runs-on: ubuntu-latest steps: - name: 'Checkout repository' @@ -286,11 +286,8 @@ jobs: with: node-version: 16 - - name: 'Bundle' - run: pnpm test:memory-leaks -- --ci --verbose --skip-test - - name: 'Memory Leak Tests' - run: pnpm test:memory-leaks -- --ci --verbose --skip-bundle + run: pnpm test:integration:memory-leaks -- --ci --verbose build-docs: name: 'Build Documentation' diff --git a/internals/http-server/src/HttpServer.ts b/internals/http-server/src/HttpServer.ts index 1bbba160f..df9374cc6 100644 --- a/internals/http-server/src/HttpServer.ts +++ b/internals/http-server/src/HttpServer.ts @@ -33,7 +33,8 @@ const closeHttpServer = (server: HTTPServer) => new Promise((resolve, reje resolve(); } }); -}) +}); + export class HttpServer { name?: string; @@ -55,10 +56,17 @@ export class HttpServer { if (!await exists(this.dist)) { throw new Error(`dist Directory "${this.dist}" supplied to server does not exist`); } - const httpServer = createServer((request, response) => handler(request, response, { - public: this.dist, - headers: serverHeaders, - })); + + const httpServer = createServer((request, response) => { + response.setHeader('Access-Control-Allow-Origin', '*'); + response.setHeader('Access-Control-Request-Method', '*'); + response.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET'); + response.setHeader('Access-Control-Allow-Headers', '*'); + return handler(request, response, { + public: this.dist, + headers: serverHeaders, + }); + }); this.httpServer = httpServer; await startHttpServer(httpServer, this.port); @@ -68,7 +76,11 @@ export class HttpServer { verbose('Starting server with tunnel'); await this.tunnel.start(); } - return this.url; + const url = this.url; + if (!url) { + throw new Error('No URL was created'); + } + return url; } get url() { diff --git a/internals/test-runner/src/ClientsideTestRunner.ts b/internals/test-runner/src/ClientsideTestRunner.ts index 46a5d7431..2bbed0598 100644 --- a/internals/test-runner/src/ClientsideTestRunner.ts +++ b/internals/test-runner/src/ClientsideTestRunner.ts @@ -192,8 +192,8 @@ export class ClientsideTestRunner { }); // Note: these must be done sequentially; there's a race condition bug in tunnelmole - await this.server.start(); await this.fixturesServer.start(); + await this.server.start(); } async stopServers(): Promise { diff --git a/package.json b/package.json index 4fe08af6c..2e2b15343 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "test:integration:browser": "wireit", "test:integration:serverside": "wireit", "test:model": "wireit", - "test:memory-leaks": "wireit", + "test:integration:memory-leaks": "wireit", "test:unit:browser:playwright": "wireit", "test:unit:browser:jest": "wireit", "test:unit:node": "wireit" @@ -54,12 +54,12 @@ "@babel/plugin-transform-modules-commonjs": "7.22.5", "@babel/preset-env": "7.22.10", "@babel/preset-typescript": "7.22.5", + "@internals/bundlers": "workspace:*", "@internals/common": "workspace:*", - "@internals/upscaler-cli": "workspace:*", - "@internals/webdriver": "workspace:*", "@internals/http-server": "workspace:*", "@internals/test-runner": "workspace:*", - "@internals/bundlers": "workspace:*", + "@internals/upscaler-cli": "workspace:*", + "@internals/webdriver": "workspace:*", "@rollup/plugin-commonjs": "25.0.4", "@rollup/plugin-node-resolve": "15.2.0", "@schemastore/package": "0.0.10", @@ -313,14 +313,15 @@ "build:models" ] }, - "test:memory-leaks": { - "command": "pnpm --filter @upscalerjs/scripts test:memory-leaks", + "test:integration:memory-leaks": { + "command": "pnpm --filter @upscalerjs/scripts test:integration:memory-leaks", "dependencies": [ "./internals/common:build", "./internals/http-server:build", "./internals/test-runner:build", "./packages/upscalerjs:build:browser", - "build:models:esm" + "build:models:esm", + "bundle:esbuild" ] }, "test:unit:browser:playwright": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 21e13456e..eb4acb4db 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1383,7 +1383,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/compat-data': 7.22.9 - '@babel/helper-validator-option': 7.22.5 + '@babel/helper-validator-option': 7.22.15 browserslist: 4.21.9 lru-cache: 5.1.1 semver: 6.3.1 @@ -1576,7 +1576,7 @@ packages: dependencies: '@babel/core': 7.22.10 '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-member-expression-to-functions': 7.22.5 + '@babel/helper-member-expression-to-functions': 7.23.0 '@babel/helper-optimise-call-expression': 7.22.5 /@babel/helper-simple-access@7.22.5: @@ -1616,6 +1616,7 @@ packages: /@babel/helper-validator-option@7.22.5: resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} engines: {node: '>=6.9.0'} + dev: true /@babel/helper-wrap-function@7.22.9: resolution: {integrity: sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q==} diff --git a/scripts/package.json b/scripts/package.json index a304b4812..7d8b9bb06 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -23,7 +23,7 @@ "test:integration:browserstack": "pnpm __run_command ./test.ts --kind integration --platform browser --runner browserstack", "test:integration:browser": "pnpm __run_command ./test.ts --kind integration --platform browser", "test:integration:serverside": "pnpm __run_command ./test.ts --kind integration --platform node", - "test:memory-leaks": "pnpm __run_command ./test.ts --kind memory --platform browser", + "test:integration:memory-leaks": "pnpm __run_command ./test.ts --kind memory --platform browser", "test:model": "pnpm __run_command ./test.ts --kind model", "update:version": "pnpm __run_command ./package-scripts/update-version.ts", "update:tfjs": "pnpm __run_command ./package-scripts/update-tfjs.ts", diff --git a/scripts/test.ts b/scripts/test.ts index c5ed7baea..bc201a443 100644 --- a/scripts/test.ts +++ b/scripts/test.ts @@ -44,7 +44,7 @@ const getFolder = (platform: Platform, runner: Runner, kind: Kind) => { const getAllTestFiles = (platform: Platform, runner: Runner, kind: Kind): string[] => { if (kind === 'memory') { - return ['test.browser.ts']; + return ['test.browser.mts']; } if (kind === 'model') { return ['model.ts']; @@ -129,7 +129,7 @@ const test = async (platform: Platform | Platform[], runner: Runner, kind: Kind, useGPU?: boolean, watch?: boolean; }) => { - if (skipBundle !== true && runner !== 'browserstack') { + if (skipBundle !== true && runner !== 'browserstack' && kind !== 'memory') { const dependencies = await getDependencies(platform, runner, kind, ...positionalArgs); const durations: number[] = []; for (const dependency of dependencies) { @@ -154,6 +154,9 @@ const test = async (platform: Platform | Platform[], runner: Runner, kind: Kind, if (runner === 'browserstack') { return ['pnpm', 'vitest', '-c', path.resolve(ROOT_DIR, './test/integration/browserstack/vite.config.mts')]; } + if (kind === 'memory') { + return ['pnpm', 'vitest', '-c', path.resolve(ROOT_DIR, './test/integration/memory/vite.config.mts')]; + } if (kind === 'integration' && platform === 'node') { return ['pnpm', 'vitest', '-c', path.resolve(ROOT_DIR, './test/integration/serverside/vite.config.mts')]; } diff --git a/test/integration/browserstack.dependencies.ts b/test/integration/browserstack.dependencies.ts deleted file mode 100644 index 4e58977fa..000000000 --- a/test/integration/browserstack.dependencies.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { bundleEsbuild } from "../lib/esm-esbuild/prepare"; - -const dependencies = { - browser: [ - bundleEsbuild, - ], -}; - -export default dependencies; diff --git a/test/integration/browserstack/tests/browser.mts b/test/integration/browserstack/tests/browser.mts index 13d8bc826..107740d60 100644 --- a/test/integration/browserstack/tests/browser.mts +++ b/test/integration/browserstack/tests/browser.mts @@ -59,8 +59,6 @@ describe('Browser Integration Tests', () => { beforeAll(async function browserBeforeAll() { await testRunner.beforeAll(); - console.log('server url', await testRunner.getServerURL()); - console.log('fixture url', await testRunner.getFixturesServerURL()); }, 20000); afterAll(async function browserAfterAll() { @@ -73,26 +71,19 @@ describe('Browser Integration Tests', () => { }); test.each(browserOptions)("%j", async (capabilities: BrowserOption) => { - console.log(capabilities) driver = getDriver({ ...capabilities, build }, { verbose: VERBOSE }); - console.log('got driver') const ROOT_URL = await testRunner.getServerURL();; await driver.get(ROOT_URL); - console.log('got root url') await driver.wait(async () => { const title = await driver.getTitle(); return title.endsWith('| Loaded'); }, 3000); - console.log('got loaded page') const fixturePath = `${await testRunner.getFixturesServerURL()}/pixel-upsampler/test/__fixtures__/fixture.png`; const modelPath = `${await testRunner.getFixturesServerURL()}/pixel-upsampler/models/x4/x4.json`; - console.log('got fixture and model paths') const result = await executeAsyncScript(driver, ({ fixturePath, modelPath }) => { const Upscaler = window['Upscaler'] as any; - console.log('got upscaler') const model = window["@upscalerjs/pixel-upsampler/x4"]; - console.log("got model") if (!model) { throw new Error('No model found for pixel upsampler'); } diff --git a/test/integration/memory.dependencies.ts b/test/integration/memory.dependencies.ts deleted file mode 100644 index 82dbee3b6..000000000 --- a/test/integration/memory.dependencies.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { bundleEsbuild } from "../lib/esm-esbuild/prepare"; - -const dependencies = { - ['test.browser']: [ - bundleEsbuild, - ], -}; - -export default dependencies; diff --git a/test/misc/memory/test.browser.ts b/test/integration/memory/tests/test.browser.mts similarity index 77% rename from test/misc/memory/test.browser.ts rename to test/integration/memory/tests/test.browser.mts index c64f620f7..29caf5ef8 100644 --- a/test/misc/memory/test.browser.ts +++ b/test/integration/memory/tests/test.browser.mts @@ -1,16 +1,19 @@ import { JSHandle, Page } from 'puppeteer'; -import { ESBUILD_DIST , mockCDN as esbuildMockCDN } from '../../lib/esm-esbuild/prepare'; +import { describe, it, expect, } from 'vitest'; import Upscaler, { ModelDefinition } from 'upscaler'; import * as tf from '@tensorflow/tfjs'; -import { BrowserTestRunner } from '../../integration/utils/BrowserTestRunner'; - -const JEST_TIMEOUT_IN_SECONDS = 60; -jest.setTimeout(JEST_TIMEOUT_IN_SECONDS * 1000); -jest.retryTimes(4); +import path from 'path'; +import { ClientsideTestRunner } from '@internals/test-runner/clientside'; const EXPECTED_LAYER_MODELS = 2; // I don't know why, but we start with layer model references in memory. const EXPECTED_UPSCALERS = 0; +const ROOT_BUNDLER_OUTPUT_DIR = process.env.ROOT_BUNDLER_OUTPUT_DIR; +if (typeof ROOT_BUNDLER_OUTPUT_DIR !== 'string') { + throw new Error('ROOT_BUNDLER_OUTPUT_DIR not defined in env'); +} +const ESBUILD_DIST_FOLDER = path.resolve(ROOT_BUNDLER_OUTPUT_DIR, 'esbuild/dist') + // https://puppeteer.github.io/puppeteer/docs/10.0.0/puppeteer.page.queryobjects/#example const countObjects = async (page: Page, prototype: JSHandle): Promise => { const instances = await page.queryObjects(prototype); @@ -86,9 +89,11 @@ const getStartingMemory = async (page: Page) => { }; describe('Memory Leaks', () => { - const testRunner = new BrowserTestRunner({ - dist: ESBUILD_DIST, - mockCDN: esbuildMockCDN, + const testRunner = new ClientsideTestRunner({ + name: 'memory-leaks', + mock: true, + dist: ESBUILD_DIST_FOLDER, + useTunnel: true, }); beforeAll(async function beforeAll() { @@ -122,13 +127,12 @@ describe('Memory Leaks', () => { const endingObjects = ending[name]; try { expect(endingObjects).toEqual(startingObjects); - } catch(err) { + } catch (err) { const diff = endingObjects - startingObjects; expect(new Error(`Memory Leak, there are ${diff} objects of type ${name} and there should be 0. Ending objects: ${endingObjects}, starting objects: ${startingObjects}`)).toBeUndefined(); } } - - } + }; // describe('examples of tests that explicitly throw memory leaks', () => { // // // it('should throw because of maps', async () => { @@ -206,13 +210,13 @@ describe('Memory Leaks', () => { it('should create upscalers', async () => { const startingMemory = await getStartingMemory(testRunner.page); - await testRunner.page.evaluate(async (times) => { + await testRunner.page.evaluate(async ({ times }) => { const Upscaler = window['Upscaler']; for (let i = 0; i < times; i++) { const upscaler = new Upscaler(); await upscaler.dispose(); } - }, TIMES_TO_CHECK); + }, { times: TIMES_TO_CHECK }); await tick(testRunner.page); @@ -224,9 +228,9 @@ describe('Memory Leaks', () => { it('should create an Upscaler instance and warm up', async () => { const startingMemory = await getStartingMemory(testRunner.page); - await testRunner.page.evaluate(async (times) => { + await testRunner.page.evaluate(async ({ times }) => { const Upscaler = window['Upscaler']; - const model = window['pixel-upsampler']['x4']; + const model = window['@upscalerjs/pixel-upsampler/x4']; if (!model) { throw new Error('No model found') } @@ -237,7 +241,7 @@ describe('Memory Leaks', () => { }); await upscaler.dispose(); } - }, TIMES_TO_CHECK); + }, { times: TIMES_TO_CHECK }); await tick(testRunner.page); @@ -249,9 +253,9 @@ describe('Memory Leaks', () => { it('should create an Upscaler instance with a custom model', async () => { const startingMemory = await getStartingMemory(testRunner.page); - await testRunner.page.evaluate(async (times) => { + await testRunner.page.evaluate(async ({ times }) => { const Upscaler = window['Upscaler']; - const model = window['pixel-upsampler']['x4']; + const model = window['@upscalerjs/pixel-upsampler/x4']; if (!model) { throw new Error('No model found') } @@ -261,7 +265,7 @@ describe('Memory Leaks', () => { }); await upscaler.dispose(); } - }, TIMES_TO_CHECK); + }, { times: TIMES_TO_CHECK }); await tick(testRunner.page); const endingMemory = await getMemory(testRunner.page); @@ -272,10 +276,11 @@ describe('Memory Leaks', () => { describe('Upscale with base64 output', () => { it('should upscale with no pre / post processing functions', async () => { const startingMemory = await getStartingMemory(testRunner.page); + const fixturePath = `${await testRunner.getFixturesServerURL()}/pixel-upsampler/test/__fixtures__/fixture.png`; - const image = await testRunner.page.evaluate(async (times) => { + const image = await testRunner.page.evaluate(async ({ times, fixturePath }) => { const Upscaler = window['Upscaler']; - const model = window['pixel-upsampler']['x4']; + const model = window['@upscalerjs/pixel-upsampler/x4']; if (!model) { throw new Error('No model found') } @@ -284,27 +289,28 @@ describe('Memory Leaks', () => { const upscaler = new Upscaler({ model, }); - image = await upscaler.execute(window['fixtures']['pixel-upsampler']); + image = await upscaler.execute(fixturePath); await upscaler.dispose(); } return image; - }, TIMES_TO_CHECK); + }, { times: TIMES_TO_CHECK, fixturePath }); await tick(testRunner.page); const endingMemory = await getMemory(testRunner.page); const names = prototypes.map(p => p.name); checkMemory(names, startingMemory, endingMemory); - expect(image!.substring(0,22)).toEqual('data:image/png;base64,'); + expect(image!.substring(0, 22)).toEqual('data:image/png;base64,'); }); it('should upscale with a pre and no post processing functions', async () => { const startingMemory = await getStartingMemory(testRunner.page); + const fixturePath = `${await testRunner.getFixturesServerURL()}/pixel-upsampler/test/__fixtures__/fixture.png`; - const image = await testRunner.page.evaluate(async (times) => { + const image = await testRunner.page.evaluate(async ({ times, fixturePath }) => { const tf = window['tf']; const Upscaler = window['Upscaler']; - const model = window['pixel-upsampler']['x4']; + const model = window['@upscalerjs/pixel-upsampler/x4']; if (!model) { throw new Error('No model found') } @@ -316,28 +322,29 @@ describe('Memory Leaks', () => { preprocess: (image) => tf.mul(image, 1), } }); - image = await upscaler.execute(window['fixtures']['pixel-upsampler']); + image = await upscaler.execute(fixturePath); await upscaler.dispose(); } return image; - }, TIMES_TO_CHECK); + }, { times: TIMES_TO_CHECK, fixturePath }); await tick(testRunner.page); const endingMemory = await getMemory(testRunner.page); const names = prototypes.map(p => p.name); checkMemory(names, startingMemory, endingMemory); - expect(image!.substring(0,22)).toEqual('data:image/png;base64,'); + expect(image!.substring(0, 22)).toEqual('data:image/png;base64,'); }); - + it('should upscale with no pre and a post processing functions', async () => { const startingMemory = await getStartingMemory(testRunner.page); + const fixturePath = `${await testRunner.getFixturesServerURL()}/pixel-upsampler/test/__fixtures__/fixture.png`; - const image = await testRunner.page.evaluate(async (times) => { + const image = await testRunner.page.evaluate(async ({ times, fixturePath }) => { const tf = window['tf']; const Upscaler = window['Upscaler']; let image; - const model = window['pixel-upsampler']['x4']; + const model = window['@upscalerjs/pixel-upsampler/x4']; if (!model) { throw new Error('No model found') } @@ -348,27 +355,28 @@ describe('Memory Leaks', () => { postprocess: (image) => tf.mul(image, 1), } }); - image = await upscaler.execute(window['fixtures']['pixel-upsampler']); + image = await upscaler.execute(fixturePath); await upscaler.dispose(); } return image; - }, TIMES_TO_CHECK); + }, { times: TIMES_TO_CHECK, fixturePath }); await tick(testRunner.page); const endingMemory = await getMemory(testRunner.page); const names = prototypes.map(p => p.name); checkMemory(names, startingMemory, endingMemory); - expect(image!.substring(0,22)).toEqual('data:image/png;base64,'); + expect(image!.substring(0, 22)).toEqual('data:image/png;base64,'); }); it('should upscale with a pre and a post processing functions', async () => { const startingMemory = await getStartingMemory(testRunner.page); + const fixturePath = `${await testRunner.getFixturesServerURL()}/pixel-upsampler/test/__fixtures__/fixture.png`; - const image = await testRunner.page.evaluate(async (times) => { + const image = await testRunner.page.evaluate(async ({ times, fixturePath }) => { const tf = window['tf']; const Upscaler = window['Upscaler']; - const model = window['pixel-upsampler']['x4']; + const model = window['@upscalerjs/pixel-upsampler/x4']; if (!model) { throw new Error('No model found') } @@ -381,28 +389,29 @@ describe('Memory Leaks', () => { postprocess: (image) => tf.mul(image, 1), } }); - image = await upscaler.execute(window['fixtures']['pixel-upsampler']); + image = await upscaler.execute(fixturePath); await upscaler.dispose(); } return image; - }, TIMES_TO_CHECK); + }, { times: TIMES_TO_CHECK, fixturePath }); await tick(testRunner.page); const endingMemory = await getMemory(testRunner.page); const names = prototypes.map(p => p.name); checkMemory(names, startingMemory, endingMemory); - expect(image!.substring(0,22)).toEqual('data:image/png;base64,'); + expect(image!.substring(0, 22)).toEqual('data:image/png;base64,'); }); }); it('should upscale with a pre and a post processing functions into a tensor', async () => { const startingMemory = await getStartingMemory(testRunner.page); + const fixturePath = `${await testRunner.getFixturesServerURL()}/pixel-upsampler/test/__fixtures__/fixture.png`; - await testRunner.page.evaluate(async (times) => { + await testRunner.page.evaluate(async ({ times, fixturePath }) => { const tf = window['tf']; const Upscaler = window['Upscaler']; - const model = window['pixel-upsampler']['x4']; + const model = window['@upscalerjs/pixel-upsampler/x4']; if (!model) { throw new Error('No model found') } @@ -414,7 +423,7 @@ describe('Memory Leaks', () => { postprocess: (image) => tf.mul(image, 1), } }); - const tensor = await upscaler.execute(window['fixtures']['pixel-upsampler'], { + const tensor = await upscaler.execute(fixturePath, { output: 'tensor', }); @@ -422,7 +431,7 @@ describe('Memory Leaks', () => { await upscaler.dispose(); } - }, TIMES_TO_CHECK); + }, { times: TIMES_TO_CHECK, fixturePath }); await tick(testRunner.page); const endingMemory = await getMemory(testRunner.page); @@ -431,22 +440,23 @@ describe('Memory Leaks', () => { }); it('should upscale with a pre and a post processing functions from a tensor', async () => { - await testRunner.page.evaluate(async () => { + const fixturePath = `${await testRunner.getFixturesServerURL()}/pixel-upsampler/test/__fixtures__/fixture.png`; + await testRunner.page.evaluate(async ({ fixturePath }) => { const getImage = (): Promise => new Promise(resolve => { const img = new Image(); - img.src = window['fixtures']['pixel-upsampler']; + img.src = fixturePath; img.crossOrigin = 'anonymous'; img.onload = () => resolve(img); }) const img = await getImage(); window['src'] = await window['tf'].browser.fromPixels(img); - }); + }, { fixturePath }); const startingMemory = await getStartingMemory(testRunner.page); - const image = await testRunner.page.evaluate(async (times) => { + const image = await testRunner.page.evaluate(async ({ times, fixturePath }) => { const tf = window['tf']; const Upscaler = window['Upscaler']; - const model = window['pixel-upsampler']['x4']; + const model = window['@upscalerjs/pixel-upsampler/x4']; if (!model) { throw new Error('No model found') } @@ -464,23 +474,24 @@ describe('Memory Leaks', () => { await upscaler.dispose(); } return output!; - }, TIMES_TO_CHECK); + }, { times: TIMES_TO_CHECK, fixturePath }); await tick(testRunner.page); const endingMemory = await getMemory(testRunner.page); const names = prototypes.map(p => p.name); checkMemory(names, startingMemory, endingMemory); - expect(image.substring(0,22)).toEqual('data:image/png;base64,'); + expect(image.substring(0, 22)).toEqual('data:image/png;base64,'); const isDisposed = await testRunner.page.evaluate(async () => window['src']!.isDisposed); expect(isDisposed).toEqual(false); }); it('should upscale with a pre and a post processing functions with patch sizes', async () => { + const fixturePath = `${await testRunner.getFixturesServerURL()}/pixel-upsampler/test/__fixtures__/fixture.png`; const startingMemory = await getStartingMemory(testRunner.page); - const image = await testRunner.page.evaluate(async (times) => { + const image = await testRunner.page.evaluate(async ({ times, fixturePath }) => { const tf = window['tf']; const Upscaler = window['Upscaler']; - const model = window['pixel-upsampler']['x4']; + const model = window['@upscalerjs/pixel-upsampler/x4']; if (!model) { throw new Error('No model found') } @@ -493,7 +504,7 @@ describe('Memory Leaks', () => { postprocess: (image) => tf.mul(image, 1), } }); - output = await upscaler.execute(window['fixtures']['pixel-upsampler'], { + output = await upscaler.execute(fixturePath, { patchSize: 5, padding: 0, }); @@ -501,18 +512,18 @@ describe('Memory Leaks', () => { await upscaler.dispose(); } return output; - }, TIMES_TO_CHECK); + }, { times: TIMES_TO_CHECK, fixturePath }); await tick(testRunner.page); const endingMemory = await getMemory(testRunner.page); const names = prototypes.map(p => p.name); checkMemory(names, startingMemory, endingMemory); - expect(image!.substring(0,22)).toEqual('data:image/png;base64,'); + expect(image!.substring(0, 22)).toEqual('data:image/png;base64,'); }); // it('should upscale with an ESRGAN-thick model', async () => { // const startingMemory = await getStartingMemory(testRunner.page); - // const image = await testRunner.page.evaluate(async (times) => { + // const image = await testRunner.page.evaluate(async ({ times }) => { // const Upscaler = window['Upscaler']; // const ESRGANThick = window['esrgan-thick']['4x']; // let output; @@ -525,7 +536,7 @@ describe('Memory Leaks', () => { // await upscaler.dispose(); // } // return output; - // }, TIMES_TO_CHECK); + // }, { times: TIMES_TO_CHECK }); // await tick(testRunner.page); // const endingMemory = await getMemory(testRunner.page); @@ -535,10 +546,11 @@ describe('Memory Leaks', () => { // }); it('should callback to progress with a src', async () => { + const fixturePath = `${await testRunner.getFixturesServerURL()}/pixel-upsampler/test/__fixtures__/fixture.png`; const startingMemory = await getStartingMemory(testRunner.page); - const image = await testRunner.page.evaluate(async (times) => { + const image = await testRunner.page.evaluate(async ({ times, fixturePath }) => { const Upscaler = window['Upscaler']; - const model = window['pixel-upsampler']['x4']; + const model = window['@upscalerjs/pixel-upsampler/x4']; if (!model) { throw new Error('No model found') } @@ -547,7 +559,7 @@ describe('Memory Leaks', () => { const upscaler = new Upscaler({ model, }); - await upscaler.execute(window['fixtures']['pixel-upsampler'], { + await upscaler.execute(fixturePath, { output: 'base64', patchSize: 14, padding: 2, @@ -559,21 +571,23 @@ describe('Memory Leaks', () => { await upscaler.dispose(); } return output; - }, TIMES_TO_CHECK); + }, { times: TIMES_TO_CHECK, fixturePath }); await tick(testRunner.page); const endingMemory = await getMemory(testRunner.page); const names = prototypes.map(p => p.name); checkMemory(names, startingMemory, endingMemory); - expect((image! as string).substring(0,22)).toEqual('data:image/png;base64,'); + expect((image! as string).substring(0, 22)).toEqual('data:image/png;base64,'); }); it('should callback to progress with a tensor', async () => { + const fixturePath = `${await testRunner.getFixturesServerURL()}/pixel-upsampler/test/__fixtures__/fixture.png`; const startingMemory = await getStartingMemory(testRunner.page); - const image = await testRunner.page.evaluate(async (times) => { + await new Promise(r => setTimeout(r, 1000 * 10)); + const image = await testRunner.page.evaluate(async ({ times, fixturePath }) => { const Upscaler = window['Upscaler']; let output: tf.Tensor; - const model = window['pixel-upsampler']['x4']; + const model = window['@upscalerjs/pixel-upsampler/x4']; if (!model) { throw new Error('No model found') } @@ -581,7 +595,7 @@ describe('Memory Leaks', () => { const upscaler = new Upscaler({ model, }); - await upscaler.execute(window['fixtures']['pixel-upsampler'], { + await upscaler.execute(fixturePath, { output: 'base64', progressOutput: 'tensor', patchSize: 14, @@ -598,7 +612,7 @@ describe('Memory Leaks', () => { } window['output'] = output!; return output!; - }, TIMES_TO_CHECK); + }, { times: TIMES_TO_CHECK, fixturePath }); await tick(testRunner.page); expect(image.shape).toEqual([16, 16, 3]); @@ -611,11 +625,12 @@ describe('Memory Leaks', () => { }); it('should cancel without leaking memory', async () => { + const fixturePath = `${await testRunner.getFixturesServerURL()}/pixel-upsampler/test/__fixtures__/fixture.png`; const startingMemory = await getStartingMemory(testRunner.page); - await testRunner.page.evaluate((times) => new Promise(resolve => { + await testRunner.page.evaluate(({ times, fixturePath }) => new Promise(resolve => { const Upscaler = window['Upscaler']; const abortController = new AbortController(); - const model = window['pixel-upsampler']['x4']; + const model = window['@upscalerjs/pixel-upsampler/x4']; if (!model) { throw new Error('No model found') } @@ -623,7 +638,7 @@ describe('Memory Leaks', () => { const upscaler = new Upscaler({ model, }); - upscaler.execute(window['fixtures']['pixel-upsampler'], { + upscaler.execute(fixturePath, { output: 'base64', signal: abortController.signal, }).catch(() => { @@ -631,7 +646,7 @@ describe('Memory Leaks', () => { }); abortController.abort(); } - }), TIMES_TO_CHECK); + }), { times: TIMES_TO_CHECK, fixturePath }); await tick(testRunner.page); const endingMemory = await getMemory(testRunner.page); @@ -640,11 +655,12 @@ describe('Memory Leaks', () => { }); it('should cancel without leaking memory with patch sizes', async () => { + const fixturePath = `${await testRunner.getFixturesServerURL()}/pixel-upsampler/test/__fixtures__/fixture.png`; const startingMemory = await getStartingMemory(testRunner.page); - await testRunner.page.evaluate(async (times) => { + await testRunner.page.evaluate(async ({ times, fixturePath }) => { const Upscaler = window['Upscaler']; const abortController = new AbortController(); - const model = window['pixel-upsampler']['x4']; + const model = window['@upscalerjs/pixel-upsampler/x4']; if (!model) { throw new Error('No model found') } @@ -653,7 +669,7 @@ describe('Memory Leaks', () => { model, }); try { - await upscaler.execute(window['fixtures']['pixel-upsampler'], { + await upscaler.execute(fixturePath, { output: 'base64', signal: abortController.signal, patchSize: 14, @@ -668,7 +684,7 @@ describe('Memory Leaks', () => { await upscaler.dispose(); } - }, TIMES_TO_CHECK); + }, { times: TIMES_TO_CHECK, fixturePath }); await tick(testRunner.page); const endingMemory = await getMemory(testRunner.page); @@ -677,10 +693,11 @@ describe('Memory Leaks', () => { }); it('should cancel without leaking memory with patch sizes and a tensor response', async () => { + const fixturePath = `${await testRunner.getFixturesServerURL()}/pixel-upsampler/test/__fixtures__/fixture.png`; const startingMemory = await getStartingMemory(testRunner.page); - await testRunner.page.evaluate(async (times) => { + await testRunner.page.evaluate(async ({ times, fixturePath }) => { const Upscaler = window['Upscaler']; - const model = window['pixel-upsampler']['x4']; + const model = window['@upscalerjs/pixel-upsampler/x4']; if (!model) { throw new Error('No model found') } @@ -690,7 +707,7 @@ describe('Memory Leaks', () => { model, }); try { - await upscaler.execute(window['fixtures']['pixel-upsampler'], { + await upscaler.execute(fixturePath, { output: 'tensor', signal: abortController.signal, patchSize: 14, @@ -706,7 +723,7 @@ describe('Memory Leaks', () => { await upscaler.dispose(); } - }, TIMES_TO_CHECK); + }, { times: TIMES_TO_CHECK, fixturePath }); await tick(testRunner.page); const endingMemory = await getMemory(testRunner.page); diff --git a/test/integration/memory/vite.config.mts b/test/integration/memory/vite.config.mts new file mode 100644 index 000000000..8c57e8bd2 --- /dev/null +++ b/test/integration/memory/vite.config.mts @@ -0,0 +1,8 @@ +import { defineConfig, mergeConfig } from 'vitest/config'; +import viteConfig from '../../vite.config.mjs'; + +export default mergeConfig(viteConfig, defineConfig({ + test: { + root: __dirname, + }, +})); diff --git a/test/integration/serverside/vite.config.mts b/test/integration/serverside/vite.config.mts index 5c92c704e..8c57e8bd2 100644 --- a/test/integration/serverside/vite.config.mts +++ b/test/integration/serverside/vite.config.mts @@ -5,4 +5,4 @@ export default mergeConfig(viteConfig, defineConfig({ test: { root: __dirname, }, -})) +})); diff --git a/test/misc/memory/jestconfig.js b/test/misc/memory/jestconfig.js deleted file mode 100644 index a603cf9dd..000000000 --- a/test/misc/memory/jestconfig.js +++ /dev/null @@ -1,33 +0,0 @@ -const path = require('path'); -const ROOT = path.resolve(__dirname, '../../..'); -const TEST_ROOT = path.resolve(ROOT, 'test') - -const jestconfig = require(path.resolve(TEST_ROOT, 'jestconfig.json')); -const tsJestRegex = Object.keys(jestconfig.transform).filter(key => key.includes('ts')).pop(); -if (!tsJestRegex) { - throw new Error('No matching key could be found for .ts'); -} -const tsJestTsConfig = jestconfig.transform[tsJestRegex]; -const transform = { - ...jestconfig.transform, - [tsJestRegex]: [ - tsJestTsConfig[0], - { - ...tsJestTsConfig[1], - tsconfig: { - ...tsJestTsConfig[1].tsconfig, - "target": "esnext", - } - }, - ], -} -module.exports = { - ...jestconfig, - "setupFilesAfterEnv": [path.resolve(TEST_ROOT, "jest.setup.ts")], - setupFiles: [], - "testRegex": "(/.*|(\\.|/)(test|spec))\\.(tsx?)$", - roots: [ - "", - ], - "transform": transform -};