Skip to content

Commit

Permalink
ci: fix jest memory flakiness (#18859)
Browse files Browse the repository at this point in the history
  • Loading branch information
millsp committed Apr 27, 2023
1 parent 15dbb01 commit 8690c5b
Show file tree
Hide file tree
Showing 4 changed files with 781 additions and 344 deletions.
1 change: 1 addition & 0 deletions packages/client/package.json
Expand Up @@ -65,6 +65,7 @@
"@codspeed/benchmark.js-plugin": "1.0.2",
"@faker-js/faker": "7.6.0",
"@fast-check/jest": "1.6.0",
"@jest/create-cache-key-function": "29.5.0",
"@jest/globals": "29.4.3",
"@jest/test-sequencer": "29.4.3",
"@opentelemetry/api": "1.4.0",
Expand Down
67 changes: 67 additions & 0 deletions packages/client/tests/functional/esbuild-transformer.js
@@ -0,0 +1,67 @@
const fs = require('fs')

const esbuild = require('esbuild')
const getCacheKeyFunction = require('@jest/create-cache-key-function').default

const nodeVersion = process.version.match(/v(\d+)/)[1] || '14'
const cacheKeyFunction = getCacheKeyFunction([], ['v1', nodeVersion])

function needsTranspilation(contents, filename) {
if (filename.endsWith('.ts') === true) {
return true
}

if (filename.endsWith('.mjs') === true) {
return true
}

if (contents.includes('require(') === true) {
return false
}

if (contents.includes('module.exports') === true) {
return false
}

if (contents.includes('exports.') === true) {
return false
}

return true
}

const transformer = {
getCacheKey(contents, filename, ...rest) {
return cacheKeyFunction(filename, fs.statSync(filename).mtimeMs.toString(), ...rest)
},
process(_content, filename, { transformerConfig }) {
if (needsTranspilation(_content, filename) === true) {
return esbuild.transformSync(_content, {
sourcesContent: true,
minify: false,
sourcefile: filename,
loader: 'ts',
format: 'cjs',
platform: 'node',
target: `node${nodeVersion}`,
keepNames: true,
logLevel: 'error',
sourcemap: true,
...transformerConfig,
})
}

try {
return {
code: _content,
map: fs.readFileSync(`${filename}.map`, 'utf8'),
}
} catch (e) {}

return {
code: _content,
}
},
}

module.exports = transformer
24 changes: 2 additions & 22 deletions packages/client/tests/functional/jest.config.js
@@ -1,23 +1,12 @@
'use strict'
const os = require('os')
const path = require('path')

const packagesDir = path.resolve(__dirname, '..', '..', '..')
const runtimeDir = path.dirname(require.resolve('../../runtime'))

const isMacOrWindowsCI = Boolean(process.env.CI) && ['darwin', 'win32'].includes(process.platform)

module.exports = () => {
const configCommon = {
testMatch: ['**/*.ts', '!(**/*.d.ts)', '!(**/_utils/**)', '!(**/_*.ts)', '!(**/.generated/**)'],
// By default, jest passes every file it loads thorough a transform and caches result both on disk and in memory
// That includes all generated clients as well. So, unless we ignore them, they'd be kept in memory until test process
// is finished, even though they are needed for 1 test only
transformIgnorePatterns: [
'[\\.]generated[\\/]@prisma[\\/]client[\\/]',
escapeRegex(runtimeDir),
`${escapeRegex(packagesDir)}[\\/][^\\/]+[\\/]dist[\\/]`,
],
transformIgnorePatterns: [],
reporters: ['default'],
globalSetup: './_utils/globalSetup.js',
snapshotSerializers: ['@prisma/get-platform/src/test-utils/jestSnapshotSerializer'],
Expand Down Expand Up @@ -62,16 +51,7 @@ module.exports = () => {
return {
...configCommon,
transform: {
'^.+\\.(m?j|t)s$': '@swc/jest',
'^.+\\.(m?j|t)s$': ['./esbuild-transformer', {}],
},
}
}

/**
* https://stackoverflow.com/a/6969486
* @param {string} str
* @returns {string}
*/
function escapeRegex(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
}

0 comments on commit 8690c5b

Please sign in to comment.