Skip to content
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

Add tests for pear shift #254

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
345 changes: 345 additions & 0 deletions test/07-commands.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,345 @@
const test = require('brittle')
const path = require('bare-path')
const Helper = require('./helper')
const { discoveryKey } = require('hypercore-crypto')
const fs = require('bare-fs')
const parseLink = require('../lib/parse-link')

const harness = path.join(Helper.localDir, 'test', 'fixtures', 'harness')
const minimal = path.join(Helper.localDir, 'test', 'fixtures', 'minimal')

class Rig {
setup = async ({ comment, timeout }) => {
timeout(180000)
const helper = new Helper()
this.helper = helper
comment('connecting local sidecar')
await helper.ready()
}

cleanup = async ({ comment }) => {
comment('shutting down local sidecar')
await this.helper.shutdown()
comment('local sidecar shut down')
}
}

const rig = new Rig()

test('commands setup', rig.setup)

test('pear shift <source> <destination>', async function ({ plan, is, teardown, timeout }) {
plan(2)
timeout(180000)

const relativePath = path.relative(harness, minimal)

const testId1 = Math.floor(Math.random() * 100000)
const argvInit1 = ['stage', '--json', `test-${testId1}`, relativePath]
const stager1 = await Helper.open(harness, { tags: ['exit'] }, { lineout: true })
await stager1.inspector.evaluate(`
__PEAR_TEST__.command(${JSON.stringify(argvInit1)})
`, { returnByValue: false })

let staged1
for await (const line of stager1.lineout) {
const result = JSON.parse(line)
if (result.tag === 'addendum') staged1 = result.data
if (result.tag === 'final') break
}

await stager1.inspector.evaluate('__PEAR_TEST__.ipc.destroy()', { returnByValue: false })
await stager1.inspector.close()
await stager1.until.exit

const testId2 = Math.floor(Math.random() * 100000)
const argvInit2 = ['stage', '--json', `test-${testId2}`, relativePath]
const stager2 = await Helper.open(harness, { tags: ['exit'] }, { lineout: true })
await stager2.inspector.evaluate(`
__PEAR_TEST__.command(${JSON.stringify(argvInit2)})
`, { returnByValue: false })

let staged2
for await (const line of stager2.lineout) {
const result = JSON.parse(line)
if (result.tag === 'addendum') staged2 = result.data
if (result.tag === 'final') break
}

const pearDir = (await stager2.inspector.evaluate('Pear.config.pearDir')).value

await stager2.inspector.evaluate('__PEAR_TEST__.ipc.destroy()', { returnByValue: false })
await stager2.inspector.close()
await stager2.until.exit

const storageDir = path.join(pearDir, 'app-storage', 'by-dkey')
const appStorage1 = path.join(storageDir, discoveryKey(parseLink(staged1.link).drive.key).toString('hex'))
const appStorage2 = path.join(storageDir, discoveryKey(parseLink(staged2.link).drive.key).toString('hex'))

fs.mkdirSync(appStorage1, { recursive: true })
fs.writeFileSync(path.join(appStorage1, 'test.txt'), 'test')
teardown(async () => {
await fs.promises.rm(appStorage1, { recursive: true }).catch(() => {})
await fs.promises.rm(appStorage2, { recursive: true }).catch(() => {})
})

const argv = ['shift', staged1.link, staged2.link]
const running = await Helper.open(harness, { tags: ['exit'] }, { lineout: true })
await running.inspector.evaluate(`
__PEAR_TEST__.command(${JSON.stringify(argv)})
`, { returnByValue: false })

let shiftSuccess = false
for await (const line of running.lineout) {
if (line.endsWith('Success')) {
shiftSuccess = true
break
}
}
await running.inspector.evaluate('__PEAR_TEST__.ipc.destroy()', { returnByValue: false })
await running.inspector.close()

is(shiftSuccess, true, 'should successfully shift app storage')
is(fs.existsSync(path.join(appStorage2, 'test.txt')), true, 'should move app storage file to destination')
await running.until.exit
})

