Skip to content

Commit

Permalink
promote: convert check_assets tests to node:test
Browse files Browse the repository at this point in the history
Refs: #3958
  • Loading branch information
richardlau committed Nov 29, 2024
1 parent 5886bcd commit 3173ed7
Show file tree
Hide file tree
Showing 2 changed files with 316 additions and 387 deletions.
387 changes: 0 additions & 387 deletions ansible/www-standalone/tools/promote/check_assets.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

const fs = require('fs').promises
const path = require('path')
const childProcess = require('child_process')
const assert = require('assert')

const versionRe = /^v\d+\.\d+\.\d+/
const additionalDistAssets = [
Expand Down Expand Up @@ -217,388 +215,3 @@ async function execute () {
console.log(' \u001b[33mPromote if you are certain this is the the correct course of action\u001b[39m')
}
}

/* TESTS ***********************************************************************/

function test () {
// makes a staging or dist directory given a version string
async function makeFixture (version, isStaging, dir, assets) {
if (!assets) {
assets = await loadExpectedAssets(version)
}
for (let asset of assets) {
let absoluteAsset = path.join(dir, asset)
if (asset.endsWith('/')) {
await fs.mkdir(absoluteAsset, { recursive: true })
} else {
await fs.writeFile(absoluteAsset, asset, 'utf8')
}
let dashPos = isStaging && asset.indexOf('/')
if (isStaging && (dashPos === -1 || dashPos === asset.length - 1)) {
// in staging, all files and directories that are ready have a
// duplicate empty file with .done in the name
await fs.writeFile(absoluteAsset.replace(/\/?$/, '.done'), asset, 'utf8')
}
}
return assets
}

async function rimraf (dir) {
const stat = await fs.stat(dir)
if (!stat.isDirectory()) {
await fs.unlink(dir)
return
}
const ls = await fs.readdir(dir)
for (let f of ls) {
f = path.join(dir, f)
const stat = await fs.stat(f)
if (stat.isDirectory()) {
await rimraf(f)
} else {
await fs.unlink(f)
}
}
await fs.rmdir(dir)
}

// execute check_assets.js with the given staging and dist dirs, collect output
async function executeMe (stagingDir, distDir) {
return new Promise((resolve, reject) => {
const args = [ '--no-warnings', __filename, stagingDir, distDir ]
childProcess.execFile(process.execPath, args, (err, stdout, stderr) => {
if (err) {
return reject(err)
}
if (stderr) {
console.log('STDERR:', stderr)
}
resolve(stdout)
})
})
}

async function runTest (number, version, expectedStdout, setup) {
const testDir = await fs.mkdtemp(`${__filename}_`)
const fixtureStagingDir = path.join(testDir, `staging/${version}`)
const fixtureDistDir = path.join(testDir, `dist/${version}`)
await setup(fixtureStagingDir, fixtureDistDir)

const stdout = await executeMe(fixtureStagingDir, fixtureDistDir)
console.log(`\nTest ${number} Assertions ???`)
console.log(`STDOUT------------------------------------------\n\n${stdout}\n------------------------------------------------`)
assert.equal(stdout, expectedStdout)
console.log(`Test ${number} Assertions ✓✓✓`)

await rimraf(testDir)
}
// TEST 1: Everything is in staging, nothing in dist, good to go
async function test1 () {
const version = 'v8.13.0'
const expectedStdout =
'... Checking assets\n' +
'... Expecting a total of 44 assets for v8.x\n' +
'... 44 assets waiting in staging\n' +
'... 0 assets already promoted\n' +
' \u001b[32m\u001b[1m✓\u001b[22m\u001b[39m Complete set of expected assets in place for v8.x\n'

async function setup (fixtureStagingDir, fixtureDistDir) {
await makeFixture(version, true, fixtureStagingDir)
}

return runTest(1, version, expectedStdout, setup)
}

// TEST 2: Not quite everything is in staging, missing two assets, nothing in dist
async function test2 () {
const version = 'v10.1.0'
const expectedStdout =
'... Checking assets\n' +
'... Expecting a total of 41 assets for v10.x\n' +
'... 38 assets waiting in staging\n' +
'... 0 assets already promoted\n' +
' \u001b[33m\u001b[1m⚠\u001b[22m\u001b[39m The following assets are expected for v10.x but are currently missing from staging:\n' +
' • node-v10.1.0-linux-armv6l.tar.gz\n' +
' • node-v10.1.0-linux-armv6l.tar.xz\n' +
' • node-v10.1.0.pkg\n' +
' \u001b[33mPromote if you are certain this is the the correct course of action\u001b[39m\n'

async function setup (fixtureStagingDir, fixtureDistDir) {
await makeFixture(version, true, fixtureStagingDir)
await Promise.all([
fs.unlink(path.join(fixtureStagingDir, 'node-v10.1.0-linux-armv6l.tar.gz')),
fs.unlink(path.join(fixtureStagingDir, 'node-v10.1.0-linux-armv6l.tar.gz.done')),
fs.unlink(path.join(fixtureStagingDir, 'node-v10.1.0-linux-armv6l.tar.xz')),
fs.unlink(path.join(fixtureStagingDir, 'node-v10.1.0-linux-armv6l.tar.xz.done')),
fs.unlink(path.join(fixtureStagingDir, 'node-v10.1.0.pkg')),
fs.unlink(path.join(fixtureStagingDir, 'node-v10.1.0.pkg.done'))
])
}

return runTest(2, version, expectedStdout, setup)
}

// TEST 3: Everything in staging, 3 files in dist
async function test3 () {
const version = 'v6.0.1'
const expectedStdout =
'... Checking assets\n' +
'... Expecting a total of 46 assets for v6.x\n' +
'... 46 assets waiting in staging\n' +
' \u001b[33m\u001b[1m⚠\u001b[22m\u001b[39m 3 assets already promoted will be overwritten, is this OK?\n' +
' • node-v6.0.1-headers.tar.gz\n' +
' • node-v6.0.1-x86.msi\n' +
' • node-v6.0.1.tar.gz\n' +
' \u001b[32m\u001b[1m✓\u001b[22m\u001b[39m Complete set of expected assets in place for v6.x\n' +
' \u001b[33mPromote if you are certain this is the the correct course of action\u001b[39m\n'

async function setup (fixtureStagingDir, fixtureDistDir) {
await makeFixture(version, true, fixtureStagingDir)
const distAssets = await makeFixture(version, false, fixtureDistDir)
await Promise.all(
distAssets.filter((a) => {
return a !== 'node-v6.0.1-headers.tar.gz' &&
a !== 'node-v6.0.1.tar.gz' &&
a !== 'node-v6.0.1-x86.msi' &&
// deleting all directories, so we don't need to delete the children
!/^win-x64\/.+/.test(a) &&
!/^win-x86\/.+/.test(a) &&
!/^docs\/.+/.test(a)
}).map((e) => rimraf(path.join(fixtureDistDir, e)))
)
}

return runTest(3, version, expectedStdout, setup)
}

// TEST 4: Everything in staging and everything in dist
async function test4 () {
const version = 'v11.11.11'
const expectedStdout =
'... Checking assets\n' +
'... Expecting a total of 41 assets for v11.x\n' +
'... 41 assets waiting in staging\n' +
' \u001b[33m\u001b[1m⚠\u001b[22m\u001b[39m 41 assets already promoted will be overwritten, is this OK?\n' +
' \u001b[32m\u001b[1m✓\u001b[22m\u001b[39m Complete set of expected assets in place for v11.x\n' +
' \u001b[33mPromote if you are certain this is the the correct course of action\u001b[39m\n'

async function setup (fixtureStagingDir, fixtureDistDir) {
await makeFixture(version, true, fixtureStagingDir)
await makeFixture(version, false, fixtureDistDir)
}

return runTest(4, version, expectedStdout, setup)
}

// TEST 5: No expected files list is available for this version, it has to guess
async function test5 () {
const version = 'v9.9.9'
const expectedStdout =
'... Checking assets\n' +
' \u001b[33m\u001b[1m⚠\u001b[22m\u001b[39m No expected asset list is available for v9.x, using the list for v8.x instead\n' +
' Should a new list be created for v9.x?\n' +
' https://github.com/nodejs/build/tree/main/ansible/www-standalone/tools/promote/expected_assets/v9.x\n' +
'... Expecting a total of 44 assets for v9.x\n' +
'... 41 assets waiting in staging\n' +
'... 0 assets already promoted\n' +
' \u001b[33m\u001b[1m⚠\u001b[22m\u001b[39m The following assets are expected for v9.x but are currently missing from staging:\n' +
' • node-v9.9.9-linux-x86.tar.gz\n' +
' • node-v9.9.9-linux-x86.tar.xz\n' +
' • node-v9.9.9-sunos-x86.tar.gz\n' +
' • node-v9.9.9-sunos-x86.tar.xz\n' +
' \u001b[31m\u001b[1m✖\u001b[22m\u001b[39m The following assets were found in staging but are not expected for v9.x:\n' +
' • docs/apilinks.json\n' +
' Does the expected assets list for v9.x need to be updated?\n' +
' https://github.com/nodejs/build/tree/main/ansible/www-standalone/tools/promote/expected_assets/v9.x\n' +
' \u001b[33mPromote if you are certain this is the the correct course of action\u001b[39m\n'

async function setup (fixtureStagingDir, fixtureDistDir) {
// use the 10.x list, which is missing the x86 files, it'll check the 9.x
const expectedAssets = await loadExpectedAssets(version, 'v10.x')
await makeFixture(version, true, fixtureStagingDir, expectedAssets)
}

return runTest(5, version, expectedStdout, setup)
}

// TEST 6: Everything is in dist except for the armv6l files, but they are in staging
async function test6 () {
const version = 'v10.0.0'
const expectedStdout =
'... Checking assets\n' +
'... Expecting a total of 41 assets for v10.x\n' +
'... 2 assets waiting in staging\n' +
'... 39 assets already promoted\n' +
' \u001b[32m\u001b[1m✓\u001b[22m\u001b[39m Complete set of expected assets in place for v10.x\n'

async function setup (fixtureStagingDir, fixtureDistDir) {
await fs.mkdir(fixtureStagingDir, { recursive: true })
await makeFixture(version, true, fixtureStagingDir, [
'node-v10.0.0-linux-armv6l.tar.gz',
'node-v10.0.0-linux-armv6l.tar.xz'
])
await makeFixture(version, false, fixtureDistDir)
await Promise.all([
fs.unlink(path.join(fixtureDistDir, 'node-v10.0.0-linux-armv6l.tar.gz')),
fs.unlink(path.join(fixtureDistDir, 'node-v10.0.0-linux-armv6l.tar.xz'))
])
}

return runTest(6, version, expectedStdout, setup)
}

// TEST 7: Some unexpected files in staging
async function test7 () {
const version = 'v10.0.0'
const expectedStdout =
'... Checking assets\n' +
'... Expecting a total of 41 assets for v10.x\n' +
'... 2 assets waiting in staging\n' +
'... 41 assets already promoted\n' +
' \u001b[32m\u001b[1m✓\u001b[22m\u001b[39m Complete set of expected assets in place for v10.x\n' +
' \u001b[31m\u001b[1m✖\u001b[22m\u001b[39m The following assets were found in staging but are not expected for v10.x:\n' +
' • ooolaalaa.tar.gz\n' +
' • whatdis.tar.xz\n' +
' Does the expected assets list for v10.x need to be updated?\n' +
' https://github.com/nodejs/build/tree/main/ansible/www-standalone/tools/promote/expected_assets/v10.x\n' +
' \u001b[33mPromote if you are certain this is the the correct course of action\u001b[39m\n'

async function setup (fixtureStagingDir, fixtureDistDir) {
await fs.mkdir(fixtureStagingDir, { recursive: true })
await makeFixture(version, true, fixtureStagingDir, [
'ooolaalaa.tar.gz',
'whatdis.tar.xz'
])
await makeFixture(version, false, fixtureDistDir)
}

return runTest(7, version, expectedStdout, setup)
}

// TEST 8: Unexpected files in subdirectories, only check 2 levels deep
async function test8 () {
const version = 'v11.11.1'
const expectedStdout =
'... Checking assets\n' +
'... Expecting a total of 41 assets for v11.x\n' +
'... 43 assets waiting in staging\n' +
'... 0 assets already promoted\n' +
' \u001b[32m\u001b[1m✓\u001b[22m\u001b[39m Complete set of expected assets in place for v11.x\n' +
' \u001b[31m\u001b[1m✖\u001b[22m\u001b[39m The following assets were found in staging but are not expected for v11.x:\n' +
' • docs/bar\n' +
' • docs/foo\n' +
' Does the expected assets list for v11.x need to be updated?\n' +
' https://github.com/nodejs/build/tree/main/ansible/www-standalone/tools/promote/expected_assets/v11.x\n' +
' \u001b[33mPromote if you are certain this is the the correct course of action\u001b[39m\n'

async function setup (fixtureStagingDir, fixtureDistDir) {
await fs.mkdir(fixtureStagingDir, { recursive: true })
await makeFixture(version, true, fixtureStagingDir)
await Promise.all([
fs.writeFile(path.join(fixtureStagingDir, 'docs/foo'), 'foo'),
fs.writeFile(path.join(fixtureStagingDir, 'docs/bar'), 'foo'),
fs.writeFile(path.join(fixtureStagingDir, 'docs/api/baz'), 'bar')
])
}

return runTest(8, version, expectedStdout, setup)
}

// TEST 9: Some unexpected files in dist
async function test9 () {
const version = 'v6.7.8'
const expectedStdout =
'... Checking assets\n' +
'... Expecting a total of 46 assets for v6.x\n' +
'... 46 assets waiting in staging\n' +
'... 2 assets already promoted\n' +
' \u001b[32m\u001b[1m✓\u001b[22m\u001b[39m Complete set of expected assets in place for v6.x\n' +
' \u001b[31m\u001b[1m✖\u001b[22m\u001b[39m The following assets were already promoted but are not expected for v6.x:\n' +
' • ooolaalaa.tar.gz\n' +
' • whatdis.tar.xz\n' +
' Does the expected assets list for v6.x need to be updated?\n' +
' https://github.com/nodejs/build/tree/main/ansible/www-standalone/tools/promote/expected_assets/v6.x\n' +
' \u001b[33mPromote if you are certain this is the the correct course of action\u001b[39m\n'

async function setup (fixtureStagingDir, fixtureDistDir) {
await fs.mkdir(fixtureDistDir, { recursive: true })
await makeFixture(version, false, fixtureDistDir, [
'ooolaalaa.tar.gz',
'whatdis.tar.xz'
])
await makeFixture(version, true, fixtureStagingDir)
}

return runTest(9, version, expectedStdout, setup)
}

// TEST 10: SHASUMS in dist already, shouldn't bother us
async function test10 () {
const version = 'v8.0.0'
const expectedStdout =
'... Checking assets\n' +
'... Expecting a total of 44 assets for v8.x\n' +
'... 44 assets waiting in staging\n' +
' \u001b[33m\u001b[1m⚠\u001b[22m\u001b[39m 4 assets already promoted will be overwritten, is this OK?\n' +
' • docs/\n' +
' • docs/api/\n' +
' • node-v8.0.0-linux-armv6l.tar.gz\n' +
' • node-v8.0.0-linux-armv6l.tar.xz\n' +
' \u001b[32m\u001b[1m✓\u001b[22m\u001b[39m Complete set of expected assets in place for v8.x\n' +
' \u001b[33mPromote if you are certain this is the the correct course of action\u001b[39m\n'

async function setup (fixtureStagingDir, fixtureDistDir) {
await fs.mkdir(fixtureDistDir, { recursive: true })
await Promise.all([
makeFixture(version, true, fixtureStagingDir),
makeFixture(version, false, fixtureDistDir, [
'SHASUMS256.txt',
'SHASUMS256.txt.asc',
'SHASUMS256.txt.sig',
'docs/',
'docs/api/',
'docs/api/bar',
'node-v8.0.0-linux-armv6l.tar.gz',
'node-v8.0.0-linux-armv6l.tar.xz'
])
])
}

return runTest(10, version, expectedStdout, setup)
}

// run in parallel and just print failures to stderr
let failures = 0
let passes = 0
const tests = [
test1,
test2,
test3,
test4,
test5,
test6,
test7,
test8,
test9,
test10
]

tests.forEach((test) => {
test()
.then(() => passes++)
.catch((err) => {
failures++
console.error(err)
})
})

process.on('exit', () => {
if (failures) {
console.error(`\n\u001b[31mThere were ${failures} test failures\u001b[39m`)
} else if (passes === tests.length) {
console.error('\n\u001b[32mAll tests have passed!\u001b[39m')
} else {
console.error(`\n\u001b[31mNot all tests seem to have run, something's wrong\u001b[39m`)
}
})
}
Loading

0 comments on commit 3173ed7

Please sign in to comment.