Skip to content

Commit

Permalink
More tests
Browse files Browse the repository at this point in the history
  • Loading branch information
arcanis committed Oct 15, 2021
1 parent dd32d14 commit 30a3b02
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 26 deletions.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Filename, ppath, xfs} from '@yarnpkg/fslib';
import {Filename, PortablePath, ppath, xfs} from '@yarnpkg/fslib';
import {RequestType, startRegistryRecording} from 'pkg-tests-core/sources/utils/tests';

export {};
Expand Down Expand Up @@ -96,6 +96,34 @@ describe(`Features`, () => {
}]);
}));

it(`should produce a stable lockfile, regardless of the architecture`, makeTemporaryEnv({
dependencies: {
[`native`]: `1.0.0`,
},
}, async ({path, run, source}) => {
await xfs.writeJsonPromise(ppath.join(path, Filename.rc), {
supportedArchitectures: {
os: [`foo`],
cpu: [`x64`],
},
});

await run(`install`);
const lockfile64 = await xfs.readFilePromise(ppath.join(path, Filename.lockfile), `utf8`);

await xfs.writeJsonPromise(ppath.join(path, Filename.rc), {
supportedArchitectures: {
os: [`foo`],
cpu: [`x86`],
},
});

await run(`install`);
const lockfile86 = await xfs.readFilePromise(ppath.join(path, Filename.lockfile), `utf8`);

expect(lockfile86).toEqual(lockfile64);
}));