test('pear shift --json <source> <destination>', async function ({ plan, is, alike, teardown, timeout }) {
plan(2)
timeout(180000)

const relativePath = path.relative(harness, minimal)

const testId1 = Math.floor(Math.random() * 100000)
const argvInit1 = ['stage', '--json', `test-${testId1}`, relativePath]
const stager1 = await Helper.open(harness, { tags: ['exit'] }, { lineout: true })
await stager1.inspector.evaluate(`
__PEAR_TEST__.command(${JSON.stringify(argvInit1)})
`, { returnByValue: false })

let staged1
for await (const line of stager1.lineout) {
const result = JSON.parse(line)
if (result.tag === 'addendum') staged1 = result.data
if (result.tag === 'final') break
}

await stager1.inspector.evaluate('__PEAR_TEST__.ipc.destroy()', { returnByValue: false })
await stager1.inspector.close()
await stager1.until.exit

const testId2 = Math.floor(Math.random() * 100000)
const argvInit2 = ['stage', '--json', `test-${testId2}`, relativePath]
const stager2 = await Helper.open(harness, { tags: ['exit'] }, { lineout: true })
await stager2.inspector.evaluate(`
__PEAR_TEST__.command(${JSON.stringify(argvInit2)})
`, { returnByValue: false })

let staged2
for await (const line of stager2.lineout) {
const result = JSON.parse(line)
if (result.tag === 'addendum') staged2 = result.data
if (result.tag === 'final') break
}

const pearDir = (await stager2.inspector.evaluate('Pear.config.pearDir')).value

await stager2.inspector.evaluate('__PEAR_TEST__.ipc.destroy()', { returnByValue: false })
await stager2.inspector.close()
await stager2.until.exit

const storageDir = path.join(pearDir, 'app-storage', 'by-dkey')
const appStorage1 = path.join(storageDir, discoveryKey(parseLink(staged1.link).drive.key).toString('hex'))
const appStorage2 = path.join(storageDir, discoveryKey(parseLink(staged2.link).drive.key).toString('hex'))

fs.mkdirSync(appStorage1, { recursive: true })
fs.writeFileSync(path.join(appStorage1, 'test.txt'), 'test')
teardown(async () => {
await fs.promises.rm(appStorage1, { recursive: true }).catch(() => {})
await fs.promises.rm(appStorage2, { recursive: true }).catch(() => {})
})

const argv = ['shift', '--json', staged1.link, staged2.link]
const running = await Helper.open(harness, { tags: ['exit'] }, { lineout: true })
await running.inspector.evaluate(`
__PEAR_TEST__.command(${JSON.stringify(argv)})
`, { returnByValue: false })

const seen = new Set()
const tags = []
for await (const line of running.lineout) {
const result = JSON.parse(line)
if (seen.has(result.tag)) continue
seen.add(result.tag)
tags.push(result.tag)
if (result.tag === 'final') break
}
await running.inspector.evaluate('__PEAR_TEST__.ipc.destroy()', { returnByValue: false })
await running.inspector.close()

alike(tags, ['moving', 'complete', 'final'], 'should output correct tags')
is(fs.existsSync(path.join(appStorage2, 'test.txt')), true, 'should move app storage file to destination')
await running.until.exit
})

test('pear shift --force <source> <destination>', async function ({ plan, is, teardown, timeout }) {
plan(3)
timeout(180000)

const relativePath = path.relative(harness, minimal)

const testId1 = Math.floor(Math.random() * 100000)
const argvInit1 = ['stage', '--json', `test-${testId1}`, relativePath]
const stager1 = await Helper.open(harness, { tags: ['exit'] }, { lineout: true })
await stager1.inspector.evaluate(`
__PEAR_TEST__.command(${JSON.stringify(argvInit1)})
`, { returnByValue: false })

let staged1
for await (const line of stager1.lineout) {
const result = JSON.parse(line)
if (result.tag === 'addendum') staged1 = result.data
if (result.tag === 'final') break
}

await stager1.inspector.evaluate('__PEAR_TEST__.ipc.destroy()', { returnByValue: false })
await stager1.inspector.close()
await stager1.until.exit

const testId2 = Math.floor(Math.random() * 100000)
const argvInit2 = ['stage', '--json', `test-${testId2}`, relativePath]
const stager2 = await Helper.open(harness, { tags: ['exit'] }, { lineout: true })
await stager2.inspector.evaluate(`
__PEAR_TEST__.command(${JSON.stringify(argvInit2)})
`, { returnByValue: false })

let staged2
for await (const line of stager2.lineout) {
const result = JSON.parse(line)
if (result.tag === 'addendum') staged2 = result.data
if (result.tag === 'final') break
}

const pearDir = (await stager2.inspector.evaluate('Pear.config.pearDir')).value

await stager2.inspector.evaluate('__PEAR_TEST__.ipc.destroy()', { returnByValue: false })
await stager2.inspector.close()
await stager2.until.exit

const storageDir = path.join(pearDir, 'app-storage', 'by-dkey')
const appStorage1 = path.join(storageDir, discoveryKey(parseLink(staged1.link).drive.key).toString('hex'))
const appStorage2 = path.join(storageDir, discoveryKey(parseLink(staged2.link).drive.key).toString('hex'))

fs.mkdirSync(appStorage1, { recursive: true })
fs.mkdirSync(appStorage2, { recursive: true })
fs.writeFileSync(path.join(appStorage1, 'test.txt'), 'test')
fs.writeFileSync(path.join(appStorage2, 'testold.txt'), 'test')
teardown(async () => {
await fs.promises.rm(appStorage1, { recursive: true }).catch(() => {})
await fs.promises.rm(appStorage2, { recursive: true }).catch(() => {})
})

const argv = ['shift', '--force', staged1.link, staged2.link]
const running = await Helper.open(harness, { tags: ['exit'] }, { lineout: true })
await running.inspector.evaluate(`
__PEAR_TEST__.command(${JSON.stringify(argv)})
`, { returnByValue: false })

let shiftSuccess = false
for await (const line of running.lineout) {
if (line.endsWith('Success')) {
shiftSuccess = true
break
}
}
await running.inspector.evaluate('__PEAR_TEST__.ipc.destroy()', { returnByValue: false })
await running.inspector.close()

is(shiftSuccess, true, 'should successfully shift app storage')
is(fs.existsSync(path.join(appStorage2, 'test.txt')), true, 'should move app storage file to destination')
is(fs.existsSync(path.join(appStorage2, 'testold.txt')), false, 'should delete existing app storage file at destination')
await running.until.exit
})

