-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add caching to run failed and longer tests first #1541
Merged
sheremet-va
merged 17 commits into
vitest-dev:main
from
sheremet-va:feat/order-tests-by-duration
Jul 3, 2022
Merged
Changes from 11 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
49f1e18
feat: add caching to run failed and longer tests first
sheremet-va 855144b
chore: cleanup
sheremet-va 174ab62
chore: add clearCache
sheremet-va 37199e7
chore: update lockfile
sheremet-va cbee24c
chore: add filesCache
sheremet-va 92dd023
refactor: add sequelizer
sheremet-va 553d285
chore: lockfile
sheremet-va 63d27d4
refactor: renaming
sheremet-va 78bf586
chore: dont override version
sheremet-va dae2bc0
chore: fix clearCache
sheremet-va e396589
chore: guard slice
sheremet-va ee19777
Merge branch 'main' of https://github.com/vitest-dev/vitest into feat…
sheremet-va b9e251d
chore: cleanup
sheremet-va 4f401f1
docs: cleanup
sheremet-va 073b4dd
chore: cleanup
sheremet-va f87b88a
chore: remove command for now
sheremet-va 8444004
refactor: cleanup
sheremet-va File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import fs, { type Stats } from 'fs' | ||
|
||
type FileStatsCache = Pick<Stats, 'size'> | ||
|
||
export class FilesStatsCache { | ||
public cache = new Map<string, FileStatsCache>() | ||
|
||
public getStats(fsPath: string): FileStatsCache | undefined { | ||
return this.cache.get(fsPath) | ||
} | ||
|
||
public async updateStats(fsPath: string) { | ||
if (!fs.existsSync(fsPath)) | ||
return | ||
|
||
const stats = await fs.promises.stat(fsPath) | ||
this.cache.set(fsPath, { size: stats.size }) | ||
} | ||
|
||
public removeStats(fsPath: string) { | ||
this.cache.delete(fsPath) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import fs from 'fs' | ||
import { findUp } from 'find-up' | ||
import { resolve } from 'pathe' | ||
import { loadConfigFromFile } from 'vite' | ||
import { configFiles } from '../../constants' | ||
import type { CliOptions } from '../cli-api' | ||
import { slash } from '../../utils' | ||
|
||
export class VitestCache { | ||
static resolveCacheDir(root: string, dir: string | undefined) { | ||
return resolve(root, slash(dir || 'node_modules/.vitest')) | ||
} | ||
|
||
static async clearCache(options: CliOptions) { | ||
const root = resolve(options.root || process.cwd()) | ||
|
||
const configPath = options.config | ||
? resolve(root, options.config) | ||
: await findUp(configFiles, { cwd: root } as any) | ||
|
||
const config = await loadConfigFromFile({ command: 'serve', mode: 'test' }, configPath) | ||
|
||
if (!config) | ||
throw new Error(`[vitest] Not able to load config from ${configPath}`) | ||
|
||
const cache = config.config.test?.cache | ||
|
||
if (cache === false) | ||
throw new Error('[vitest] Cache is disabled') | ||
|
||
const cachePath = VitestCache.resolveCacheDir(root, cache?.dir) | ||
|
||
let cleared = false | ||
|
||
if (fs.existsSync(cachePath)) { | ||
fs.rmSync(cachePath, { recursive: true, force: true }) | ||
cleared = true | ||
} | ||
return { dir: cachePath, cleared } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import fs from 'fs' | ||
import { dirname, resolve } from 'pathe' | ||
import type { File, ResolvedConfig } from '../../types' | ||
import { version } from '../../../package.json' | ||
|
||
export interface SuiteResultCache { | ||
failed: boolean | ||
duration: number | ||
} | ||
|
||
export class ResultsCache { | ||
private cache = new Map<string, SuiteResultCache>() | ||
private cachePath: string | null = null | ||
private version: string = version | ||
private root = '/' | ||
|
||
setConfig(root: string, config: ResolvedConfig['cache']) { | ||
this.root = root | ||
if (config) | ||
this.cachePath = resolve(config.dir, 'results.json') | ||
} | ||
|
||
getResults(fsPath: string) { | ||
return this.cache.get(fsPath?.slice(this.root.length)) | ||
} | ||
|
||
async readFromCache() { | ||
if (!this.cachePath) | ||
return | ||
|
||
if (fs.existsSync(this.cachePath)) { | ||
const resultsCache = await fs.promises.readFile(this.cachePath, 'utf8') | ||
const { results, version } = JSON.parse(resultsCache) | ||
this.cache = new Map(results) | ||
this.version = version | ||
} | ||
} | ||
|
||
updateResults(files: File[]) { | ||
files.forEach((file) => { | ||
const result = file.result | ||
if (!result) | ||
return | ||
const duration = result.duration || 0 | ||
// store as relative, so cache would be the same in CI and locally | ||
const relativePath = file.filepath?.slice(this.root.length) | ||
this.cache.set(relativePath, { | ||
duration: duration >= 0 ? duration : 0, | ||
failed: result.state === 'fail', | ||
}) | ||
}) | ||
} | ||
|
||
removeFromCache(filepath: string) { | ||
this.cache.delete(filepath) | ||
} | ||
|
||
async writeToCache() { | ||
if (!this.cachePath) | ||
return | ||
|
||
const resultsCache = Array.from(this.cache.entries()) | ||
|
||
const cacheDirname = dirname(this.cachePath) | ||
|
||
if (!fs.existsSync(cacheDirname)) | ||
await fs.promises.mkdir(cacheDirname, { recursive: true }) | ||
|
||
await fs.promises.writeFile(this.cachePath, JSON.stringify({ | ||
version: this.version, | ||
results: resultsCache, | ||
})) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not a fan of having pascal case in CLI. Maybe
purge
, WDYT?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why
purge
tho? Don't see any connection to cache. We can doclear-cache
, I guess.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just want to find a single word to represent it. As for reference, here is what package managers are doing:
And for Vite: https://vitejs.dev/guide/dep-pre-bundling.html#file-system-cache
/cc @patak-dev in case we are also going to add a clear cache command for Vite, I think we better align the commands
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do
vitect clean
, and passcache
as an argument. In future we might add option to clear only some specific caches.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated to proposed solution. What do you think, @antfu, @patak-dev?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardly disagree with using a lot - I don't know why you would even use it in Vitest, only to clear malformed cache maybe.
Also single words only look good, but confuse a lot. What
--clean
means? What happens when you call it? I want to havecache
in the name somewhere.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I use
--force
a lot because ya, I'm debugging Vite cache itself 👀So I agree with you that normally isn't something that final users will be reaching a lot. I'm fine with
--clearCache
(maybe good to check how it will look later for--clearCache="parts of it"
)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will look something like this:
We use cac's notation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@antfu what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will remove command for now, since I want this feature to be released today. Command will be in another PR.