[tests] Update tests to run with vercel cli tarball (#8257)

This PR update the tests suite to wait for Vercel CLI tarball and then use that tarball to run E2E tests.

This is valuable because it will package all the packages in this monorepo to make the tests follow more closely what will happen in production once merged.

Since the current "Find Changes" step takes about 2 minutes, we run that first (it happens concurrently with the tarball preparation). Then once we complete "Find Changes" we wait for the tarball but it will likely be ready by that point since it also takes about 2 minutes. After both of those steps, the E2E tests continue as usual but with the `VERCEL_CLI_VERSION` set to the tarball.

- Related to #7967 
- Closes #8245 
- Closes #8227
This commit is contained in:
Steven
2022-07-27 17:56:03 -04:00
committed by GitHub
parent 8993a3c4af
commit b5b792e42f
22 changed files with 2392 additions and 338 deletions

View File

@@ -17,6 +17,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
outputs: outputs:
tests: ${{ steps['set-tests'].outputs['tests'] }} tests: ${{ steps['set-tests'].outputs['tests'] }}
dplUrl: ${{ steps.waitForTarball.outputs.url }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- run: git --version - run: git --version
@@ -32,6 +33,12 @@ jobs:
echo "Files to test:" echo "Files to test:"
echo "$TESTS_ARRAY" echo "$TESTS_ARRAY"
echo "::set-output name=tests::$TESTS_ARRAY" echo "::set-output name=tests::$TESTS_ARRAY"
- uses: patrickedqvist/wait-for-vercel-preview@ae34b392ef30297f2b672f9afb3c329bde9bd487
id: waitForTarball
with:
token: ${{ secrets.GITHUB_TOKEN }}
max_timeout: 360
check_interval: 5
test: test:
timeout-minutes: 120 timeout-minutes: 120
@@ -69,13 +76,14 @@ jobs:
- run: yarn install --network-timeout 1000000 - run: yarn install --network-timeout 1000000
- name: Build ${{matrix.packageName}} and all its dependencies - name: Build ${{matrix.packageName}} and all its dependencies
run: yarn turbo run build --cache-dir=".turbo" --scope=${{matrix.packageName}} --include-dependencies --no-deps run: node_modules/.bin/turbo run build --cache-dir=".turbo" --scope=${{matrix.packageName}} --include-dependencies --no-deps
env: env:
FORCE_COLOR: '1' FORCE_COLOR: '1'
- name: Test ${{matrix.packageName}} - name: Test ${{matrix.packageName}}
run: node_modules/.bin/turbo run test --cache-dir=".turbo" --scope=${{matrix.packageName}} --no-deps -- ${{ join(matrix.testPaths, ' ') }} run: node_modules/.bin/turbo run test --cache-dir=".turbo" --scope=${{matrix.packageName}} --no-deps -- ${{ join(matrix.testPaths, ' ') }}
shell: bash shell: bash
env: env:
VERCEL_CLI_VERSION: ${{ needs.setup.outputs.dplUrl }}/tarballs/vercel.tgz
VERCEL_TEAM_TOKEN: ${{ secrets.VERCEL_TEAM_TOKEN }} VERCEL_TEAM_TOKEN: ${{ secrets.VERCEL_TEAM_TOKEN }}
VERCEL_REGISTRATION_URL: ${{ secrets.VERCEL_REGISTRATION_URL }} VERCEL_REGISTRATION_URL: ${{ secrets.VERCEL_REGISTRATION_URL }}
FORCE_COLOR: '1' FORCE_COLOR: '1'

View File

@@ -1,22 +1,12 @@
import path from 'path'; import path from 'path';
import fs from 'fs-extra'; import fs from 'fs-extra';
import { import {
packAndDeploy,
testDeployment, testDeployment,
// @ts-ignore // @ts-ignore
} from '../../../test/lib/deployment/test-deployment'; } from '../../../test/lib/deployment/test-deployment';
jest.setTimeout(4 * 60 * 1000); jest.setTimeout(4 * 60 * 1000);
const builderUrl = '@canary';
let buildUtilsUrl: string;
beforeAll(async () => {
const buildUtilsPath = path.resolve(__dirname, '..');
buildUtilsUrl = await packAndDeploy(buildUtilsPath);
console.log('buildUtilsUrl', buildUtilsUrl);
});
const fixturesPath = path.resolve(__dirname, 'fixtures'); const fixturesPath = path.resolve(__dirname, 'fixtures');
// Fixtures that have separate tests and should be skipped in the loop // Fixtures that have separate tests and should be skipped in the loop
@@ -42,10 +32,7 @@ for (const fixture of fs.readdirSync(fixturesPath)) {
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
it(`Should build "${fixture}"`, async () => { it(`Should build "${fixture}"`, async () => {
await expect( await expect(
testDeployment( testDeployment(path.join(fixturesPath, fixture))
{ builderUrl, buildUtilsUrl },
path.join(fixturesPath, fixture)
)
).resolves.toBeDefined(); ).resolves.toBeDefined();
}); });
} }
@@ -68,10 +55,7 @@ for (const builder of buildersToTestWith) {
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
it(`Should build "${builder}/${fixture}"`, async () => { it(`Should build "${builder}/${fixture}"`, async () => {
await expect( await expect(
testDeployment( testDeployment(path.join(fixturesPath2, fixture))
{ builderUrl, buildUtilsUrl },
path.join(fixturesPath2, fixture)
)
).resolves.toBeDefined(); ).resolves.toBeDefined();
}); });
} }

