diff --git a/package.json b/package.json index 0d8796c48d7733c2c80deda635ff4c7344acfd1e..fe988f094d57f88d17eceed049a71fbbab0e349b 100755 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "main": "index.js", "license": "AGPLv3", "scripts": { - "prepublish": "tsc" + "prepublish": "tsc", + "test": "mocha" }, "dependencies": { "body-parser": "1.17.1", @@ -21,8 +22,12 @@ }, "devDependencies": { "@types/node": "^11.9.3", + "@types/mocha": "^2.2.41", "duniter": "1.7.x", - "typescript": "^3.3.3" + "typescript": "^3.3.3", + "mocha": "^3.4.2", + "should": "*", + "ts-node": "^3.3.0" }, "peerDependencies": { "duniter": "1.7.x" diff --git a/test/indexing.ts b/test/indexing.ts new file mode 100644 index 0000000000000000000000000000000000000000..f5f94bc99c3515e03711f7e6f46863afe991b4f1 --- /dev/null +++ b/test/indexing.ts @@ -0,0 +1,97 @@ +// Source file from duniter: Crypto-currency software to manage libre currency such as Ğ1 +// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +import {assertEqual, assertTrue, writeBasicTestWithConfAnd2Users} from "duniter/test/integration/tools/test-framework" +import {CommonConstants} from "duniter/app/lib/common-libs/constants"; +import {DataFinder, initMonitDB} from "../lib/DataFinder"; +import {MonitDBBlock} from "../lib/SqliteBlockchain"; + +describe('Indexing blockchain', () => writeBasicTestWithConfAnd2Users({ + sigQty: 1, + medianTimeBlocks: 1, + forksize: 2, +}, (test) => { + + const now = 1500000000 + + before(() => { + CommonConstants.BLOCKS_IN_MEMORY_MAX = 3 // Must be > forkWindowSize + }) + + test('Duniter blockchain init', async (s1, cat, tac) => { + await cat.createIdentity() + await tac.createIdentity() + await cat.cert(tac) + await tac.cert(cat) + await cat.join() + await tac.join() + for (let i = 0; i < 6; i++) { + await s1.commit({ time: now }) + } + const head = await s1.commit({ time: now }) + assertEqual(head.number, 6); + (s1.dal.blockchainArchiveDAL as any)._chunkSize = 2 // Archive 2 blocks per file + }) + + test('first indexing by monit', async (s1) => { + // Simulate that archiving was called on Duniter once (during sync) + await s1.dal.archiveBlocks() + // Now test Monit + await initMonitDB(s1._server, true) + assertEqual(await DataFinder.getInstance().getHighestBlockNumber(), 6) // Current block in Monit = current in Duniter + assertEqual(await DataFinder.getInstance().getHighestArchivedBlockNumber(), 4) // Highest archived = current - forksize + }) + + test('second indexing by monit after adding some blocks to the blockchain', async (s1) => { + for (let i = 0; i < 3; i++) { + await s1.commit({ time: now }) + } + // Now test Monit + await DataFinder.getInstance().index() + assertEqual(await DataFinder.getInstance().getHighestBlockNumber(), 9) + assertEqual(await DataFinder.getInstance().getHighestArchivedBlockNumber(), 7) + }) + + test('third indexing taking care of forks', async (s1) => { + + // Make a #10 block + const b10v1Duniter = await s1.commit({ time: now }) + await DataFinder.getInstance().index() + const b10v1Monit = await DataFinder.getInstance().getHighestBlock() as MonitDBBlock + assertEqual(await DataFinder.getInstance().getHighestBlockNumber(), 10) + assertEqual(b10v1Monit.number, 10) + assertEqual(b10v1Monit.hash, b10v1Duniter.hash) + assertEqual(await DataFinder.getInstance().getHighestArchivedBlockNumber(), 8) // Archived level = 10 - forksize + + // Revert + await s1.revert() + + // Re-commit + const b10v2Duniter = await s1.commit({ time: now + 1 }) + await DataFinder.getInstance().index() + const b10v2Monit = await DataFinder.getInstance().getHighestBlock() as MonitDBBlock + assertEqual(await DataFinder.getInstance().getHighestBlockNumber(), 10) + assertEqual(b10v2Monit.number, 10) + assertEqual(b10v2Monit.hash, b10v2Duniter.hash) + assertEqual(await DataFinder.getInstance().getHighestArchivedBlockNumber(), 8) // Archived level = 10 - forksize + + // assertions + assertTrue(b10v1Duniter.number === b10v2Duniter.number) + assertTrue(b10v1Duniter.hash !== b10v2Duniter.hash) + assertTrue(b10v1Monit.number === b10v2Monit.number) + assertTrue(b10v1Monit.hash !== b10v2Monit.hash) + assertTrue(b10v1Monit.hash === b10v1Duniter.hash) + assertTrue(b10v2Monit.hash === b10v2Duniter.hash) + }) +})) + diff --git a/test/mocha.opts b/test/mocha.opts new file mode 100644 index 0000000000000000000000000000000000000000..21039253bb7916b4aff02e306631ef57795f1f0b --- /dev/null +++ b/test/mocha.opts @@ -0,0 +1,8 @@ +--compilers ts-node/register +--require source-map-support/register +--full-trace +--growl +--timeout 60000 +--recursive +-R spec +test/ diff --git a/tsconfig.json b/tsconfig.json index 5cad0e30a8a110973b49d9aabd086ad9c086f856..84a98f52f36aa28b8697d453fbb6581326774c2c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,7 +15,8 @@ }, "include": [ "routes", - "lib" + "lib", + "test" ], "compileOnSave": true }