orbitdb/test/log-references.spec.js
2023-02-16 10:18:39 +02:00

175 lines
6.6 KiB
JavaScript

import { strictEqual } from 'assert'
import rimraf from 'rimraf'
import { copy } from 'fs-extra'
import { Log, MemoryStorage } from '../src/log.js'
import IdentityProvider from 'orbit-db-identity-provider'
import Keystore from '../src/Keystore.js'
// Test utils
import { config, testAPIs } from 'orbit-db-test-utils'
const { sync: rmrf } = rimraf
const { createIdentity } = IdentityProvider
let testIdentity
Object.keys(testAPIs).forEach((IPFS) => {
describe('Log - References (' + IPFS + ')', function () {
this.timeout(config.timeout)
const { identityKeyFixtures, signingKeyFixtures, identityKeysPath, signingKeysPath } = config
let keystore, signingKeystore
before(async () => {
rmrf(identityKeysPath)
rmrf(signingKeysPath)
await copy(identityKeyFixtures, identityKeysPath)
await copy(signingKeyFixtures, signingKeysPath)
keystore = new Keystore(identityKeysPath)
signingKeystore = new Keystore(signingKeysPath)
testIdentity = await createIdentity({ id: 'userA', keystore, signingKeystore })
})
after(async () => {
rmrf(identityKeysPath)
rmrf(signingKeysPath)
await keystore.close()
await signingKeystore.close()
})
describe('References', async () => {
const amount = 64
it('creates entries with 2 references', async () => {
const maxReferenceDistance = 2
const log1 = await Log(testIdentity, { logId: 'A' })
for (let i = 0; i < amount; i++) {
await log1.append(i.toString(), { pointerCount: maxReferenceDistance })
}
const values1 = await log1.values()
strictEqual(values1[values1.length - 1].refs.length, 1)
})
it('creates entries with 4 references', async () => {
const maxReferenceDistance = 2
const log2 = await Log(testIdentity, { logId: 'B' })
for (let i = 0; i < amount * 2; i++) {
await log2.append(i.toString(), { pointerCount: Math.pow(maxReferenceDistance, 2) })
}
const values2 = await log2.values()
strictEqual(values2[values2.length - 1].refs.length, 2)
})
it('creates entries with 8 references', async () => {
const maxReferenceDistance = 2
const log3 = await Log(testIdentity, { logId: 'C' })
for (let i = 0; i < amount * 3; i++) {
await log3.append(i.toString(), { pointerCount: Math.pow(maxReferenceDistance, 3) })
}
const values3 = await log3.values()
strictEqual(values3[values3.length - 1].refs.length, 3)
})
it('creates entries with 16 references', async () => {
const maxReferenceDistance = 2
const log4 = await Log(testIdentity, { logId: 'D' })
for (let i = 0; i < amount * 4; i++) {
await log4.append(i.toString(), { pointerCount: Math.pow(maxReferenceDistance, 4) })
}
const values4 = await log4.values()
strictEqual(values4[values4.length - 1].refs.length, 4)
})
const inputs = [
{ amount: 1, referenceCount: 1, refLength: 0 },
{ amount: 1, referenceCount: 2, refLength: 0 },
{ amount: 2, referenceCount: 1, refLength: 1 },
{ amount: 2, referenceCount: 2, refLength: 1 },
{ amount: 3, referenceCount: 2, refLength: 1 },
{ amount: 3, referenceCount: 4, refLength: 1 },
{ amount: 4, referenceCount: 4, refLength: 2 },
{ amount: 4, referenceCount: 4, refLength: 2 },
{ amount: 32, referenceCount: 4, refLength: 2 },
{ amount: 32, referenceCount: 8, refLength: 3 },
{ amount: 32, referenceCount: 16, refLength: 4 },
{ amount: 18, referenceCount: 32, refLength: 5 },
{ amount: 128, referenceCount: 32, refLength: 5 },
{ amount: 63, referenceCount: 64, refLength: 5 },
{ amount: 64, referenceCount: 64, refLength: 6 },
{ amount: 65, referenceCount: 64, refLength: 6 },
{ amount: 91, referenceCount: 64, refLength: 6 },
{ amount: 128, referenceCount: 64, refLength: 6 },
{ amount: 128, referenceCount: 1, refLength: 0 },
{ amount: 128, referenceCount: 2, refLength: 1 },
{ amount: 256, referenceCount: 1, refLength: 0 },
{ amount: 256, referenceCount: 4, refLength: 2 },
{ amount: 256, referenceCount: 8, refLength: 3 },
{ amount: 256, referenceCount: 16, refLength: 4 },
{ amount: 256, referenceCount: 32, refLength: 5 },
{ amount: 1024, referenceCount: 2, refLength: 1 }
]
inputs.forEach(input => {
it(`has ${input.refLength} references, max distance ${input.referenceCount}, total of ${input.amount} entries`, async () => {
const test = async (amount, referenceCount, refLength) => {
const storage = await MemoryStorage()
const log1 = await Log(testIdentity, { logId: 'A', storage })
for (let i = 0; i < amount; i++) {
await log1.append((i + 1).toString(), { pointerCount: referenceCount })
}
const values = await log1.values()
strictEqual(values.length, input.amount)
strictEqual(values[values.length - 1].clock.time, input.amount)
for (let k = 0; k < input.amount; k++) {
const idx = values.length - k - 1
strictEqual(values[idx].clock.time, idx + 1)
// Check the first ref (distance 2)
if (values[idx].refs.length > 0) { strictEqual(values[idx].refs[0], values[idx - 2].hash) }
// Check the second ref (distance 4)
if (values[idx].refs.length > 1 && idx > referenceCount) { strictEqual(values[idx].refs[1], values[idx - 4].hash) }
// Check the third ref (distance 8)
if (values[idx].refs.length > 2 && idx > referenceCount) { strictEqual(values[idx].refs[2], values[idx - 8].hash) }
// Check the fourth ref (distance 16)
if (values[idx].refs.length > 3 && idx > referenceCount) { strictEqual(values[idx].refs[3], values[idx - 16].hash) }
// Check the fifth ref (distance 32)
if (values[idx].refs.length > 4 && idx > referenceCount) { strictEqual(values[idx].refs[4], values[idx - 32].hash) }
// Check the fifth ref (distance 64)
if (values[idx].refs.length > 5 && idx > referenceCount) { strictEqual(values[idx].refs[5], values[idx - 64].hash) }
// Check the reference of each entry
if (idx > referenceCount) { strictEqual(values[idx].refs.length, refLength) }
}
}
await test(input.amount, input.referenceCount, input.refLength)
})
})
})
})
})