View File

@@ -5,22 +5,12 @@ import { detectBuilders } from '../src';
const fs = promises; const fs = promises;
import { import {
packAndDeploy,
testDeployment, testDeployment,
// @ts-ignore // @ts-ignore
} from '../../../test/lib/deployment/test-deployment'; } from '../../../test/lib/deployment/test-deployment';
jest.setTimeout(4 * 60 * 1000); jest.setTimeout(4 * 60 * 1000);
const builderUrl = '@canary';
let buildUtilsUrl: string;
beforeAll(async () => {
const buildUtilsPath = path.resolve(__dirname, '..');
buildUtilsUrl = await packAndDeploy(buildUtilsPath);
console.log('buildUtilsUrl', buildUtilsUrl);
});
it('Test `detectBuilders` and `detectRoutes`', async () => { it('Test `detectBuilders` and `detectRoutes`', async () => {
const fixture = path.join(__dirname, 'fixtures', '01-zero-config-api'); const fixture = path.join(__dirname, 'fixtures', '01-zero-config-api');
const json = await fs.readFile(path.join(fixture, 'package.json'), 'utf8'); const json = await fs.readFile(path.join(fixture, 'package.json'), 'utf8');
@@ -76,10 +66,7 @@ it('Test `detectBuilders` and `detectRoutes`', async () => {
JSON.stringify(nowConfig, null, 2) JSON.stringify(nowConfig, null, 2)
); );
const deployment = await testDeployment( const deployment = await testDeployment(fixture);
{ builderUrl, buildUtilsUrl },
fixture
);
expect(deployment).toBeDefined(); expect(deployment).toBeDefined();
}); });
@@ -158,9 +145,6 @@ it('Test `detectBuilders` with `index` files', async () => {
JSON.stringify(nowConfig, null, 2) JSON.stringify(nowConfig, null, 2)
); );
const deployment = await testDeployment( const deployment = await testDeployment(fixture);
{ builderUrl, buildUtilsUrl },
fixture
);
expect(deployment).toBeDefined(); expect(deployment).toBeDefined();
}); });

View File

