Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
738a8a7
Rename applicationName to contextName. Add replicator permissions.
Dec 8, 2022
a43a44c
Add generateHash utility method
Dec 8, 2022
237b6c8
Refactor so context databases are in their own database that will be …
Dec 9, 2022
a6834a6
Implement untested auth/replicationCreds
Dec 9, 2022
81e27b9
Implementation complete, untested.
Dec 10, 2022
f4f4b59
Add comments for next steps
Dec 11, 2022
d5ba263
First pass at replication test
Dec 11, 2022
2fa4209
Fix missing endpoint variable
Dec 13, 2022
e34169e
Bug fixes and enhanced logging
Dec 14, 2022
07ed3f7
Bug fixes from testing
Dec 14, 2022
e8c7187
Bug fixes
Dec 14, 2022
9913781
Support generating correct CouchURI for server
Dec 14, 2022
6532f5c
Bug fixes
Dec 14, 2022
35d4947
Fix syntax error
Dec 14, 2022
f883ab2
First tests passing
Dec 14, 2022
33022a3
Fix clearing databases. Add warnings.
Dec 14, 2022
5077cad
Ensure replicator user has did context role
Dec 14, 2022
34d1849
Bug fixes
Dec 14, 2022
ea1772a
Try basic auth header
Dec 14, 2022
a06c32c
Update replication document creation
Dec 15, 2022
bd4088a
Create new replicater user for replication instead of using admin
Dec 15, 2022
5b39538
Bug fix replication
Dec 15, 2022
f4f0f66
Update working tests
Dec 15, 2022
0e2000b
All tests written so far, pass!
Dec 15, 2022
eae007d
Remove commented test code
Dec 15, 2022
2ef69ff
Code cleanup
Dec 15, 2022
f519090
Code cleanup. Replication test cleanup. Verify timestamp when fetchin…
Dec 15, 2022
b64191e
Replication tests all passing with remote 3x servers
Dec 19, 2022
cf18ed0
Remove console output
Dec 19, 2022
e69bb7f
Merge branch 'release/2.0-acacia' into feature/49-server-replication
Dec 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sample.env
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ DB_HOST_EXTERNAL="localhost"
DB_PORT_EXTERNAL=5984

# The public URI of this storage node server (Will match what is stored in DID Documents)
# Note: Must include the port and have NO trailing slash
ENDPOINT_URI="http://localhost:5000"

