orbitdb/test/orbitdb-multiple-databases.test.js
2023-09-23 16:25:29 +01:00

182 lines
4.9 KiB
JavaScript

import { strictEqual } from 'assert'
// import mapSeries from 'p-each-series'
import { rimraf } from 'rimraf'
import OrbitDB from '../src/orbitdb.js'
import connectPeers from './utils/connect-nodes.js'
import waitFor from './utils/wait-for.js'
import createHelia from './utils/create-helia.js'
const dbPath1 = './orbitdb/tests/multiple-databases/1'
const dbPath2 = './orbitdb/tests/multiple-databases/2'
const databaseInterfaces = [
{
name: 'events',
open: async (orbitdb, address, options) => await orbitdb.open(address, options),
write: async (db, index) => {
await db.add('hello' + index)
},
query: async (db) => {
const all = await db.all()
return all.length
}
},
{
name: 'key-value',
open: async (orbitdb, address, options) => await orbitdb.open(address, { ...options, type: 'keyvalue' }),
write: async (db, index) => await db.put('hello', index),
query: async (db) => await db.get('hello')
},
{
name: 'documents',
open: async (orbitdb, address, options) => await orbitdb.open(address, { ...options, type: 'documents' }),
write: async (db, index) => await db.put({ _id: 'hello', testing: index }),
query: async (db) => {
const doc = await db.get('hello')
return doc ? doc.value.testing : 0
}
}
]
describe('orbitdb - Multiple Databases', function () {
this.timeout(30000)
let ipfs1, ipfs2
let orbitdb1, orbitdb2
const localDatabases = []
const remoteDatabases = []
// Create two IPFS instances and two OrbitDB instances (2 nodes/peers)
before(async () => {
[ipfs1, ipfs2] = await Promise.all([createHelia(), createHelia()])
await connectPeers(ipfs1, ipfs2)
console.log('Peers connected')
orbitdb1 = await OrbitDB({ ipfs: ipfs1, id: 'user1', directory: dbPath1 })
orbitdb2 = await OrbitDB({ ipfs: ipfs2, id: 'user2', directory: dbPath2 })
})
after(async () => {
if (orbitdb1) {
await orbitdb1.stop()
}
if (orbitdb2) {
await orbitdb2.stop()
}
await rimraf('./orbitdb')
if (ipfs1) {
await ipfs1.stop()
}
if (ipfs2) {
await ipfs2.stop()
}
await rimraf('./ipfs1')
await rimraf('./ipfs2')
})
beforeEach(async () => {
let options = {}
// Set write access for both clients
options.write = [
orbitdb1.identity.id,
orbitdb2.identity.id
]
let connected1Count = 0
let connected2Count = 0
const onConnected1 = async (peerId, heads) => {
++connected1Count
}
const onConnected2 = async (peerId, heads) => {
++connected2Count
}
console.log('Creating databases and waiting for peers to connect')
// Open the databases on the first node
options = Object.assign({}, options, { create: true })
// Open the databases on the first node
for (const dbInterface of databaseInterfaces) {
const db = await dbInterface.open(orbitdb1, dbInterface.name, options)
db.events.on('join', onConnected1)
localDatabases.push(db)
}
for (const [index, dbInterface] of databaseInterfaces.entries()) {
const address = localDatabases[index].address.toString()
const db = await dbInterface.open(orbitdb2, address, options)
db.events.on('join', onConnected2)
remoteDatabases.push(db)
}
// Wait for the peers to connect
await waitFor(() => connected1Count === 3, () => true)
await waitFor(() => connected2Count === 3, () => true)
console.log('Peers connected')
})
afterEach(async () => {
for (const db of remoteDatabases) {
await db.drop()
await db.close()
}
for (const db of localDatabases) {
await db.drop()
await db.close()
}
})
it('replicates multiple open databases', async () => {
const entryCount = 10
// Write entries to each database
console.log('Writing to databases')
for (let index = 0; index < databaseInterfaces.length; index++) {
const dbInterface = databaseInterfaces[index]
const db = localDatabases[index]
// Create an array that we use to create the db entries
for (let i = 1; i < entryCount + 1; i++) {
await dbInterface.write(db, i)
}
}
const isReplicated = async (db) => {
const all = await db.log.all()
return all.length === entryCount
}
// Function to check if all databases have been replicated
const allReplicated = async () => {
for (const db of remoteDatabases) {
const replicated = await isReplicated(db)
if (!replicated) {
return false
}
}
return true
}
console.log('Waiting for replication to finish')
await waitFor(async () => await allReplicated(), () => true, 2000)
console.log('Replication finished')
for (let i = 0; i < databaseInterfaces.length; i++) {
const db = remoteDatabases[i]
const result = await databaseInterfaces[i].query(db)
strictEqual(result, entryCount)
strictEqual((await db.log.all()).length, entryCount)
}
})
})