func TestVerifyChain(t *testing.T) { ledgerTestWrapper := createFreshDBAndTestLedgerWrapper(t) ledger := ledgerTestWrapper.ledger // Build a big blockchain for i := 0; i < 100; i++ { ledger.BeginTxBatch(i) ledger.TxBegin("txUuid" + strconv.Itoa(i)) ledger.SetState("chaincode"+strconv.Itoa(i), "key"+strconv.Itoa(i), []byte("value"+strconv.Itoa(i))) ledger.TxFinished("txUuid"+strconv.Itoa(i), true) transaction, _ := buildTestTx(t) ledger.CommitTxBatch(i, []*protos.Transaction{transaction}, nil, []byte("proof")) } // Verify the chain for lowBlock := uint64(0); lowBlock < ledger.GetBlockchainSize()-1; lowBlock++ { testutil.AssertEquals(t, ledgerTestWrapper.VerifyChain(ledger.GetBlockchainSize()-1, lowBlock), lowBlock) } for highBlock := ledger.GetBlockchainSize() - 1; highBlock > 0; highBlock-- { testutil.AssertEquals(t, ledgerTestWrapper.VerifyChain(highBlock, 0), uint64(0)) } // Add bad blocks and test badBlock := protos.NewBlock(nil, nil) badBlock.PreviousBlockHash = []byte("evil") for i := uint64(0); i < ledger.GetBlockchainSize(); i++ { goodBlock := ledgerTestWrapper.GetBlockByNumber(i) ledger.PutRawBlock(badBlock, i) for lowBlock := uint64(0); lowBlock < ledger.GetBlockchainSize()-1; lowBlock++ { if i == ledger.GetBlockchainSize()-1 { testutil.AssertEquals(t, ledgerTestWrapper.VerifyChain(ledger.GetBlockchainSize()-1, lowBlock), uint64(i)) } else if i >= lowBlock { testutil.AssertEquals(t, ledgerTestWrapper.VerifyChain(ledger.GetBlockchainSize()-1, lowBlock), uint64(i+1)) } else { testutil.AssertEquals(t, ledgerTestWrapper.VerifyChain(ledger.GetBlockchainSize()-1, lowBlock), lowBlock) } } for highBlock := ledger.GetBlockchainSize() - 1; highBlock != ^uint64(0); highBlock-- { if i == highBlock { testutil.AssertEquals(t, ledgerTestWrapper.VerifyChain(highBlock, 0), uint64(i)) } else if i < highBlock { testutil.AssertEquals(t, ledgerTestWrapper.VerifyChain(highBlock, 0), uint64(i+1)) } else { testutil.AssertEquals(t, ledgerTestWrapper.VerifyChain(highBlock, 0), uint64(0)) } } ledgerTestWrapper.PutRawBlock(goodBlock, i) } // Test edge cases _, err := ledger.VerifyChain(2, 10) testutil.AssertError(t, err, "Expected error as high block is less than low block") _, err = ledger.VerifyChain(0, 100) testutil.AssertError(t, err, "Expected error as high block is out of bounds") }
func TestInvalidOrderDelta(t *testing.T) { ledgerTestWrapper := createFreshDBAndTestLedgerWrapper(t) ledger := ledgerTestWrapper.ledger // Block 0 ledger.BeginTxBatch(0) ledger.TxBegin("txUuid1") ledger.SetState("chaincode1", "key1", []byte("value1A")) ledger.SetState("chaincode2", "key2", []byte("value2A")) ledger.SetState("chaincode3", "key3", []byte("value3A")) ledger.TxFinished("txUuid1", true) transaction, _ := buildTestTx(t) ledger.CommitTxBatch(0, []*protos.Transaction{transaction}, nil, []byte("proof")) testutil.AssertEquals(t, ledgerTestWrapper.GetState("chaincode1", "key1", true), []byte("value1A")) testutil.AssertEquals(t, ledgerTestWrapper.GetState("chaincode2", "key2", true), []byte("value2A")) testutil.AssertEquals(t, ledgerTestWrapper.GetState("chaincode3", "key3", true), []byte("value3A")) // Block 1 ledger.BeginTxBatch(1) ledger.TxBegin("txUuid1") ledger.SetState("chaincode1", "key1", []byte("value1B")) ledger.SetState("chaincode2", "key2", []byte("value2B")) ledger.SetState("chaincode3", "key3", []byte("value3B")) ledger.TxFinished("txUuid1", true) transaction, _ = buildTestTx(t) ledger.CommitTxBatch(1, []*protos.Transaction{transaction}, nil, []byte("proof")) testutil.AssertEquals(t, ledgerTestWrapper.GetState("chaincode1", "key1", true), []byte("value1B")) testutil.AssertEquals(t, ledgerTestWrapper.GetState("chaincode2", "key2", true), []byte("value2B")) testutil.AssertEquals(t, ledgerTestWrapper.GetState("chaincode3", "key3", true), []byte("value3B")) delta := ledgerTestWrapper.GetStateDelta(1) err := ledger.CommitStateDelta(1) testutil.AssertError(t, err, "Expected error commiting delta") err = ledger.RollbackTxBatch(1) testutil.AssertError(t, err, "Expected error rolling back delta") ledgerTestWrapper.ApplyStateDelta(2, delta) err = ledger.ApplyStateDelta(3, delta) testutil.AssertError(t, err, "Expected error applying delta") err = ledger.CommitStateDelta(3) testutil.AssertError(t, err, "Expected error applying delta") err = ledger.RollbackStateDelta(3) testutil.AssertError(t, err, "Expected error applying delta") }
func TestDBBadConnectionDef(t *testing.T) { //create a new connection _, err := CreateConnectionDefinition("^^^localhost:5984", "database", "", "") testutil.AssertError(t, err, fmt.Sprintf("Did not receive error when trying to create database connection definition with a bad hostname")) }
func TestDBBadJSON(t *testing.T) { if ledgerconfig.IsCouchDBEnabled() == true { cleanup() defer cleanup() //create a new connection db, err := CreateConnectionDefinition(connectURL, database, username, password) testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create database connection definition")) //create a new database _, errdb := db.CreateDatabaseIfNotExist() testutil.AssertNoError(t, errdb, fmt.Sprintf("Error when trying to create database")) //Retrieve the info for the new database and make sure the name matches dbResp, _, errdb := db.GetDatabaseInfo() testutil.AssertNoError(t, errdb, fmt.Sprintf("Error when trying to retrieve database information")) testutil.AssertEquals(t, dbResp.DbName, database) badJSON := []byte(`{"asset_name"}`) //Save the test document _, saveerr := db.SaveDoc("1", "", badJSON, nil) testutil.AssertError(t, saveerr, fmt.Sprintf("Error should have been thrown for a bad JSON")) } }
func TestLedgerDifferentID(t *testing.T) { ledgerTestWrapper := createFreshDBAndTestLedgerWrapper(t) ledger := ledgerTestWrapper.ledger ledger.BeginTxBatch(1) ledger.TxBegin("txUuid") ledger.SetState("chaincode1", "key1", []byte("value1")) ledger.SetState("chaincode2", "key2", []byte("value2")) ledger.SetState("chaincode3", "key3", []byte("value3")) ledger.TxFinished("txUuid", true) transaction, _ := buildTestTx(t) err := ledger.CommitTxBatch(2, []*protos.Transaction{transaction}, nil, []byte("prrof")) testutil.AssertError(t, err, "ledger should throw error for wrong batch ID") }
func TestDBBadConnection(t *testing.T) { if ledgerconfig.IsCouchDBEnabled() == true { //create a new connection db, err := CreateConnectionDefinition(badConnectURL, database, username, password) testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create database connection definition")) //create a new database _, errdb := db.CreateDatabaseIfNotExist() testutil.AssertError(t, errdb, fmt.Sprintf("Error should have been thrown while creating a database with an invalid connecion")) //Save the test document _, saveerr := db.SaveDoc("3", "", assetJSON, nil) testutil.AssertError(t, saveerr, fmt.Sprintf("Error should have been thrown while saving a document with an invalid connecion")) //Retrieve the updated test document _, _, geterr := db.ReadDoc("3") testutil.AssertError(t, geterr, fmt.Sprintf("Error should have been thrown while retrieving a document with an invalid connecion")) } }
func TestDBTestDropDatabaseBadConnection(t *testing.T) { if ledgerconfig.IsCouchDBEnabled() == true { cleanup() defer cleanup() //create a new connection db, err := CreateConnectionDefinition(badConnectURL, database, username, password) testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create database connection definition")) //Attempt to drop the database without creating first _, errdbdrop := db.DropDatabase() testutil.AssertError(t, errdbdrop, fmt.Sprintf("Error should have been reported for attempting to drop a database before creation")) } }
func TestDBRetrieveNonExistingDocument(t *testing.T) { if ledgerconfig.IsCouchDBEnabled() == true { cleanup() defer cleanup() //create a new connection db, err := CreateConnectionDefinition(connectURL, database, username, password) testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create database connection definition")) //create a new database _, errdb := db.CreateDatabaseIfNotExist() testutil.AssertNoError(t, errdb, fmt.Sprintf("Error when attempting to create a database")) //Attempt to retrieve the updated test document _, _, geterr2 := db.ReadDoc("2") testutil.AssertError(t, geterr2, fmt.Sprintf("Error should have been thrown while attempting to retrieve a nonexisting document")) } }
func TestDBCreateDatabaseAndPersist(t *testing.T) { if ledgerconfig.IsCouchDBEnabled() == true { cleanup() defer cleanup() //create a new connection db, err := CreateConnectionDefinition(connectURL, database, username, password) testutil.AssertNoError(t, err, fmt.Sprintf("Error when trying to create database connection definition")) //create a new database _, errdb := db.CreateDatabaseIfNotExist() testutil.AssertNoError(t, errdb, fmt.Sprintf("Error when trying to create database")) //Retrieve the info for the new database and make sure the name matches dbResp, _, errdb := db.GetDatabaseInfo() testutil.AssertNoError(t, errdb, fmt.Sprintf("Error when trying to retrieve database information")) testutil.AssertEquals(t, dbResp.DbName, database) //Save the test document _, saveerr := db.SaveDoc("1", "", assetJSON, nil) testutil.AssertNoError(t, saveerr, fmt.Sprintf("Error when trying to save a document")) //Retrieve the test document dbGetResp, _, geterr := db.ReadDoc("1") testutil.AssertNoError(t, geterr, fmt.Sprintf("Error when trying to retrieve a document")) //Unmarshal the document to Asset structure assetResp := &Asset{} json.Unmarshal(dbGetResp, &assetResp) //Verify the owner retrieved matches testutil.AssertEquals(t, assetResp.Owner, "jerry") //Change owner to bob assetResp.Owner = "bob" //create a byte array of the JSON assetDocUpdated, _ := json.Marshal(assetResp) //Save the updated test document _, saveerr = db.SaveDoc("1", "", assetDocUpdated, nil) testutil.AssertNoError(t, saveerr, fmt.Sprintf("Error when trying to save the updated document")) //Retrieve the updated test document dbGetResp, _, geterr = db.ReadDoc("1") testutil.AssertNoError(t, geterr, fmt.Sprintf("Error when trying to retrieve a document")) //Unmarshal the document to Asset structure assetResp = &Asset{} json.Unmarshal(dbGetResp, &assetResp) //Assert that the update was saved and retrieved testutil.AssertEquals(t, assetResp.Owner, "bob") //Drop the database _, errdbdrop := db.DropDatabase() testutil.AssertNoError(t, errdbdrop, fmt.Sprintf("Error dropping database")) //Retrieve the info for the new database and make sure the name matches _, _, errdbinfo := db.GetDatabaseInfo() testutil.AssertError(t, errdbinfo, fmt.Sprintf("Error should have been thrown for missing database")) } }