test('pear shift --force --json <source> <destination>', async function ({ plan, is, teardown, timeout, alike }) {
plan(3)
timeout(180000)

const relativePath = path.relative(harness, minimal)

const testId1 = Math.floor(Math.random() * 100000)
const argvInit1 = ['stage', '--json', `test-${testId1}`, relativePath]
const stager1 = await Helper.open(harness, { tags: ['exit'] }, { lineout: true })
await stager1.inspector.evaluate(`
__PEAR_TEST__.command(${JSON.stringify(argvInit1)})
`, { returnByValue: false })

let staged1
for await (const line of stager1.lineout) {
const result = JSON.parse(line)
if (result.tag === 'addendum') staged1 = result.data
if (result.tag === 'final') break
}

await stager1.inspector.evaluate('__PEAR_TEST__.ipc.destroy()', { returnByValue: false })
await stager1.inspector.close()
await stager1.until.exit

const testId2 = Math.floor(Math.random() * 100000)
const argvInit2 = ['stage', '--json', `test-${testId2}`, relativePath]
const stager2 = await Helper.open(harness, { tags: ['exit'] }, { lineout: true })
await stager2.inspector.evaluate(`
__PEAR_TEST__.command(${JSON.stringify(argvInit2)})
`, { returnByValue: false })

let staged2
for await (const line of stager2.lineout) {
const result = JSON.parse(line)
if (result.tag === 'addendum') staged2 = result.data
if (result.tag === 'final') break
}

const pearDir = (await stager2.inspector.evaluate('Pear.config.pearDir')).value

await stager2.inspector.evaluate('__PEAR_TEST__.ipc.destroy()', { returnByValue: false })
await stager2.inspector.close()
await stager2.until.exit

const storageDir = path.join(pearDir, 'app-storage', 'by-dkey')
const appStorage1 = path.join(storageDir, discoveryKey(parseLink(staged1.link).drive.key).toString('hex'))
const appStorage2 = path.join(storageDir, discoveryKey(parseLink(staged2.link).drive.key).toString('hex'))

fs.mkdirSync(appStorage1, { recursive: true })
fs.mkdirSync(appStorage2, { recursive: true })
fs.writeFileSync(path.join(appStorage1, 'test.txt'), 'test')
fs.writeFileSync(path.join(appStorage2, 'testold.txt'), 'test')
teardown(async () => {
await fs.promises.rm(appStorage1, { recursive: true }).catch(() => {})
await fs.promises.rm(appStorage2, { recursive: true }).catch(() => {})
})

const argv = ['shift', '--force', '--json', staged1.link, staged2.link]
const running = await Helper.open(harness, { tags: ['exit'] }, { lineout: true })
await running.inspector.evaluate(`
__PEAR_TEST__.command(${JSON.stringify(argv)})
`, { returnByValue: false })

const seen = new Set()
const tags = []
for await (const line of running.lineout) {
const result = JSON.parse(line)
if (seen.has(result.tag)) continue
seen.add(result.tag)
tags.push(result.tag)
if (result.tag === 'final') break
}
await running.inspector.evaluate('__PEAR_TEST__.ipc.destroy()', { returnByValue: false })
await running.inspector.close()

alike(tags, ['moving', 'complete', 'final'], 'should output correct tags')
is(fs.existsSync(path.join(appStorage2, 'test.txt')), true, 'should move app storage file to destination')
is(fs.existsSync(path.join(appStorage2, 'testold.txt')), false, 'should delete existing app storage file at destination')
await running.until.exit
})

test('commands cleanup', rig.cleanup)
2 changes: 1 addition & 1 deletion test/fixtures/harness/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Harness extends ReadyResource {
const { default: cmd } = await import('pear/cmd')
this.cmd = cmd
}
return new this.Helper(opts)
return new this.Helper({ platformDir: global.Pear.config.pearDir, opts })
}

nextUpdate () {
Expand Down
1 change: 1 addition & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ async function runTests () {
await import('./04-worker.test.js')
await import('./05-encrypted.test.js')
await import('./06-updates.test.js')
await import('./07-commands.test.js')

test.resume()
}
Loading