DB_REJECT_UNAUTHORIZED_SSL=true
Expand Down
61 changes: 22 additions & 39 deletions test/replication.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ describe("Replication tests", function() {
if (!doc) {
doc = new DIDDocument(DID, DID_PUBLIC_KEY)
}

await doc.addContext(CONTEXT_NAME, keyring, DID_PRIVATE_KEY, {
database: {
type: 'VeridaDatabase',
Expand Down Expand Up @@ -163,7 +164,7 @@ describe("Replication tests", function() {
})

// Create the test databases on the first endpoint
it.only('can create the test databases on the endpoints', async () => {
it('can create the test databases on the endpoints', async () => {
for (let i in ENDPOINTS) {
let endpoint = ENDPOINTS[i]
for (let i in TEST_DATABASES) {
Expand All @@ -175,7 +176,7 @@ describe("Replication tests", function() {
})

// Call `checkReplication(db1)` on all the endpoints (first database only)
it.only('can initialise replication for one database via checkReplication()', async () => {
it('can initialise replication for one database via checkReplication()', async () => {
// @todo: fix code so endpoint doesn't create replication entries to itself
try {
for (let i in ENDPOINTS) {
Expand Down Expand Up @@ -226,7 +227,9 @@ describe("Replication tests", function() {
assert.equal(replicationEntry.source.url, `http://localhost:5984/${dbHash}`, `Source URI is correct for ${endpointCheckUri}`)
assert.equal(replicationEntry.target.url, `${ENDPOINTS_COUCH[endpointCheckUri]}/${dbHash}`, `Destination URI is correct for ${endpointCheckUri}`)

REPLICATOR_CREDS[endpoint] = replicationEntry.target.headers
if (!REPLICATOR_CREDS[endpointCheckUri]) {
REPLICATOR_CREDS[endpointCheckUri] = replicationEntry.target.headers
}

const replicationResponse = await Axios.get(`${ENDPOINT_DSN[endpoint]}/_scheduler/docs/_replicator/${replicatorId}-${dbHash}`)
assert.ok(replicationResponse, 'Have a replication job')
Expand All @@ -241,11 +244,12 @@ describe("Replication tests", function() {
}
})

it.only('verify replication user can write to first database', async () => {
it('verify replication user can write to first database', async () => {
const endpoint0 = ENDPOINTS[0]
const endpoint1 = ENDPOINTS[1]

const couch = buildEndpointConnection(ENDPOINT_DSN[endpoint0], REPLICATOR_CREDS[endpoint1])
const creds = REPLICATOR_CREDS[endpoint0]
const couch = buildEndpointConnection(ENDPOINTS_COUCH[endpoint0], creds)

log(`${endpoint0}: Creating three test records on ${TEST_DATABASES[0]} (${TEST_DATABASE_HASH[0]}) using credentials from ${endpoint1}`)
const endpoint0db1Connection = couch.db.use(TEST_DATABASE_HASH[0])
Expand All @@ -258,7 +262,7 @@ describe("Replication tests", function() {
})

// Verify data saved to db1 is being replicated for all endpoints
it.only('verify data is replicated on all endpoints for first database', async () => {
it('verify data is replicated on all endpoints for first database', async () => {
// Sleep 5ms to have replication time to do its thing
log('Sleeping so replication has time to do its thing...')
await Utils.sleep(5000)
Expand All @@ -272,9 +276,8 @@ describe("Replication tests", function() {

const externalEndpoint = ENDPOINTS[i]

// Connect to the external endpoint, using the credentials from the
// first endpoint to confirm it has access (plus admin user doesnt have access)
const couch = buildEndpointConnection(ENDPOINTS_COUCH[externalEndpoint], REPLICATOR_CREDS[ENDPOINTS[0]])
const creds = REPLICATOR_CREDS[externalEndpoint]
const couch = buildEndpointConnection(ENDPOINTS_COUCH[externalEndpoint], creds)
const conn = couch.db.use(TEST_DATABASE_HASH[0])

log(`${externalEndpoint}: Verifying endpoint has docs`)
Expand All @@ -285,7 +288,7 @@ describe("Replication tests", function() {
}
})

it.only('can initialise replication for all database via checkReplication()', async () => {
it('can initialise replication for all database via checkReplication()', async () => {
for (let i in ENDPOINTS) {
const endpoint = ENDPOINTS[i]
log(`${endpoint}: Calling checkReplication() on all databases for ${endpoint}`)
Expand All @@ -294,10 +297,10 @@ describe("Replication tests", function() {
}
})

it.only('verify data is being replicated for all databases and endpoints', async () => {
// Sleep 5ms to have replication time to initialise
it('verify data is being replicated for all databases and endpoints', async () => {
// Sleep 1s to have replication time to initialise
log('Sleeping so replication has time to do its thing...')
await Utils.sleep(5000)
await Utils.sleep(1000)

let recordCount = 0
// Create data on every database, on every endpoint, and verify on every other endpoint
Expand All @@ -314,15 +317,7 @@ describe("Replication tests", function() {
log(`${dbName} (${dbHash}): Creating a record on every endpoint`)
for (let e in ENDPOINTS) {
const endpoint = ENDPOINTS[e]

// Use the credentials of a different server as the local server doesn't have permissions
// to write (even as admin)
let creds
if (e == 0) {
creds = REPLICATOR_CREDS[ENDPOINTS[1]]
} else {
creds = REPLICATOR_CREDS[ENDPOINTS[0]]
}
const creds = REPLICATOR_CREDS[endpoint]

// create a record on this endpoint
const couch = buildEndpointConnection(ENDPOINTS_COUCH[endpoint], creds)
Expand All @@ -333,19 +328,12 @@ describe("Replication tests", function() {
}

log(`${dbName} (${dbHash}): Done (${createdDatabaseIds.length}). Sleeping for replication to do its thing...`)
await Utils.sleep(5000)
await Utils.sleep(1000)

for (let e in ENDPOINTS) {
const endpoint = ENDPOINTS[e]

// Use the credentials of a different server as the local server doesn't have permissions
// to write (even as admin)
let creds
if (e == 0) {
creds = REPLICATOR_CREDS[ENDPOINTS[1]]
} else {
creds = REPLICATOR_CREDS[ENDPOINTS[0]]
}
const creds = REPLICATOR_CREDS[endpoint]

// create a record on this endpoint
const couch = buildEndpointConnection(ENDPOINTS_COUCH[endpoint], creds)
Expand All @@ -361,7 +349,7 @@ describe("Replication tests", function() {
}
})

it.only('can delete a database', async () => {
it('can delete a database', async () => {
// delete a database from all endpoints
for (let e in ENDPOINTS) {
const endpoint = ENDPOINTS[e]
Expand All @@ -370,20 +358,15 @@ describe("Replication tests", function() {
}
})

it.only('verify database is completely deleted from all endpoints', async () => {
it('verify database is completely deleted from all endpoints', async () => {
const dbHash = TEST_DATABASE_HASH[0]

for (let e in ENDPOINTS) {
const endpoint = ENDPOINTS[e]

// Use the credentials of a different server as the local server doesn't have permissions
// to write (even as admin)
let creds
if (e == 0) {
creds = REPLICATOR_CREDS[ENDPOINTS[1]]
} else {
creds = REPLICATOR_CREDS[ENDPOINTS[0]]
}
const creds = REPLICATOR_CREDS[endpoint]

const couch = buildEndpointConnection(ENDPOINTS_COUCH[endpoint], creds)

Expand Down
24 changes: 24 additions & 0 deletions test/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,24 @@ class Utils {
return response
}

async deleteDatabase(databaseName, did, contextName, accessToken, serverUrl) {
if (!serverUrl) {
serverUrl = CONFIG.SERVER_URL
}

const response = await Axios.post(`${serverUrl}/user/deleteDatabase`, {
databaseName,
did,
contextName
}, {
headers: {
Authorization: `Bearer ${accessToken}`
}
});

return response
}

async checkReplication(endpointUri, accessToken, databaseName) {
const response = await Axios.post(`${endpointUri}/user/checkReplication`, {
databaseName
Expand Down Expand Up @@ -116,6 +134,12 @@ class Utils {
delete response.data['signature']
return EncryptionUtils.verifySig(response.data, signature, VDA_PUBLIC_KEY)
}

async sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
}

const utils = new Utils()
Expand Down