@@ -1,15 +1,8 @@
{ {
"version": 2, "version": 2,
"builds": [
{
"src": "api/v1/routes/**/*.go",
"use": "@vercel/go",
"config": { "zeroConfig": true }
}
],
"probes": [ "probes": [
{ {
"path": "/api/v1/routes/someroute.go", "path": "/api/v1/routes/someroute",
"mustContain": "version:go1.13.15:Dependency:RANDOMNESS_PLACEHOLDER" "mustContain": "version:go1.13.15:Dependency:RANDOMNESS_PLACEHOLDER"
} }
] ]

View File

@@ -2,24 +2,10 @@ const fs = require('fs');
const path = require('path'); const path = require('path');
const { const {
packAndDeploy,
testDeployment, testDeployment,
} = require('../../../test/lib/deployment/test-deployment.js'); } = require('../../../test/lib/deployment/test-deployment.js');
jest.setTimeout(4 * 60 * 1000); jest.setTimeout(4 * 60 * 1000);
let buildUtilsUrl;
let builderUrl;
beforeAll(async () => {
if (!buildUtilsUrl) {
const buildUtilsPath = path.resolve(__dirname, '..', '..', 'build-utils');
buildUtilsUrl = await packAndDeploy(buildUtilsPath);
console.log('buildUtilsUrl', buildUtilsUrl);
}
const builderPath = path.resolve(__dirname, '..');
builderUrl = await packAndDeploy(builderPath);
console.log('builderUrl', builderUrl);
});
const skipFixtures = ['08-include-files']; const skipFixtures = ['08-include-files'];
const fixturesPath = path.resolve(__dirname, 'fixtures'); const fixturesPath = path.resolve(__dirname, 'fixtures');
@@ -33,10 +19,7 @@ for (const fixture of fs.readdirSync(fixturesPath)) {
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
it(`should build ${fixture}`, async () => { it(`should build ${fixture}`, async () => {
await expect( await expect(
testDeployment( testDeployment(path.join(fixturesPath, fixture))
{ builderUrl, buildUtilsUrl },
path.join(fixturesPath, fixture)
)
).resolves.toBeDefined(); ).resolves.toBeDefined();
}); });
} }

View File

@@ -1,23 +1,12 @@
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const { version } = require('../package.json');
const { const {
packAndDeploy,
testDeployment, testDeployment,
} = require('../../../test/lib/deployment/test-deployment.js'); } = require('../../../test/lib/deployment/test-deployment.js');
jest.setTimeout(12 * 60 * 1000); jest.setTimeout(12 * 60 * 1000);
let builderUrl;
const buildUtilsUrl = version.includes('canary') ? '@canary' : undefined;
beforeAll(async () => {
const builderPath = path.resolve(__dirname, '..');
builderUrl = await packAndDeploy(builderPath);
console.log('builderUrl', builderUrl);
});
const fixturesPath = path.resolve(__dirname, 'fixtures'); const fixturesPath = path.resolve(__dirname, 'fixtures');
// eslint-disable-next-line no-restricted-syntax // eslint-disable-next-line no-restricted-syntax
@@ -25,10 +14,7 @@ for (const fixture of fs.readdirSync(fixturesPath)) {
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
it(`should build ${fixture}`, async () => { it(`should build ${fixture}`, async () => {
await expect( await expect(
testDeployment( testDeployment(path.join(fixturesPath, fixture))
{ builderUrl, buildUtilsUrl },
path.join(fixturesPath, fixture)
)
).resolves.toBeDefined(); ).resolves.toBeDefined();
}); });
} }

View File

