Browse Source

server: Complete fixing the tests after schema changes (#35)

It is very likely that this change has fixed #15.
prometheus-integration
Alexis Hernandez 7 years ago
parent
commit
9759bc4bb9
  1. 5
      server/app/com/xsn/explorer/data/anorm/DatabasePostgresSeeder.scala
  2. 217
      server/test/com/xsn/explorer/processors/BlockEventsProcessorSpec.scala

5
server/app/com/xsn/explorer/data/anorm/DatabasePostgresSeeder.scala

@ -81,13 +81,12 @@ class DatabasePostgresSeeder @Inject() (
} }
private def deleteBlockCascade(block: Block)(implicit conn: Connection): Option[Unit] = { private def deleteBlockCascade(block: Block)(implicit conn: Connection): Option[Unit] = {
// transactions
val deletedTransactions = transactionPostgresDAO.deleteBy(block.hash)
for { for {
// block // block
_ <- blockPostgresDAO.delete(block.hash) _ <- blockPostgresDAO.delete(block.hash)
// transactions
deletedTransactions = transactionPostgresDAO.deleteBy(block.hash)
// balances // balances
_ <- balances(deletedTransactions) _ <- balances(deletedTransactions)
.map { b => b.copy(spent = -b.spent, received = -b.received) } .map { b => b.copy(spent = -b.spent, received = -b.received) }

217
server/test/com/xsn/explorer/processors/BlockEventsProcessorSpec.scala

@ -30,99 +30,86 @@ class BlockEventsProcessorSpec extends PostgresDataHandlerSpec with ScalaFutures
new TransactionPostgresDAO(new FieldOrderingSQLInterpreter)) new TransactionPostgresDAO(new FieldOrderingSQLInterpreter))
lazy val xsnService = new FileBasedXSNService lazy val xsnService = new FileBasedXSNService
lazy val processor = blockEventsProcessor() lazy val processor = blockEventsProcessor(xsnService)
val blockList = List(
BlockLoader.get("00000c822abdbb23e28f79a49d29b41429737c6c7e15df40d1b1f1b35907ae34"),
BlockLoader.get("000003fb382f6892ae96594b81aa916a8923c70701de4e7054aac556c7271ef7"),
BlockLoader.get("000004645e2717b556682e3c642a4c6e473bf25c653ff8e8c114a3006040ffb8"),
BlockLoader.get("00000766115b26ecbc09cd3a3db6870fdaf2f049d65a910eb2f2b48b566ca7bd")
)
before { before {
clearDatabase() clearDatabase()
} }
"newLatestBlock" should { "newLatestBlock" should {
"fail on genesis block due to the missing transaction" in { "process genesis block" in {
// see https://github.com/X9Developers/XSN/issues/32 val block = blockList.head
val block0 = BlockLoader.get("00000c822abdbb23e28f79a49d29b41429737c6c7e15df40d1b1f1b35907ae34") whenReady(processor.processBlock(block.hash)) { result =>
result mustEqual Good(FirstBlockCreated(block))
whenReady(processor.processBlock(block0.hash)) { result =>
result mustEqual Good(MissingBlockIgnored)
}
}
"process first block" in {
val block1 = BlockLoader.get("000003fb382f6892ae96594b81aa916a8923c70701de4e7054aac556c7271ef7")
whenReady(processor.processBlock(block1.hash)) { result =>
result.isGood mustEqual true
} }
} }
"process a new block" in { "process a new block" in {
val block1 = BlockLoader.get("000003fb382f6892ae96594b81aa916a8923c70701de4e7054aac556c7271ef7") val block0 = blockList(0)
val block2 = BlockLoader.get("000004645e2717b556682e3c642a4c6e473bf25c653ff8e8c114a3006040ffb8") val block1 = blockList(1)
val block3 = BlockLoader.get("00000766115b26ecbc09cd3a3db6870fdaf2f049d65a910eb2f2b48b566ca7bd") val block2 = blockList(2)
List(block1, block2).map(dataHandler.insert).foreach(_.isGood mustEqual true) createBlocks(processor, block0, block1)
whenReady(processor.processBlock(block3.hash)) { result => whenReady(processor.processBlock(block2.hash)) { result =>
result mustEqual Good(NewBlockAppended(block3)) result mustEqual Good(NewBlockAppended(block2))
val blocks = List(block1, block2, block3) val blocks = List(block0, block1, block2)
verifyBlockchain(blocks) verifyBlockchain(blocks)
} }
} }
"process a rechain" in { "process a rechain" in {
val block1 = BlockLoader.get("000003fb382f6892ae96594b81aa916a8923c70701de4e7054aac556c7271ef7") val block0 = blockList(0)
val block2 = BlockLoader.get("000004645e2717b556682e3c642a4c6e473bf25c653ff8e8c114a3006040ffb8") val block1 = blockList(1)
val block3 = BlockLoader.get("00000766115b26ecbc09cd3a3db6870fdaf2f049d65a910eb2f2b48b566ca7bd") val block2 = blockList(2)
List(block1, block2, block3).map(dataHandler.insert).foreach(_.isGood mustEqual true) createBlocks(processor, block0, block1, block2)
whenReady(processor.processBlock(block2.hash)) { whenReady(processor.processBlock(block1.hash)) {
case Good(RechainDone(orphanBlock, newBlock)) => case Good(RechainDone(orphanBlock, newBlock)) =>
orphanBlock.hash mustEqual block3.hash orphanBlock.hash mustEqual block2.hash
newBlock.hash mustEqual block2.hash newBlock.hash mustEqual block1.hash
val blocks = List(block1, block2) val blocks = List(block0, block1)
verifyBlockchain(blocks) verifyBlockchain(blocks)
case _ => fail() case e => fail()
} }
} }
"process a missing block" in { "process a repeated block without affecting the balances" in {
val block1 = BlockLoader.get("000003fb382f6892ae96594b81aa916a8923c70701de4e7054aac556c7271ef7") val block0 = blockList(0)
val block2 = BlockLoader.get("000004645e2717b556682e3c642a4c6e473bf25c653ff8e8c114a3006040ffb8") val block1 = blockList(1)
val block3 = BlockLoader.get("00000766115b26ecbc09cd3a3db6870fdaf2f049d65a910eb2f2b48b566ca7bd") val block2 = blockList(2)
List(block2, block3).map(dataHandler.insert).foreach(_.isGood mustEqual true) createBlocks(processor, block0, block1, block2)
whenReady(processor.processBlock(block1.hash)) { result => val statsDataHandler = new StatisticsPostgresDataHandler(database, new StatisticsPostgresDAO)
result.isGood mustEqual true val expectedStats = statsDataHandler.getStatistics().get
val blocks = List(block1, block2, block3)
verifyBlockchain(blocks)
}
}
"processing a repeated missing block doesn't affect the balance" in {
val block1 = BlockLoader.get("000003fb382f6892ae96594b81aa916a8923c70701de4e7054aac556c7271ef7")
val block2 = BlockLoader.get("000004645e2717b556682e3c642a4c6e473bf25c653ff8e8c114a3006040ffb8")
val block3 = BlockLoader.get("00000766115b26ecbc09cd3a3db6870fdaf2f049d65a910eb2f2b48b566ca7bd")
List(block1, block2, block3).map(dataHandler.insert).foreach(_.isGood mustEqual true)
whenReady(processor.processBlock(block1.hash)) { result => whenReady(processor.processBlock(block0.hash)) { result =>
result.isGood mustEqual true result.isGood mustEqual true
val blocks = List(block1, block2, block3) val blocks = List(block0, block1, block2)
verifyBlockchain(blocks) verifyBlockchain(blocks)
val statsDataHandler = new StatisticsPostgresDataHandler(database, new StatisticsPostgresDAO)
val stats = statsDataHandler.getStatistics().get val stats = statsDataHandler.getStatistics().get
stats.totalSupply.isEmpty mustEqual true stats.totalSupply mustEqual expectedStats.totalSupply
stats.circulatingSupply.isEmpty mustEqual true stats.circulatingSupply mustEqual expectedStats.circulatingSupply
} }
} }
"process a block without spent index on transactions" in { "process a block without spent index on transactions" in {
val block = BlockLoader.get("000001ff95f22b8d82db14a5c5e9f725e8239e548be43c668766e7ddaee81924") val block = BlockLoader.get("000001ff95f22b8d82db14a5c5e9f725e8239e548be43c668766e7ddaee81924")
.copy(previousBlockhash = None)
val processor = blockEventsProcessor(block)
whenReady(processor.processBlock(block.hash)) { result => whenReady(processor.processBlock(block.hash)) { result =>
result.isGood mustEqual true result.isGood mustEqual true
@ -140,17 +127,15 @@ class BlockEventsProcessorSpec extends PostgresDataHandlerSpec with ScalaFutures
} }
"process a rechain without corrupting the balances table" in { "process a rechain without corrupting the balances table" in {
val block1 = BlockLoader.get("000003fb382f6892ae96594b81aa916a8923c70701de4e7054aac556c7271ef7") val block0 = blockList(0)
val block2 = BlockLoader.get("000004645e2717b556682e3c642a4c6e473bf25c653ff8e8c114a3006040ffb8") val block1 = blockList(1)
val block2 = blockList(2)
List(block1, block2) createBlocks(processor, block0, block1, block2)
.map(_.hash)
.map(processor.processBlock)
.foreach { whenReady(_) { _.isGood mustEqual true } }
whenReady(processor.processBlock(block1.hash)) { result => whenReady(processor.processBlock(block1.hash)) { result =>
result.isGood mustEqual true result.isGood mustEqual true
val blocks = List(block1) val blocks = List(block0, block1)
verifyBlockchain(blocks) verifyBlockchain(blocks)
val balanceDataHandler = new BalancePostgresDataHandler(database, new BalancePostgresDAO(new FieldOrderingSQLInterpreter)) val balanceDataHandler = new BalancePostgresDataHandler(database, new BalancePostgresDAO(new FieldOrderingSQLInterpreter))
@ -169,12 +154,12 @@ class BlockEventsProcessorSpec extends PostgresDataHandlerSpec with ScalaFutures
} }
} }
// TODO: failed once on travis, might not be stable
"ignore orphan block on rare rechain events when the rpc server doesn't have the block anymore" in { "ignore orphan block on rare rechain events when the rpc server doesn't have the block anymore" in {
// see https://github.com/X9Developers/block-explorer/issues/6 // see https://github.com/X9Developers/block-explorer/issues/6
val block1 = BlockLoader.get("000003fb382f6892ae96594b81aa916a8923c70701de4e7054aac556c7271ef7") val block0 = blockList(0)
val block2 = BlockLoader.get("000004645e2717b556682e3c642a4c6e473bf25c653ff8e8c114a3006040ffb8") val block1 = blockList(1)
val block3 = BlockLoader.get("00000766115b26ecbc09cd3a3db6870fdaf2f049d65a910eb2f2b48b566ca7bd") val block2 = blockList(2)
val block3 = blockList(3)
val xsnService = new FileBasedXSNService { val xsnService = new FileBasedXSNService {
override def getBlock(blockhash: Blockhash): FutureApplicationResult[Block] = { override def getBlock(blockhash: Blockhash): FutureApplicationResult[Block] = {
@ -187,11 +172,8 @@ class BlockEventsProcessorSpec extends PostgresDataHandlerSpec with ScalaFutures
} }
val processor = blockEventsProcessor(xsn = xsnService) val processor = blockEventsProcessor(xsn = xsnService)
List(block1, block2) createBlocks(processor, block0, block1, block2)
.map(_.hash)
.map(processor.processBlock)
.foreach { whenReady(_) { _.isGood mustEqual true } }
/** /**
* When processing the latest block, a rechain event has occurred in the rpc server which leads to * When processing the latest block, a rechain event has occurred in the rpc server which leads to
@ -199,16 +181,17 @@ class BlockEventsProcessorSpec extends PostgresDataHandlerSpec with ScalaFutures
*/ */
whenReady(processor.processBlock(block3.hash)) { result => whenReady(processor.processBlock(block3.hash)) { result =>
result mustEqual Good(MissingBlockIgnored) result mustEqual Good(MissingBlockIgnored)
val blocks = List(block1, block2) val blocks = List(block0, block1, block2)
verifyBlockchain(blocks) verifyBlockchain(blocks)
} }
} }
"ignore orphan block on rare rechain events when the rpc server doesn't have the a transaction from the block anymore" in { "ignore orphan block on rare rechain events when the rpc server doesn't have the a transaction from the block anymore" in {
// see https://github.com/X9Developers/block-explorer/issues/6 // see https://github.com/X9Developers/block-explorer/issues/6
val block1 = BlockLoader.get("000003fb382f6892ae96594b81aa916a8923c70701de4e7054aac556c7271ef7") val block0 = blockList(0)
val block2 = BlockLoader.get("000004645e2717b556682e3c642a4c6e473bf25c653ff8e8c114a3006040ffb8") val block1 = blockList(1)
val block3 = BlockLoader.get("00000766115b26ecbc09cd3a3db6870fdaf2f049d65a910eb2f2b48b566ca7bd") val block2 = blockList(2)
val block3 = blockList(3)
val xsnService = new FileBasedXSNService { val xsnService = new FileBasedXSNService {
override def getTransaction(txid: TransactionId): FutureApplicationResult[Transaction] = { override def getTransaction(txid: TransactionId): FutureApplicationResult[Transaction] = {
@ -222,10 +205,7 @@ class BlockEventsProcessorSpec extends PostgresDataHandlerSpec with ScalaFutures
val processor = blockEventsProcessor(xsn = xsnService) val processor = blockEventsProcessor(xsn = xsnService)
List(block1, block2) createBlocks(processor, block0, block1, block2)
.map(_.hash)
.map(processor.processBlock)
.foreach { whenReady(_) { _.isGood mustEqual true } }
/** /**
* When processing the latest block, a rechain event has occurred in the rpc server which leads to * When processing the latest block, a rechain event has occurred in the rpc server which leads to
@ -233,39 +213,27 @@ class BlockEventsProcessorSpec extends PostgresDataHandlerSpec with ScalaFutures
*/ */
whenReady(processor.processBlock(block3.hash)) { result => whenReady(processor.processBlock(block3.hash)) { result =>
result mustEqual Good(MissingBlockIgnored) result mustEqual Good(MissingBlockIgnored)
val blocks = List(block1, block2) val blocks = List(block0, block1, block2)
verifyBlockchain(blocks) verifyBlockchain(blocks)
} }
} }
"remove orphan block on rare rechain events when the block height already exists" in { "remove orphan block on rare rechain events when the block height already exists" in {
// see https://github.com/X9Developers/block-explorer/issues/6 // see https://github.com/X9Developers/block-explorer/issues/6
val block1 = BlockLoader.get("000003fb382f6892ae96594b81aa916a8923c70701de4e7054aac556c7271ef7") val block0 = blockList(0)
val block2 = BlockLoader.get("000004645e2717b556682e3c642a4c6e473bf25c653ff8e8c114a3006040ffb8") val block1 = blockList(1)
val block3 = BlockLoader.get("00000766115b26ecbc09cd3a3db6870fdaf2f049d65a910eb2f2b48b566ca7bd") val block2 = blockList(2)
val block3 = blockList(3)
.copy(height = block2.height) .copy(height = block2.height)
.copy(previousBlockhash = block2.previousBlockhash) .copy(previousBlockhash = block2.previousBlockhash)
val xsnService = new FileBasedXSNService { val processor = blockEventsProcessor(block3)
override def getBlock(blockhash: Blockhash): FutureApplicationResult[Block] = {
if (blockhash == block3.hash) {
Future.successful(Good(block3))
} else {
super.getBlock(blockhash)
}
}
}
val processor = blockEventsProcessor(xsn = xsnService)
List(block1, block2) createBlocks(processor, block0, block1, block2)
.map(_.hash)
.map(processor.processBlock)
.foreach { whenReady(_) { _.isGood mustEqual true } }
whenReady(processor.processBlock(block3.hash)) { result => whenReady(processor.processBlock(block3.hash)) { result =>
result mustEqual Good(ReplacedByBlockHeight(block3)) result mustEqual Good(ReplacedByBlockHeight(block3))
val blocks = List(block1.copy(nextBlockhash = Some(block3.hash)), block3) val blocks = List(block0, block1.copy(nextBlockhash = Some(block3.hash)), block3)
verifyBlockchain(blocks) verifyBlockchain(blocks)
// ensure block2 has been removed // ensure block2 has been removed
@ -275,31 +243,19 @@ class BlockEventsProcessorSpec extends PostgresDataHandlerSpec with ScalaFutures
"keep the correct previous_blockhash on rare events" in { "keep the correct previous_blockhash on rare events" in {
// see https://github.com/X9Developers/block-explorer/issues/12 // see https://github.com/X9Developers/block-explorer/issues/12
val block1 = BlockLoader.get("000003fb382f6892ae96594b81aa916a8923c70701de4e7054aac556c7271ef7") val block0 = blockList(0)
val block2 = BlockLoader.get("000004645e2717b556682e3c642a4c6e473bf25c653ff8e8c114a3006040ffb8") val block1 = blockList(1)
val block3 = BlockLoader.get("00000766115b26ecbc09cd3a3db6870fdaf2f049d65a910eb2f2b48b566ca7bd") val block2 = blockList(2)
val rareBlock3 = block3.copy(previousBlockhash = Some(block1.hash)) val block3 = blockList(3)
val rareBlock3 = block3.copy(previousBlockhash = block2.previousBlockhash)
val xsnService = new FileBasedXSNService {
override def getBlock(blockhash: Blockhash): FutureApplicationResult[Block] = {
if (blockhash == block3.hash) {
Future.successful(Good(rareBlock3))
} else {
super.getBlock(blockhash)
}
}
}
val processor = blockEventsProcessor(xsn = xsnService) val processor = blockEventsProcessor(rareBlock3)
List(block1, rareBlock3) createBlocks(processor, block0, block1, rareBlock3)
.map(_.hash)
.map(processor.processBlock)
.foreach { whenReady(_) { _.isGood mustEqual true } }
whenReady(processor.processBlock(block2.hash)) { result => whenReady(processor.processBlock(block2.hash)) { result =>
result mustEqual Good(MissingBlockProcessed(block2)) result mustEqual Good(MissingBlockProcessed(block2))
val blocks = List(block1, block2, block3) val blocks = List(block0, block1, block2, block3)
verifyBlockchain(blocks) verifyBlockchain(blocks)
} }
} }
@ -320,7 +276,30 @@ class BlockEventsProcessorSpec extends PostgresDataHandlerSpec with ScalaFutures
} }
} }
private def blockEventsProcessor(xsn: XSNService = xsnService) = { private def createBlocks(processor: BlockEventsProcessor, blocks: Block*) = {
blocks
.map(_.hash)
.foreach { block =>
whenReady(processor.processBlock(block)) { result =>
result.isGood mustEqual true
}
}
}
private def blockEventsProcessor(blocks: Block*): BlockEventsProcessor = {
val xsn = new FileBasedXSNService {
override def getBlock(blockhash: Blockhash): FutureApplicationResult[Block] = {
blocks
.find(_.hash == blockhash)
.map { block => Future.successful(Good(block)) }
.getOrElse(super.getBlock(blockhash))
}
}
blockEventsProcessor(xsn)
}
private def blockEventsProcessor(xsn: XSNService): BlockEventsProcessor = {
val dataSeeder = new DatabasePostgresSeeder( val dataSeeder = new DatabasePostgresSeeder(
database, database,
new BlockPostgresDAO, new BlockPostgresDAO,

Loading…
Cancel
Save