-
Notifications
You must be signed in to change notification settings - Fork 286
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(core-blockchain): increase coverage to 100% (#3604)
- Loading branch information
Showing
28 changed files
with
2,916 additions
and
9 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
385 changes: 385 additions & 0 deletions
385
__tests__/unit/core-blockchain/processor/block-processor.test.ts
Large diffs are not rendered by default.
Oops, something went wrong.
99 changes: 99 additions & 0 deletions
99
__tests__/unit/core-blockchain/processor/handlers/accept-block-handler.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { Container } from "@arkecosystem/core-kernel"; | ||
import { AcceptBlockHandler } from "../../../../../packages/core-blockchain/src/processor/handlers/accept-block-handler"; | ||
import { BlockProcessorResult } from "../../../../../packages/core-blockchain/src/processor"; | ||
import { Interfaces } from "@arkecosystem/crypto"; | ||
|
||
describe("AcceptBlockHandler", () => { | ||
const container = new Container.Container(); | ||
|
||
const logger = { warning: jest.fn(), debug: jest.fn(), info: jest.fn() }; | ||
const blockchain = { resetLastDownloadedBlock: jest.fn(), resetWakeUp: jest.fn() }; | ||
const state = { | ||
forkedBlock: undefined, | ||
started: undefined, | ||
setLastBlock: jest.fn(), | ||
lastDownloadedBlock: undefined | ||
}; | ||
const database = { applyBlock: jest.fn() }; | ||
const transactionPool = { acceptForgedTransaction: jest.fn() }; | ||
|
||
const application = { get: jest.fn() }; | ||
|
||
beforeAll(() => { | ||
container.unbindAll(); | ||
container.bind(Container.Identifiers.Application).toConstantValue(application); | ||
container.bind(Container.Identifiers.LogService).toConstantValue(logger); | ||
container.bind(Container.Identifiers.BlockchainService).toConstantValue(blockchain); | ||
container.bind(Container.Identifiers.StateStore).toConstantValue(state); | ||
container.bind(Container.Identifiers.DatabaseService).toConstantValue(database); | ||
container.bind(Container.Identifiers.TransactionPoolService).toConstantValue(transactionPool); | ||
}); | ||
|
||
beforeEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
describe("execute", () => { | ||
const block = { | ||
data: { id: "1222", height: 5544 }, | ||
transactions: [ | ||
{ "id": "11" }, | ||
{ "id": "12" }, | ||
] | ||
}; | ||
|
||
it("should apply block to database, transaction pool, blockchain and state", async () => { | ||
const acceptBlockHandler = container.resolve<AcceptBlockHandler>(AcceptBlockHandler); | ||
|
||
state.started = true; | ||
const result = await acceptBlockHandler.execute(block as Interfaces.IBlock); | ||
|
||
expect(result).toBe(BlockProcessorResult.Accepted); | ||
|
||
expect(database.applyBlock).toBeCalledTimes(1); | ||
expect(database.applyBlock).toHaveBeenCalledWith(block); | ||
|
||
expect(blockchain.resetWakeUp).toBeCalledTimes(1); | ||
|
||
expect(transactionPool.acceptForgedTransaction).toBeCalledTimes(2); | ||
expect(transactionPool.acceptForgedTransaction).toHaveBeenCalledWith(block.transactions[0]); | ||
expect(transactionPool.acceptForgedTransaction).toHaveBeenCalledWith(block.transactions[1]); | ||
|
||
expect(state.setLastBlock).toBeCalledTimes(1); | ||
expect(state.setLastBlock).toHaveBeenCalledWith(block); | ||
}) | ||
|
||
it("should reset state.forkedBlock if incoming block has same height", async () => { | ||
const acceptBlockHandler = container.resolve<AcceptBlockHandler>(AcceptBlockHandler); | ||
|
||
state.forkedBlock = { data: { height: block.data.height } }; | ||
const result = await acceptBlockHandler.execute(block as Interfaces.IBlock); | ||
|
||
expect(result).toBe(BlockProcessorResult.Accepted); | ||
|
||
expect(state.forkedBlock).toBeUndefined(); | ||
}) | ||
|
||
it("should set state.lastDownloadedBlock if incoming block height is higher", async () => { | ||
const acceptBlockHandler = container.resolve<AcceptBlockHandler>(AcceptBlockHandler); | ||
|
||
state.lastDownloadedBlock = { height: block.data.height - 1 }; | ||
const result = await acceptBlockHandler.execute(block as Interfaces.IBlock); | ||
|
||
expect(result).toBe(BlockProcessorResult.Accepted); | ||
|
||
expect(state.lastDownloadedBlock).toBe(block.data); | ||
}) | ||
|
||
it("should return Reject and resetLastDownloadedBlock when something throws", async () => { | ||
const acceptBlockHandler = container.resolve<AcceptBlockHandler>(AcceptBlockHandler); | ||
|
||
database.applyBlock = jest.fn().mockRejectedValueOnce(new Error("oops")); | ||
const result = await acceptBlockHandler.execute(block as Interfaces.IBlock); | ||
|
||
expect(result).toBe(BlockProcessorResult.Rejected); | ||
|
||
expect(blockchain.resetLastDownloadedBlock).toBeCalledTimes(1); | ||
}) | ||
}) | ||
}) |
34 changes: 34 additions & 0 deletions
34
__tests__/unit/core-blockchain/processor/handlers/already-forged-handler.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Container } from "@arkecosystem/core-kernel"; | ||
import { AlreadyForgedHandler } from "../../../../../packages/core-blockchain/src/processor/handlers/already-forged-handler"; | ||
import { BlockProcessorResult } from "../../../../../packages/core-blockchain/src/processor"; | ||
import { Interfaces } from "@arkecosystem/crypto"; | ||
|
||
describe("AlreadyForgedHandler", () => { | ||
const container = new Container.Container(); | ||
|
||
const blockchain = { resetLastDownloadedBlock: jest.fn() }; | ||
|
||
const application = { get: jest.fn() }; | ||
|
||
beforeAll(() => { | ||
container.unbindAll(); | ||
container.bind(Container.Identifiers.Application).toConstantValue(application); | ||
container.bind(Container.Identifiers.BlockchainService).toConstantValue(blockchain); | ||
}); | ||
|
||
beforeEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
describe("execute", () => { | ||
it("should call blockchain.resetLastDownloadedBlock and return DiscardedButCanBeBroadcasted", async () => { | ||
const alreadyForgedHandler = container.resolve<AlreadyForgedHandler>(AlreadyForgedHandler); | ||
|
||
const block = {}; | ||
const result = await alreadyForgedHandler.execute(block as Interfaces.IBlock); | ||
|
||
expect(result).toBe(BlockProcessorResult.DiscardedButCanBeBroadcasted); | ||
expect(blockchain.resetLastDownloadedBlock).toBeCalledTimes(1); | ||
}) | ||
}) | ||
}) |
58 changes: 58 additions & 0 deletions
58
__tests__/unit/core-blockchain/processor/handlers/exception-handler.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { Container } from "@arkecosystem/core-kernel"; | ||
import { ExceptionHandler } from "../../../../../packages/core-blockchain/src/processor/handlers/exception-handler"; | ||
import { AcceptBlockHandler } from "../../../../../packages/core-blockchain/src/processor/handlers/accept-block-handler"; | ||
import { BlockProcessorResult } from "../../../../../packages/core-blockchain/src/processor"; | ||
import { Interfaces } from "@arkecosystem/crypto"; | ||
|
||
describe("ExceptionHandler", () => { | ||
const container = new Container.Container(); | ||
|
||
const logger = { warning: jest.fn(), debug: jest.fn(), info: jest.fn() }; | ||
const blockchain = { resetLastDownloadedBlock: jest.fn() }; | ||
const database = { getBlock: jest.fn() }; | ||
|
||
const application = { resolve: jest.fn() }; | ||
|
||
beforeAll(() => { | ||
container.unbindAll(); | ||
container.bind(Container.Identifiers.Application).toConstantValue(application); | ||
container.bind(Container.Identifiers.BlockchainService).toConstantValue(blockchain); | ||
container.bind(Container.Identifiers.LogService).toConstantValue(logger); | ||
container.bind(Container.Identifiers.DatabaseService).toConstantValue(database); | ||
}); | ||
|
||
beforeEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
describe("execute", () => { | ||
const block = { data: { id: "123", height: 4445 } }; | ||
|
||
it("should return Rejected and resetLastDownloadedBlock when block already forged", async () => { | ||
const exceptionHandler = container.resolve<ExceptionHandler>(ExceptionHandler); | ||
|
||
database.getBlock = jest.fn().mockResolvedValueOnce(block); | ||
const result = await exceptionHandler.execute(block as Interfaces.IBlock); | ||
|
||
expect(result).toBe(BlockProcessorResult.Rejected); | ||
|
||
expect(blockchain.resetLastDownloadedBlock).toBeCalledTimes(1); | ||
}) | ||
|
||
it("should call AcceptHandler when block not already forged", async () => { | ||
const exceptionHandler = container.resolve<ExceptionHandler>(ExceptionHandler); | ||
|
||
const mockAcceptHandler = { | ||
execute: () => BlockProcessorResult.Accepted | ||
}; | ||
application.resolve = jest.fn().mockReturnValue(mockAcceptHandler); | ||
|
||
const result = await exceptionHandler.execute(block as Interfaces.IBlock); | ||
|
||
expect(result).toBe(BlockProcessorResult.Accepted); | ||
|
||
expect(application.resolve).toBeCalledTimes(1); | ||
expect(application.resolve).toBeCalledWith(AcceptBlockHandler); | ||
}) | ||
}) | ||
}) |
34 changes: 34 additions & 0 deletions
34
__tests__/unit/core-blockchain/processor/handlers/incompatible-transactions-handler.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Container } from "@arkecosystem/core-kernel"; | ||
import { IncompatibleTransactionsHandler } from "../../../../../packages/core-blockchain/src/processor/handlers/incompatible-transactions-handler"; | ||
import { BlockProcessorResult } from "../../../../../packages/core-blockchain/src/processor"; | ||
import { Interfaces } from "@arkecosystem/crypto"; | ||
|
||
describe("IncompatibleTransactionsHandler", () => { | ||
const container = new Container.Container(); | ||
|
||
const blockchain = { resetLastDownloadedBlock: jest.fn() }; | ||
|
||
const application = { get: jest.fn() }; | ||
|
||
beforeAll(() => { | ||
container.unbindAll(); | ||
container.bind(Container.Identifiers.Application).toConstantValue(application); | ||
container.bind(Container.Identifiers.BlockchainService).toConstantValue(blockchain); | ||
}); | ||
|
||
beforeEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
describe("execute", () => { | ||
it("should call blockchain.resetLastDownloadedBlock and return DiscardedButCanBeBroadcasted", async () => { | ||
const incompatibleTransactionsHandler = container.resolve<IncompatibleTransactionsHandler>(IncompatibleTransactionsHandler); | ||
|
||
const block = {}; | ||
const result = await incompatibleTransactionsHandler.execute(block as Interfaces.IBlock); | ||
|
||
expect(result).toBe(BlockProcessorResult.Rejected); | ||
expect(blockchain.resetLastDownloadedBlock).toBeCalledTimes(1); | ||
}) | ||
}) | ||
}) |
34 changes: 34 additions & 0 deletions
34
__tests__/unit/core-blockchain/processor/handlers/invalid-generator-handler.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Container } from "@arkecosystem/core-kernel"; | ||
import { InvalidGeneratorHandler } from "../../../../../packages/core-blockchain/src/processor/handlers/invalid-generator-handler"; | ||
import { BlockProcessorResult } from "../../../../../packages/core-blockchain/src/processor"; | ||
import { Interfaces } from "@arkecosystem/crypto"; | ||
|
||
describe("InvalidGeneratorHandler", () => { | ||
const container = new Container.Container(); | ||
|
||
const blockchain = { resetLastDownloadedBlock: jest.fn() }; | ||
|
||
const application = { get: jest.fn() }; | ||
|
||
beforeAll(() => { | ||
container.unbindAll(); | ||
container.bind(Container.Identifiers.Application).toConstantValue(application); | ||
container.bind(Container.Identifiers.BlockchainService).toConstantValue(blockchain); | ||
}); | ||
|
||
beforeEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
describe("execute", () => { | ||
it("should call blockchain.resetLastDownloadedBlock and return DiscardedButCanBeBroadcasted", async () => { | ||
const invalidGeneratorHandler = container.resolve<InvalidGeneratorHandler>(InvalidGeneratorHandler); | ||
|
||
const block = {}; | ||
const result = await invalidGeneratorHandler.execute(block as Interfaces.IBlock); | ||
|
||
expect(result).toBe(BlockProcessorResult.Rejected); | ||
expect(blockchain.resetLastDownloadedBlock).toBeCalledTimes(1); | ||
}) | ||
}) | ||
}) |
34 changes: 34 additions & 0 deletions
34
__tests__/unit/core-blockchain/processor/handlers/nonce-out-of-order-handler.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Container } from "@arkecosystem/core-kernel"; | ||
import { NonceOutOfOrderHandler } from "../../../../../packages/core-blockchain/src/processor/handlers/nonce-out-of-order-handler"; | ||
import { BlockProcessorResult } from "../../../../../packages/core-blockchain/src/processor"; | ||
import { Interfaces } from "@arkecosystem/crypto"; | ||
|
||
describe("NonceOutOfOrderHandler", () => { | ||
const container = new Container.Container(); | ||
|
||
const blockchain = { resetLastDownloadedBlock: jest.fn() }; | ||
|
||
const application = { get: jest.fn() }; | ||
|
||
beforeAll(() => { | ||
container.unbindAll(); | ||
container.bind(Container.Identifiers.Application).toConstantValue(application); | ||
container.bind(Container.Identifiers.BlockchainService).toConstantValue(blockchain); | ||
}); | ||
|
||
beforeEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
describe("execute", () => { | ||
it("should call blockchain.resetLastDownloadedBlock and return DiscardedButCanBeBroadcasted", async () => { | ||
const nonceOutOfOrderHandler = container.resolve<NonceOutOfOrderHandler>(NonceOutOfOrderHandler); | ||
|
||
const block = {}; | ||
const result = await nonceOutOfOrderHandler.execute(block as Interfaces.IBlock); | ||
|
||
expect(result).toBe(BlockProcessorResult.Rejected); | ||
expect(blockchain.resetLastDownloadedBlock).toBeCalledTimes(1); | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.