@@ -1,11 +1,7 @@
import type { Context, LoggerServer, Dictionary } from './types'; import type { Context, LoggerServer, Dictionary } from './types';
import type { IncomingMessage } from 'http'; import type { IncomingMessage } from 'http';
import { import { testDeployment } from '../../../test/lib/deployment/test-deployment';
packAndDeploy,
testDeployment,
} from '../../../test/lib/deployment/test-deployment';
import { fetchTokenWithRetry } from '../../../test/lib/deployment/now-deploy';
import fs from 'fs-extra'; import fs from 'fs-extra';
import http from 'http'; import http from 'http';
@@ -72,56 +68,10 @@ export const createLoggerServer = async (): Promise<LoggerServer> => {
return { url, close, content }; return { url, close, content };
}; };
let builderUrlPromise;
let builderUrlLastUpdated = 0;
const buildUtilsUrl = '@canary';
process.env.NEXT_TELEMETRY_DISABLED = '1'; process.env.NEXT_TELEMETRY_DISABLED = '1';
export async function deployAndTest(fixtureDir) { export async function deployAndTest(fixtureDir) {
let builderInfo; const { deploymentId, deploymentUrl } = await testDeployment(fixtureDir);
const builderInfoPath = path.join(__dirname, 'builder-info.json');
try {
builderInfo = await fs.readJSON(builderInfoPath);
} catch (_) {
/**/
}
let tempToken;
if (!builderUrlPromise && builderInfo) {
builderUrlPromise = Promise.resolve(builderInfo.builderUrl);
builderUrlLastUpdated = builderInfo.lastUpdated;
tempToken = builderInfo.tempToken;
}
const builderUrlIsStale = builderUrlLastUpdated < Date.now() - ms('25min');
if (!process.env.VERCEL_TOKEN && (builderUrlIsStale || !tempToken)) {
tempToken = await fetchTokenWithRetry();
}
process.env.TEMP_TOKEN = tempToken;
if (builderUrlIsStale) {
const builderPath = path.resolve(__dirname, '..');
builderUrlPromise = packAndDeploy(builderPath, false);
builderUrlLastUpdated = Date.now();
}
const builderUrl = await builderUrlPromise;
await fs.writeFile(
builderInfoPath,
JSON.stringify({
tempToken,
builderUrl,
lastUpdated: builderUrlLastUpdated,
})
);
const { deploymentId, deploymentUrl } = await testDeployment(
{ builderUrl, buildUtilsUrl },
fixtureDir
);
return { return {
deploymentId, deploymentId,

View File

@@ -28,7 +28,7 @@ async function getScreenshot(url) {
module.exports = async (req, res) => { module.exports = async (req, res) => {
const buffer = await getScreenshot('https://vercel.com/about'); const buffer = await getScreenshot('https://vercel.com/about');
if (buffer.length > 0) { if (buffer.length > 0) {
res.end('screenshot:RANDOMNESS_PLACEHOLDER'); res.end('/api/screenshot:RANDOMNESS_PLACEHOLDER');
} else { } else {
res.end('buffer is empty'); res.end('buffer is empty');
} }

View File

@@ -1,35 +0,0 @@
import chrome from 'chrome-aws-lambda';
import puppeteer from 'puppeteer-core';
import lighthouse from 'lighthouse';
import { URL } from 'url';
async function getOptions() {
const options = {
args: chrome.args,
executablePath: await chrome.executablePath,
headless: chrome.headless,
};
return options;
}
async function getResult(url) {
const options = await getOptions();
const browser = await puppeteer.launch(options);
const { port } = new URL(browser.wsEndpoint());
const result = await lighthouse(url, {
port,
output: 'html',
logLevel: 'error',
});
await browser.close();
return result;
}
module.exports = async (req, res) => {
const result = await getResult('https://vercel.com/docs');
if (req && result && result.lhr && result.lhr.categories) {
res.end('lighthouse:RANDOMNESS_PLACEHOLDER');
} else {
res.end('result is empty');
}
};

View File

@@ -1,4 +1,5 @@
{ {
"private": true,
"engines": { "engines": {
"node": "14.x" "node": "14.x"
}, },

View File

@@ -9,7 +9,7 @@ async function tryTest({
retries = 4, retries = 4,
}) { }) {
try { try {
const res = await fetch(`https://${deploymentUrl}/${testName}`); const res = await fetch(`https://${deploymentUrl}${testName}`);
assert.equal(res.status, 200); assert.equal(res.status, 200);
const text = await res.text(); const text = await res.text();
assert.equal(text.trim(), `${testName}:${randomness}`); assert.equal(text.trim(), `${testName}:${randomness}`);
@@ -32,6 +32,10 @@ async function tryTest({
} }
module.exports = async ({ deploymentUrl, fetch, randomness }) => { module.exports = async ({ deploymentUrl, fetch, randomness }) => {
await tryTest({ testName: 'lighthouse', deploymentUrl, fetch, randomness }); await tryTest({
await tryTest({ testName: 'screenshot', deploymentUrl, fetch, randomness }); testName: '/api/screenshot',
deploymentUrl,
fetch,
randomness,
});
}; };

View File

@@ -1,17 +1,8 @@
{ {
"version": 2, "functions": {
"builds": [ "api/**/*.js": {
{ "memory": 1024,
"src": "**/*.js", "maxDuration": 10
"use": "@vercel/node",
"config": {
"functions": {
"**/*.js": {
"memory": 3008,
"maxDuration": 30
}
}
}
} }
] }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,30 +1,14 @@
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const ms = require('ms');
const { version } = require('../package.json');
const { intoChunks, NUMBER_OF_CHUNKS } = require('../../../utils/chunk-tests'); const { intoChunks, NUMBER_OF_CHUNKS } = require('../../../utils/chunk-tests');
const { const {
packAndDeploy,
testDeployment, testDeployment,
} = require('../../../test/lib/deployment/test-deployment.js'); } = require('../../../test/lib/deployment/test-deployment.js');
jest.setTimeout(12 * 60 * 1000); jest.setTimeout(12 * 60 * 1000);
module.exports = function setupTests(groupIndex) { module.exports = function setupTests(groupIndex) {
let builderUrl;
let builderUrlLastUpdated = 0;
const buildUtilsUrl = version.includes('canary') ? '@canary' : undefined;
beforeEach(async () => {
if (builderUrlLastUpdated < Date.now() - ms('30min')) {
const builderPath = path.resolve(__dirname, '..');
builderUrl = await packAndDeploy(builderPath);
builderUrlLastUpdated = Date.now();
console.log('builderUrl', builderUrl);
}
});
const fixturesPath = path.resolve(__dirname, 'fixtures'); const fixturesPath = path.resolve(__dirname, 'fixtures');
const testsThatFailToBuild = new Map([ const testsThatFailToBuild = new Map([
[ [
@@ -48,10 +32,7 @@ module.exports = function setupTests(groupIndex) {
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
it(`should fail to build ${fixture}`, async () => { it(`should fail to build ${fixture}`, async () => {
try { try {
await testDeployment( await testDeployment(path.join(fixturesPath, fixture));
{ builderUrl, buildUtilsUrl },
path.join(fixturesPath, fixture)
);
} catch (err) { } catch (err) {
expect(err).toBeTruthy(); expect(err).toBeTruthy();
expect(err.deployment).toBeTruthy(); expect(err.deployment).toBeTruthy();
@@ -62,10 +43,7 @@ module.exports = function setupTests(groupIndex) {
} }
it(`should build ${fixture}`, async () => { it(`should build ${fixture}`, async () => {
await expect( await expect(
testDeployment( testDeployment(path.join(fixturesPath, fixture))
{ builderUrl, buildUtilsUrl },
path.join(fixturesPath, fixture)
)
).resolves.toBeDefined(); ).resolves.toBeDefined();
}); });
} }

View File

@@ -6,19 +6,10 @@ const execa = require('execa');
const { spawn } = require('child_process'); const { spawn } = require('child_process');
const { const {
packAndDeploy,
testDeployment, testDeployment,
} = require('../../../test/lib/deployment/test-deployment.js'); } = require('../../../test/lib/deployment/test-deployment.js');
jest.setTimeout(4 * 60 * 1000); jest.setTimeout(4 * 60 * 1000);
const buildUtilsUrl = '@canary';
let builderUrl: string;
beforeAll(async () => {
const builderPath = path.resolve(__dirname, '..');
builderUrl = await packAndDeploy(builderPath);
console.log('builderUrl', builderUrl);
});
const fixturesPath = path.resolve(__dirname, 'fixtures'); const fixturesPath = path.resolve(__dirname, 'fixtures');
@@ -85,10 +76,7 @@ for (const fixture of fs.readdirSync(fixturesPath)) {
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
it(`should build ${fixture}`, async () => { it(`should build ${fixture}`, async () => {
await expect( await expect(
testDeployment( testDeployment(path.join(fixturesPath, fixture))
{ builderUrl, buildUtilsUrl },
path.join(fixturesPath, fixture)
)
).resolves.toBeDefined(); ).resolves.toBeDefined();
}); });
} }

View File

@@ -2,26 +2,11 @@ const fs = require('fs');
const path = require('path'); const path = require('path');
const { const {
packAndDeploy,
testDeployment, testDeployment,
} = require('../../../test/lib/deployment/test-deployment.js'); } = require('../../../test/lib/deployment/test-deployment.js');
jest.setTimeout(12 * 60 * 1000); jest.setTimeout(12 * 60 * 1000);
let buildUtilsUrl;
let builderUrl;
beforeAll(async () => {
if (!buildUtilsUrl) {
const buildUtilsPath = path.resolve(__dirname, '..', '..', 'build-utils');
buildUtilsUrl = await packAndDeploy(buildUtilsPath);
console.log('buildUtilsUrl', buildUtilsUrl);
}
const builderPath = path.resolve(__dirname, '..');
builderUrl = await packAndDeploy(builderPath);
console.log('builderUrl', builderUrl);
});
const fixturesPath = path.resolve(__dirname, 'fixtures'); const fixturesPath = path.resolve(__dirname, 'fixtures');
// eslint-disable-next-line no-restricted-syntax // eslint-disable-next-line no-restricted-syntax
@@ -29,10 +14,7 @@ for (const fixture of fs.readdirSync(fixturesPath)) {
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
it(`should build ${fixture}`, async () => { it(`should build ${fixture}`, async () => {
await expect( await expect(
testDeployment( testDeployment(path.join(fixturesPath, fixture))
{ builderUrl, buildUtilsUrl },
path.join(fixturesPath, fixture)
)
).resolves.toBeDefined(); ).resolves.toBeDefined();
}); });
} }

View File

@@ -1,23 +1,12 @@
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const { version } = require('../package.json');
const { const {
packAndDeploy,
testDeployment, testDeployment,
} = require('../../../test/lib/deployment/test-deployment.js'); } = require('../../../test/lib/deployment/test-deployment.js');
jest.setTimeout(12 * 60 * 1000); jest.setTimeout(12 * 60 * 1000);
let builderUrl;
const buildUtilsUrl = version.includes('canary') ? '@canary' : undefined;
beforeAll(async () => {
const builderPath = path.resolve(__dirname, '..');
builderUrl = await packAndDeploy(builderPath);
console.log('builderUrl', builderUrl);
});
const fixturesPath = path.resolve(__dirname, 'fixtures'); const fixturesPath = path.resolve(__dirname, 'fixtures');
// eslint-disable-next-line no-restricted-syntax // eslint-disable-next-line no-restricted-syntax
@@ -25,10 +14,7 @@ for (const fixture of fs.readdirSync(fixturesPath)) {
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
it(`should build ${fixture}`, async () => { it(`should build ${fixture}`, async () => {
await expect( await expect(
testDeployment( testDeployment(path.join(fixturesPath, fixture))
{ builderUrl, buildUtilsUrl },
path.join(fixturesPath, fixture)
)
).resolves.toBeDefined(); ).resolves.toBeDefined();
}); });
} }

View File

@@ -2,24 +2,10 @@ const fs = require('fs');
const path = require('path'); const path = require('path');
const { const {
packAndDeploy,
testDeployment, testDeployment,
} = require('../../../test/lib/deployment/test-deployment.js'); } = require('../../../test/lib/deployment/test-deployment.js');
jest.setTimeout(5 * 60 * 1000); jest.setTimeout(5 * 60 * 1000);
let buildUtilsUrl;
let builderUrl;
beforeAll(async () => {
if (!buildUtilsUrl) {
const buildUtilsPath = path.resolve(__dirname, '..', '..', 'build-utils');
buildUtilsUrl = await packAndDeploy(buildUtilsPath);
console.log('buildUtilsUrl', buildUtilsUrl);
}
const builderPath = path.resolve(__dirname, '..');
builderUrl = await packAndDeploy(builderPath);
console.log('builderUrl', builderUrl);
});
const fixturesPath = path.resolve(__dirname, 'fixtures'); const fixturesPath = path.resolve(__dirname, 'fixtures');
@@ -37,10 +23,7 @@ for (const fixture of fs.readdirSync(fixturesPath)) {
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
it(`should fail to build ${fixture}`, async () => { it(`should fail to build ${fixture}`, async () => {
try { try {
await testDeployment( await testDeployment(path.join(fixturesPath, fixture));
{ builderUrl, buildUtilsUrl },
path.join(fixturesPath, fixture)
);
} catch (err) { } catch (err) {
expect(err).toBeTruthy(); expect(err).toBeTruthy();
expect(err.deployment).toBeTruthy(); expect(err.deployment).toBeTruthy();
@@ -52,10 +35,7 @@ for (const fixture of fs.readdirSync(fixturesPath)) {
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
it(`should build ${fixture}`, async () => { it(`should build ${fixture}`, async () => {
await expect( await expect(
testDeployment( testDeployment(path.join(fixturesPath, fixture))
{ builderUrl, buildUtilsUrl },
path.join(fixturesPath, fixture)
)
).resolves.toBeDefined(); ).resolves.toBeDefined();
}); });
} }

View File

@@ -1,30 +1,14 @@
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const ms = require('ms');
const { version } = require('../package.json');
const { intoChunks, NUMBER_OF_CHUNKS } = require('../../../utils/chunk-tests'); const { intoChunks, NUMBER_OF_CHUNKS } = require('../../../utils/chunk-tests');
const { const {
packAndDeploy,
testDeployment, testDeployment,
} = require('../../../test/lib/deployment/test-deployment.js'); } = require('../../../test/lib/deployment/test-deployment.js');
jest.setTimeout(12 * 60 * 1000); jest.setTimeout(12 * 60 * 1000);
module.exports = function setupTests(groupIndex) { module.exports = function setupTests(groupIndex) {
let builderUrl;
let builderUrlLastUpdated = 0;
const buildUtilsUrl = version.includes('canary') ? '@canary' : undefined;
beforeEach(async () => {
if (builderUrlLastUpdated < Date.now() - ms('30min')) {
const builderPath = path.resolve(__dirname, '..');
builderUrl = await packAndDeploy(builderPath);
builderUrlLastUpdated = Date.now();
console.log('builderUrl', builderUrl);
}
});
const fixturesPath = path.resolve(__dirname, 'fixtures'); const fixturesPath = path.resolve(__dirname, 'fixtures');
const testsThatFailToBuild = new Map([ const testsThatFailToBuild = new Map([
[ [
@@ -61,10 +45,7 @@ module.exports = function setupTests(groupIndex) {
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
it(`should fail to build ${fixture}`, async () => { it(`should fail to build ${fixture}`, async () => {
try { try {
await testDeployment( await testDeployment(path.join(fixturesPath, fixture));
{ builderUrl, buildUtilsUrl },
path.join(fixturesPath, fixture)
);
} catch (err) { } catch (err) {
expect(err).toBeTruthy(); expect(err).toBeTruthy();
expect(err.deployment).toBeTruthy(); expect(err.deployment).toBeTruthy();
@@ -75,10 +56,7 @@ module.exports = function setupTests(groupIndex) {
} }
it(`should build ${fixture}`, async () => { it(`should build ${fixture}`, async () => {
await expect( await expect(
testDeployment( testDeployment(path.join(fixturesPath, fixture))
{ builderUrl, buildUtilsUrl },
path.join(fixturesPath, fixture)
)
).resolves.toBeDefined(); ).resolves.toBeDefined();
}); });
} }

View File

@@ -33,6 +33,8 @@ async function nowDeploy(bodies, randomness, uploadNowJson) {
process.env; process.env;
const nowJson = JSON.parse(bodies['vercel.json'] || bodies['now.json']); const nowJson = JSON.parse(bodies['vercel.json'] || bodies['now.json']);
delete nowJson.probes;
const nowDeployPayload = { const nowDeployPayload = {
version: 2, version: 2,
public: true, public: true,
@@ -50,16 +52,10 @@ async function nowDeploy(bodies, randomness, uploadNowJson) {
}, },
name: 'test2020', name: 'test2020',
files, files,
builds: nowJson.builds,
meta: {}, meta: {},
...nowJson,
}; };
for (const field of ['routes', 'rewrites', 'headers', 'redirects']) {
if (nowJson[field]) {
nowDeployPayload[field] = nowJson[field];
}
}
logWithinTest(`posting ${files.length} files`); logWithinTest(`posting ${files.length} files`);
for (const { file: filename } of files) { for (const { file: filename } of files) {
@@ -146,7 +142,7 @@ async function filePost(body, digest) {
} }
async function deploymentPost(payload) { async function deploymentPost(payload) {
const url = '/v6/now/deployments?forceNew=1'; const url = '/v13/deployments?skipAutoDetectionConfirmation=1&forceNew=1';
const resp = await fetchWithAuth(url, { const resp = await fetchWithAuth(url, {
method: 'POST', method: 'POST',
body: JSON.stringify(payload), body: JSON.stringify(payload),
@@ -164,7 +160,7 @@ async function deploymentPost(payload) {
} }
async function deploymentGet(deploymentId) { async function deploymentGet(deploymentId) {
const url = `/v12/now/deployments/${deploymentId}`; const url = `/v13/deployments/${deploymentId}`;
logWithinTest('fetching deployment', url); logWithinTest('fetching deployment', url);
const resp = await fetchWithAuth(url); const resp = await fetchWithAuth(url);
const json = await resp.json(); const json = await resp.json();

View File

@@ -264,11 +264,7 @@ async function runProbe(probe, deploymentId, deploymentUrl, ctx) {
assert(hadTest, 'probe must have a test condition'); assert(hadTest, 'probe must have a test condition');
} }
async function testDeployment( async function testDeployment(fixturePath, buildDelegate) {
{ builderUrl, buildUtilsUrl },
fixturePath,
buildDelegate
) {
logWithinTest('testDeployment', fixturePath); logWithinTest('testDeployment', fixturePath);
const globResult = await glob(`${fixturePath}/**`, { const globResult = await glob(`${fixturePath}/**`, {
nodir: true, nodir: true,
@@ -321,24 +317,6 @@ async function testDeployment(
}); });
for (const build of nowJson.builds || []) { for (const build of nowJson.builds || []) {
if (builderUrl) {
if (builderUrl === '@canary') {
build.use = `${build.use}@canary`;
} else {
build.use = `https://${builderUrl}`;
}
}
if (buildUtilsUrl) {
build.config = build.config || {};
const { config } = build;
if (buildUtilsUrl === '@canary') {
const buildUtils = config.useBuildUtils || '@vercel/build-utils';
config.useBuildUtils = `${buildUtils}@canary`;
} else {
config.useBuildUtils = `https://${buildUtilsUrl}`;
}
}
if (buildDelegate) { if (buildDelegate) {
buildDelegate(build); buildDelegate(build);
} }

15
utils/chunk-tests.js vendored
View File

@@ -81,16 +81,19 @@ async function getChunkedTests() {
return chunkedTests; return chunkedTests;
} }
/**
* Run turbo cli
* @param {string[]} args
*/
async function turbo(args) { async function turbo(args) {
const chunks = []; const chunks = [];
try { try {
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
const spawned = child_process.spawn(`yarn`, ['turbo', '--', ...args], { const root = path.resolve(__dirname, '..');
cwd: path.resolve(__dirname, '..'), const turbo = path.join(root, 'node_modules', '.bin', 'turbo');
env: { const spawned = child_process.spawn(turbo, args, {
...process.env, cwd: root,
YARN_SILENT: '1', env: process.env,
},
}); });
spawned.stdout.on('data', data => { spawned.stdout.on('data', data => {
chunks.push(data); chunks.push(data);