it(`should produce a stable PnP hook, regardless of the architecture`, makeTemporaryEnv({
dependencies: {
[`native`]: `1.0.0`,
Expand Down Expand Up @@ -123,5 +151,140 @@ describe(`Features`, () => {

expect(hook86).toEqual(hook64);
}));

it(`shouldn't break when using --check-cache with native packages`, makeTemporaryEnv({
dependencies: {
[`native`]: `1.0.0`,
},
}, async ({path, run, source}) => {
await xfs.writeJsonPromise(ppath.join(path, Filename.rc), {
supportedArchitectures: {
os: [`foo`],
cpu: [`x64`],
},
});

await run(`install`);

const cacheFolder = ppath.join(path, `.yarn/cache` as PortablePath);
const cacheListing = await xfs.readdirPromise(cacheFolder);
const nativeFile = cacheListing.find(entry => entry.startsWith(`native-foo-x64-`));

// Sanity check
expect(nativeFile).toBeDefined();

await run(`install`, `--check-cache`);
}));

it(`should detect packages being tampered when using --check-cache`, makeTemporaryEnv({
dependencies: {
[`native`]: `1.0.0`,
},
}, async ({path, run, source}) => {
await xfs.writeJsonPromise(ppath.join(path, Filename.rc), {
supportedArchitectures: {
os: [`foo`],
cpu: [`x64`],
},
});

await run(`install`);

const cacheFolder = ppath.join(path, `.yarn/cache` as PortablePath);
const cacheListing = await xfs.readdirPromise(cacheFolder);
const nativeFile = cacheListing.find(entry => entry.startsWith(`native-foo-x64-`));

// Sanity check
expect(nativeFile).toBeDefined();

await xfs.appendFilePromise(ppath.join(cacheFolder, nativeFile as Filename), Buffer.from([0]));

await expect(async () => {
await run(`install`, `--check-cache`);
}).rejects.toThrow();
}));

it(`should also validate other architectures than the current one if necessary when using --check-cache`, makeTemporaryEnv({
dependencies: {
[`native`]: `1.0.0`,
},
}, async ({path, run, source}) => {
await xfs.writeJsonPromise(ppath.join(path, Filename.rc), {
supportedArchitectures: {
os: [`foo`],
cpu: [`x64`, `x86`],
},
});

await run(`install`);

const cacheFolder = ppath.join(path, `.yarn/cache` as PortablePath);
const cacheListing = await xfs.readdirPromise(cacheFolder);
const nativeFile = cacheListing.find(entry => entry.startsWith(`native-foo-x64-`));

// Sanity check
expect(nativeFile).toBeDefined();

await xfs.appendFilePromise(ppath.join(cacheFolder, nativeFile as Filename), Buffer.from([0]));

await xfs.writeJsonPromise(ppath.join(path, Filename.rc), {
supportedArchitectures: {
os: [`foo`],
cpu: [`x86`],
},
});

await expect(async () => {
await run(`install`, `--check-cache`);
}).rejects.toThrow();
}));

it(`should only fetch other architectures when using --check-cache if they are already in the cache`, makeTemporaryEnv({
dependencies: {
[`native`]: `1.0.0`,
},
}, async ({path, run, source}) => {
await xfs.writeJsonPromise(ppath.join(path, Filename.rc), {
supportedArchitectures: {
os: [`foo`],
cpu: [`x64`, `x86`],
},
});

await run(`install`);

await xfs.writeJsonPromise(ppath.join(path, Filename.rc), {
supportedArchitectures: {
os: [`foo`],
cpu: [`x64`],
},
});

const recording = await startRegistryRecording(async () => {
await run(`install`, `--check-cache`);
});

const tarballRequests = recording.filter(request => {
return request.type === RequestType.PackageTarball;
}).sort((a, b) => {
const aJson = JSON.stringify(a);
const bJson = JSON.stringify(b);
return aJson < bJson ? -1 : aJson > bJson ? 1 : 0;
});

expect(tarballRequests).toEqual([{
type: RequestType.PackageTarball,
localName: `native`,
version: `1.0.0`,
}, {
type: RequestType.PackageTarball,
localName: `native-foo-x64`,
version: `1.0.0`,
}, {
type: RequestType.PackageTarball,
localName: `native-foo-x86`,
version: `1.0.0`,
}]);
}));
});
});
19 changes: 10 additions & 9 deletions packages/yarnpkg-core/sources/Cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class Cache {

public readonly cacheKey: string;

private mutexes: Map<LocatorHash, Promise<readonly [PortablePath, string | null]>> = new Map();
private mutexes: Map<LocatorHash, Promise<readonly [boolean, PortablePath, string | null]>> = new Map();

/**
* To ensure different instances of `Cache` doesn't end up copying to the same
Expand Down Expand Up @@ -156,7 +156,6 @@ export class Cache {

async fetchPackageFromCache(locator: Locator, expectedChecksum: string | null, {onHit, onMiss, loader}: {onHit?: () => void, onMiss?: () => void, loader?: () => Promise<ZipFS>}, opts: CacheOptions = {}): Promise<[FakeFS<PortablePath>, () => void, string | null]> {
const mirrorPath = this.getLocatorMirrorPath(locator);
const shouldMock = opts.mockedPackages?.has(locator.locatorHash) && !this.check;

const baseFs = new NodeFS();

Expand Down Expand Up @@ -280,7 +279,7 @@ export class Cache {

await Promise.all(copyProcess.map(copy => copy()));

return [finalPath, checksum] as const;
return [false, finalPath, checksum] as const;
};

const loadPackageThroughMutex = async () => {
Expand All @@ -290,6 +289,7 @@ export class Cache {
// the checksum is known or not.
const tentativeCachePath = this.getLocatorPath(locator, expectedChecksum, opts);

const shouldMock = !!opts.mockedPackages?.has(locator.locatorHash) && (!this.check || !await baseFs.existsPromise(tentativeCachePath!));
const cacheExists = tentativeCachePath !== null
? shouldMock || await baseFs.existsPromise(tentativeCachePath)
: false;
Expand All @@ -306,12 +306,13 @@ export class Cache {
} else {
let checksum: string | null = null;
const cachePath = tentativeCachePath!;
if (this.check)
checksum = await validateFileAgainstRemote(cachePath);
else if (!shouldMock)
checksum = await validateFile(cachePath);

return [cachePath, checksum] as const;
if (!shouldMock)
checksum = this.check
? await validateFileAgainstRemote(cachePath)
: await validateFile(cachePath);

return [shouldMock, cachePath, checksum] as const;
}
};

Expand All @@ -328,7 +329,7 @@ export class Cache {
for (let mutex; (mutex = this.mutexes.get(locator.locatorHash));)
await mutex;

const [cachePath, checksum] = await loadPackageThroughMutex();
const [shouldMock, cachePath, checksum] = await loadPackageThroughMutex();

this.markedFiles.add(cachePath);

Expand Down
32 changes: 16 additions & 16 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -22745,17 +22745,7 @@ fsevents@^1.2.7:
languageName: node
linkType: hard

resolve@^2.0.0-next.3:
version: 2.0.0-next.3
resolution: "resolve@npm:2.0.0-next.3"
dependencies:
is-core-module: ^2.2.0
path-parse: ^1.0.6
checksum: f34b3b93ada77d64a6d590c06a83e198f3a827624c4ec972260905fa6c4d612164fbf0200d16d2beefea4ad1755b001f4a9a1293d8fc2322a8f7d6bf692c4ff5
languageName: node
linkType: hard

"resolve@npm:1.9.0":
[email protected]:
version: 1.9.0
resolution: "resolve@npm:1.9.0"
dependencies:
Expand All @@ -22764,7 +22754,7 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard

"resolve@npm:^1.1.6, resolve@npm:^1.10.0, resolve@npm:^1.12.0, resolve@npm:^1.13.1, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.3.2, resolve@npm:^1.9.0":
"resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.3.2, resolve@^1.9.0":
version: 1.20.0
resolution: "resolve@npm:1.20.0"
dependencies:
Expand All @@ -22774,6 +22764,16 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard

resolve@^2.0.0-next.3:
version: 2.0.0-next.3
resolution: "resolve@npm:2.0.0-next.3"
dependencies:
is-core-module: ^2.2.0
path-parse: ^1.0.6
checksum: f34b3b93ada77d64a6d590c06a83e198f3a827624c4ec972260905fa6c4d612164fbf0200d16d2beefea4ad1755b001f4a9a1293d8fc2322a8f7d6bf692c4ff5
languageName: node
linkType: hard

"resolve@patch:[email protected]#~builtin<compat/resolve>":
version: 1.9.0
resolution: "resolve@patch:resolve@npm%3A1.9.0#~builtin<compat/resolve>::version=1.9.0&hash=07638b"
Expand Down Expand Up @@ -25695,7 +25695,7 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard

"typescript@npm:3.7.x":
[email protected]:
version: 3.7.5
resolution: "typescript@npm:3.7.5"
bin:
Expand All @@ -25705,7 +25705,7 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard

"typescript@npm:^3.8.3":
typescript@^3.8.3:
version: 3.9.5
resolution: "typescript@npm:3.9.5"
bin:
Expand All @@ -25715,7 +25715,7 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard

"typescript@npm:^4.4.2":
typescript@^4.4.2:
version: 4.4.2
resolution: "typescript@npm:4.4.2"
bin:
Expand Down Expand Up @@ -27727,7 +27727,7 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard

"yoga-layout-prebuilt@npm:1.10.0":
[email protected]:
version: 1.10.0
resolution: "yoga-layout-prebuilt@npm:1.10.0"
dependencies:
Expand Down

0 comments on commit 30a3b02

Please sign in to comment.