github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/core/ledger/kvledger/txmgmt/txmgr/lockbasedtxmgr/txmgr_test.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package lockbasedtxmgr 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "testing" 23 24 "os" 25 26 "github.com/hyperledger/fabric/common/flogging" 27 "github.com/hyperledger/fabric/common/ledger/testutil" 28 "github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/version" 29 ledgertestutil "github.com/hyperledger/fabric/core/ledger/testutil" 30 "github.com/hyperledger/fabric/protos/ledger/queryresult" 31 ) 32 33 func TestMain(m *testing.M) { 34 ledgertestutil.SetupCoreYAMLConfig() 35 flogging.SetModuleLevel("lockbasedtxmgr", "debug") 36 37 os.Exit(m.Run()) 38 } 39 40 func TestTxSimulatorWithNoExistingData(t *testing.T) { 41 // run the tests for each environment configured in pkg_test.go 42 for _, testEnv := range testEnvs { 43 t.Logf("Running test for TestEnv = %s", testEnv.getName()) 44 testLedgerID := "testtxsimulatorwithnoexistingdata" 45 testEnv.init(t, testLedgerID) 46 testTxSimulatorWithNoExistingData(t, testEnv) 47 testEnv.cleanup() 48 } 49 } 50 51 func testTxSimulatorWithNoExistingData(t *testing.T, env testEnv) { 52 txMgr := env.getTxMgr() 53 s, _ := txMgr.NewTxSimulator() 54 value, err := s.GetState("ns1", "key1") 55 testutil.AssertNoError(t, err, fmt.Sprintf("Error in GetState(): %s", err)) 56 testutil.AssertNil(t, value) 57 58 s.SetState("ns1", "key1", []byte("value1")) 59 s.SetState("ns1", "key2", []byte("value2")) 60 s.SetState("ns2", "key3", []byte("value3")) 61 s.SetState("ns2", "key4", []byte("value4")) 62 63 value, _ = s.GetState("ns2", "key3") 64 testutil.AssertNil(t, value) 65 } 66 67 func TestTxSimulatorWithExistingData(t *testing.T) { 68 for _, testEnv := range testEnvs { 69 t.Run(testEnv.getName(), func(t *testing.T) { 70 testLedgerID := "testtxsimulatorwithexistingdata" 71 testEnv.init(t, testLedgerID) 72 testTxSimulatorWithExistingData(t, testEnv) 73 testEnv.cleanup() 74 }) 75 } 76 } 77 78 func testTxSimulatorWithExistingData(t *testing.T, env testEnv) { 79 txMgr := env.getTxMgr() 80 txMgrHelper := newTxMgrTestHelper(t, txMgr) 81 // simulate tx1 82 s1, _ := txMgr.NewTxSimulator() 83 s1.SetState("ns1", "key1", []byte("value1")) 84 s1.SetState("ns1", "key2", []byte("value2")) 85 s1.SetState("ns2", "key3", []byte("value3")) 86 s1.SetState("ns2", "key4", []byte("value4")) 87 s1.Done() 88 // validate and commit RWset 89 txRWSet1, _ := s1.GetTxSimulationResults() 90 txMgrHelper.validateAndCommitRWSet(txRWSet1) 91 92 // simulate tx2 that make changes to existing data 93 s2, _ := txMgr.NewTxSimulator() 94 value, _ := s2.GetState("ns1", "key1") 95 testutil.AssertEquals(t, value, []byte("value1")) 96 s2.SetState("ns1", "key1", []byte("value1_1")) 97 s2.DeleteState("ns2", "key3") 98 value, _ = s2.GetState("ns1", "key1") 99 testutil.AssertEquals(t, value, []byte("value1")) 100 s2.Done() 101 // validate and commit RWset for tx2 102 txRWSet2, _ := s2.GetTxSimulationResults() 103 txMgrHelper.validateAndCommitRWSet(txRWSet2) 104 105 // simulate tx3 106 s3, _ := txMgr.NewTxSimulator() 107 value, _ = s3.GetState("ns1", "key1") 108 testutil.AssertEquals(t, value, []byte("value1_1")) 109 value, _ = s3.GetState("ns2", "key3") 110 testutil.AssertEquals(t, value, nil) 111 s3.Done() 112 113 // verify the versions of keys in persistence 114 vv, _ := env.getVDB().GetState("ns1", "key1") 115 testutil.AssertEquals(t, vv.Version, version.NewHeight(2, 0)) 116 vv, _ = env.getVDB().GetState("ns1", "key2") 117 testutil.AssertEquals(t, vv.Version, version.NewHeight(1, 0)) 118 } 119 120 func TestTxValidation(t *testing.T) { 121 for _, testEnv := range testEnvs { 122 t.Logf("Running test for TestEnv = %s", testEnv.getName()) 123 testLedgerID := "testtxvalidation" 124 testEnv.init(t, testLedgerID) 125 testTxValidation(t, testEnv) 126 testEnv.cleanup() 127 } 128 } 129 130 func testTxValidation(t *testing.T, env testEnv) { 131 txMgr := env.getTxMgr() 132 txMgrHelper := newTxMgrTestHelper(t, txMgr) 133 // simulate tx1 134 s1, _ := txMgr.NewTxSimulator() 135 s1.SetState("ns1", "key1", []byte("value1")) 136 s1.SetState("ns1", "key2", []byte("value2")) 137 s1.SetState("ns2", "key3", []byte("value3")) 138 s1.SetState("ns2", "key4", []byte("value4")) 139 s1.Done() 140 // validate and commit RWset 141 txRWSet1, _ := s1.GetTxSimulationResults() 142 txMgrHelper.validateAndCommitRWSet(txRWSet1) 143 144 // simulate tx2 that make changes to existing data. 145 // tx2: Read/Update ns1:key1, Delete ns2:key3. 146 s2, _ := txMgr.NewTxSimulator() 147 value, _ := s2.GetState("ns1", "key1") 148 testutil.AssertEquals(t, value, []byte("value1")) 149 150 s2.SetState("ns1", "key1", []byte("value1_2")) 151 s2.DeleteState("ns2", "key3") 152 s2.Done() 153 154 // simulate tx3 before committing tx2 changes. Reads and modifies the key changed by tx2. 155 // tx3: Read/Update ns1:key1 156 s3, _ := txMgr.NewTxSimulator() 157 s3.GetState("ns1", "key1") 158 s3.SetState("ns1", "key1", []byte("value1_3")) 159 s3.Done() 160 161 // simulate tx4 before committing tx2 changes. Reads and Deletes the key changed by tx2 162 // tx4: Read/Delete ns2:key3 163 s4, _ := txMgr.NewTxSimulator() 164 s4.GetState("ns2", "key3") 165 s4.DeleteState("ns2", "key3") 166 s4.Done() 167 168 // simulate tx5 before committing tx2 changes. Modifies and then Reads the key changed by tx2 and writes a new key 169 // tx5: Update/Read ns1:key1 170 s5, _ := txMgr.NewTxSimulator() 171 s5.SetState("ns1", "key1", []byte("new_value")) 172 s5.GetState("ns1", "key1") 173 s5.Done() 174 175 // simulate tx6 before committing tx2 changes. Only writes a new key, does not reads/writes a key changed by tx2 176 // tx6: Update ns1:new_key 177 s6, _ := txMgr.NewTxSimulator() 178 s6.SetState("ns1", "new_key", []byte("new_value")) 179 s6.Done() 180 181 // Summary of simulated transactions 182 // tx2: Read/Update ns1:key1, Delete ns2:key3. 183 // tx3: Read/Update ns1:key1 184 // tx4: Read/Delete ns2:key3 185 // tx5: Update/Read ns1:key1 186 // tx6: Update ns1:new_key 187 188 // validate and commit RWset for tx2 189 txRWSet2, _ := s2.GetTxSimulationResults() 190 txMgrHelper.validateAndCommitRWSet(txRWSet2) 191 192 //RWSet for tx3 and tx4 and tx5 should be invalid now due to read conflicts 193 txRWSet3, _ := s3.GetTxSimulationResults() 194 txMgrHelper.checkRWsetInvalid(txRWSet3) 195 196 txRWSet4, _ := s4.GetTxSimulationResults() 197 txMgrHelper.checkRWsetInvalid(txRWSet4) 198 199 txRWSet5, _ := s5.GetTxSimulationResults() 200 txMgrHelper.checkRWsetInvalid(txRWSet5) 201 202 // tx6 should still be valid as it only writes a new key 203 txRWSet6, _ := s6.GetTxSimulationResults() 204 txMgrHelper.validateAndCommitRWSet(txRWSet6) 205 } 206 207 func TestTxPhantomValidation(t *testing.T) { 208 for _, testEnv := range testEnvs { 209 t.Logf("Running test for TestEnv = %s", testEnv.getName()) 210 testLedgerID := "testtxphantomvalidation" 211 testEnv.init(t, testLedgerID) 212 testTxPhantomValidation(t, testEnv) 213 testEnv.cleanup() 214 } 215 } 216 217 func testTxPhantomValidation(t *testing.T, env testEnv) { 218 txMgr := env.getTxMgr() 219 txMgrHelper := newTxMgrTestHelper(t, txMgr) 220 // simulate tx1 221 s1, _ := txMgr.NewTxSimulator() 222 s1.SetState("ns", "key1", []byte("value1")) 223 s1.SetState("ns", "key2", []byte("value2")) 224 s1.SetState("ns", "key3", []byte("value3")) 225 s1.SetState("ns", "key4", []byte("value4")) 226 s1.SetState("ns", "key5", []byte("value5")) 227 s1.SetState("ns", "key6", []byte("value6")) 228 s1.Done() 229 // validate and commit RWset 230 txRWSet1, _ := s1.GetTxSimulationResults() 231 txMgrHelper.validateAndCommitRWSet(txRWSet1) 232 233 // simulate tx2 234 s2, _ := txMgr.NewTxSimulator() 235 itr2, _ := s2.GetStateRangeScanIterator("ns", "key2", "key5") 236 for { 237 if result, _ := itr2.Next(); result == nil { 238 break 239 } 240 } 241 s2.DeleteState("ns", "key3") 242 s2.Done() 243 txRWSet2, _ := s2.GetTxSimulationResults() 244 245 // simulate tx3 246 s3, _ := txMgr.NewTxSimulator() 247 itr3, _ := s3.GetStateRangeScanIterator("ns", "key2", "key5") 248 for { 249 if result, _ := itr3.Next(); result == nil { 250 break 251 } 252 } 253 s3.SetState("ns", "key3", []byte("value3_new")) 254 s3.Done() 255 txRWSet3, _ := s3.GetTxSimulationResults() 256 257 // simulate tx4 258 s4, _ := txMgr.NewTxSimulator() 259 itr4, _ := s4.GetStateRangeScanIterator("ns", "key4", "key6") 260 for { 261 if result, _ := itr4.Next(); result == nil { 262 break 263 } 264 } 265 s4.SetState("ns", "key3", []byte("value3_new")) 266 s4.Done() 267 txRWSet4, _ := s4.GetTxSimulationResults() 268 269 // txRWSet2 should be valid 270 txMgrHelper.validateAndCommitRWSet(txRWSet2) 271 // txRWSet2 makes txRWSet3 invalid as it deletes a key in the range 272 txMgrHelper.checkRWsetInvalid(txRWSet3) 273 // txRWSet4 should be valid as it iterates over a different range 274 txMgrHelper.validateAndCommitRWSet(txRWSet4) 275 } 276 277 func TestIterator(t *testing.T) { 278 for _, testEnv := range testEnvs { 279 t.Logf("Running test for TestEnv = %s", testEnv.getName()) 280 281 testLedgerID := "testiterator.1" 282 testEnv.init(t, testLedgerID) 283 testIterator(t, testEnv, 10, 2, 7) 284 testEnv.cleanup() 285 286 testLedgerID = "testiterator.2" 287 testEnv.init(t, testLedgerID) 288 testIterator(t, testEnv, 10, 1, 11) 289 testEnv.cleanup() 290 291 testLedgerID = "testiterator.3" 292 testEnv.init(t, testLedgerID) 293 testIterator(t, testEnv, 10, 0, 0) 294 testEnv.cleanup() 295 296 testLedgerID = "testiterator.4" 297 testEnv.init(t, testLedgerID) 298 testIterator(t, testEnv, 10, 5, 0) 299 testEnv.cleanup() 300 301 testLedgerID = "testiterator.5" 302 testEnv.init(t, testLedgerID) 303 testIterator(t, testEnv, 10, 0, 5) 304 testEnv.cleanup() 305 } 306 } 307 308 func testIterator(t *testing.T, env testEnv, numKeys int, startKeyNum int, endKeyNum int) { 309 cID := "cID" 310 txMgr := env.getTxMgr() 311 txMgrHelper := newTxMgrTestHelper(t, txMgr) 312 s, _ := txMgr.NewTxSimulator() 313 for i := 1; i <= numKeys; i++ { 314 k := createTestKey(i) 315 v := createTestValue(i) 316 t.Logf("Adding k=[%s], v=[%s]", k, v) 317 s.SetState(cID, k, v) 318 } 319 s.Done() 320 // validate and commit RWset 321 txRWSet, _ := s.GetTxSimulationResults() 322 txMgrHelper.validateAndCommitRWSet(txRWSet) 323 324 var startKey string 325 var endKey string 326 var begin int 327 var end int 328 329 if startKeyNum != 0 { 330 begin = startKeyNum 331 startKey = createTestKey(startKeyNum) 332 } else { 333 begin = 1 //first key in the db 334 startKey = "" 335 } 336 337 if endKeyNum != 0 { 338 endKey = createTestKey(endKeyNum) 339 end = endKeyNum 340 } else { 341 endKey = "" 342 end = numKeys + 1 //last key in the db 343 } 344 345 expectedCount := end - begin 346 347 queryExecuter, _ := txMgr.NewQueryExecutor() 348 itr, _ := queryExecuter.GetStateRangeScanIterator(cID, startKey, endKey) 349 count := 0 350 for { 351 kv, _ := itr.Next() 352 if kv == nil { 353 break 354 } 355 keyNum := begin + count 356 k := kv.(*queryresult.KV).Key 357 v := kv.(*queryresult.KV).Value 358 t.Logf("Retrieved k=%s, v=%s at count=%d start=%s end=%s", k, v, count, startKey, endKey) 359 testutil.AssertEquals(t, k, createTestKey(keyNum)) 360 testutil.AssertEquals(t, v, createTestValue(keyNum)) 361 count++ 362 } 363 testutil.AssertEquals(t, count, expectedCount) 364 } 365 366 func TestIteratorWithDeletes(t *testing.T) { 367 for _, testEnv := range testEnvs { 368 t.Logf("Running test for TestEnv = %s", testEnv.getName()) 369 testLedgerID := "testiteratorwithdeletes" 370 testEnv.init(t, testLedgerID) 371 testIteratorWithDeletes(t, testEnv) 372 testEnv.cleanup() 373 } 374 } 375 376 func testIteratorWithDeletes(t *testing.T, env testEnv) { 377 cID := "cID" 378 txMgr := env.getTxMgr() 379 txMgrHelper := newTxMgrTestHelper(t, txMgr) 380 s, _ := txMgr.NewTxSimulator() 381 for i := 1; i <= 10; i++ { 382 k := createTestKey(i) 383 v := createTestValue(i) 384 t.Logf("Adding k=[%s], v=[%s]", k, v) 385 s.SetState(cID, k, v) 386 } 387 s.Done() 388 // validate and commit RWset 389 txRWSet1, _ := s.GetTxSimulationResults() 390 txMgrHelper.validateAndCommitRWSet(txRWSet1) 391 392 s, _ = txMgr.NewTxSimulator() 393 s.DeleteState(cID, createTestKey(4)) 394 s.Done() 395 // validate and commit RWset 396 txRWSet2, _ := s.GetTxSimulationResults() 397 txMgrHelper.validateAndCommitRWSet(txRWSet2) 398 399 queryExecuter, _ := txMgr.NewQueryExecutor() 400 itr, _ := queryExecuter.GetStateRangeScanIterator(cID, createTestKey(3), createTestKey(6)) 401 defer itr.Close() 402 kv, _ := itr.Next() 403 testutil.AssertEquals(t, kv.(*queryresult.KV).Key, createTestKey(3)) 404 kv, _ = itr.Next() 405 testutil.AssertEquals(t, kv.(*queryresult.KV).Key, createTestKey(5)) 406 } 407 408 func TestTxValidationWithItr(t *testing.T) { 409 for _, testEnv := range testEnvs { 410 t.Logf("Running test for TestEnv = %s", testEnv.getName()) 411 testLedgerID := "testtxvalidationwithitr" 412 testEnv.init(t, testLedgerID) 413 testTxValidationWithItr(t, testEnv) 414 testEnv.cleanup() 415 } 416 } 417 418 func testTxValidationWithItr(t *testing.T, env testEnv) { 419 cID := "cID" 420 txMgr := env.getTxMgr() 421 txMgrHelper := newTxMgrTestHelper(t, txMgr) 422 423 // simulate tx1 424 s1, _ := txMgr.NewTxSimulator() 425 for i := 1; i <= 10; i++ { 426 k := createTestKey(i) 427 v := createTestValue(i) 428 t.Logf("Adding k=[%s], v=[%s]", k, v) 429 s1.SetState(cID, k, v) 430 } 431 s1.Done() 432 // validate and commit RWset 433 txRWSet1, _ := s1.GetTxSimulationResults() 434 txMgrHelper.validateAndCommitRWSet(txRWSet1) 435 436 // simulate tx2 that reads key_001 and key_002 437 s2, _ := txMgr.NewTxSimulator() 438 itr, _ := s2.GetStateRangeScanIterator(cID, createTestKey(1), createTestKey(5)) 439 // read key_001 and key_002 440 itr.Next() 441 itr.Next() 442 itr.Close() 443 s2.Done() 444 445 // simulate tx3 that reads key_004 and key_005 446 s3, _ := txMgr.NewTxSimulator() 447 itr, _ = s3.GetStateRangeScanIterator(cID, createTestKey(4), createTestKey(6)) 448 // read key_001 and key_002 449 itr.Next() 450 itr.Next() 451 itr.Close() 452 s3.Done() 453 454 // simulate tx4 before committing tx2 and tx3. Modifies a key read by tx3 455 s4, _ := txMgr.NewTxSimulator() 456 s4.DeleteState(cID, createTestKey(5)) 457 s4.Done() 458 459 // validate and commit RWset for tx4 460 txRWSet4, _ := s4.GetTxSimulationResults() 461 txMgrHelper.validateAndCommitRWSet(txRWSet4) 462 463 //RWSet tx3 should be invalid now 464 txRWSet3, _ := s3.GetTxSimulationResults() 465 txMgrHelper.checkRWsetInvalid(txRWSet3) 466 467 // tx2 should still be valid 468 txRWSet2, _ := s2.GetTxSimulationResults() 469 txMgrHelper.validateAndCommitRWSet(txRWSet2) 470 471 } 472 473 func TestGetSetMultipeKeys(t *testing.T) { 474 for _, testEnv := range testEnvs { 475 t.Logf("Running test for TestEnv = %s", testEnv.getName()) 476 testLedgerID := "testgetsetmultipekeys" 477 testEnv.init(t, testLedgerID) 478 testGetSetMultipeKeys(t, testEnv) 479 testEnv.cleanup() 480 } 481 } 482 483 func testGetSetMultipeKeys(t *testing.T, env testEnv) { 484 cID := "cID" 485 txMgr := env.getTxMgr() 486 txMgrHelper := newTxMgrTestHelper(t, txMgr) 487 // simulate tx1 488 s1, _ := txMgr.NewTxSimulator() 489 multipleKeyMap := make(map[string][]byte) 490 for i := 1; i <= 10; i++ { 491 k := createTestKey(i) 492 v := createTestValue(i) 493 multipleKeyMap[k] = v 494 } 495 s1.SetStateMultipleKeys(cID, multipleKeyMap) 496 s1.Done() 497 // validate and commit RWset 498 txRWSet, _ := s1.GetTxSimulationResults() 499 txMgrHelper.validateAndCommitRWSet(txRWSet) 500 qe, _ := txMgr.NewQueryExecutor() 501 defer qe.Done() 502 multipleKeys := []string{} 503 for k := range multipleKeyMap { 504 multipleKeys = append(multipleKeys, k) 505 } 506 values, _ := qe.GetStateMultipleKeys(cID, multipleKeys) 507 testutil.AssertEquals(t, len(values), 10) 508 for i, v := range values { 509 testutil.AssertEquals(t, v, multipleKeyMap[multipleKeys[i]]) 510 } 511 512 s2, _ := txMgr.NewTxSimulator() 513 defer s2.Done() 514 values, _ = s2.GetStateMultipleKeys(cID, multipleKeys[5:7]) 515 testutil.AssertEquals(t, len(values), 2) 516 for i, v := range values { 517 testutil.AssertEquals(t, v, multipleKeyMap[multipleKeys[i+5]]) 518 } 519 } 520 521 func createTestKey(i int) string { 522 if i == 0 { 523 return "" 524 } 525 return fmt.Sprintf("key_%03d", i) 526 } 527 528 func createTestValue(i int) []byte { 529 return []byte(fmt.Sprintf("value_%03d", i)) 530 } 531 532 //TestExecuteQueryQuery is only tested on the CouchDB testEnv 533 func TestExecuteQuery(t *testing.T) { 534 535 for _, testEnv := range testEnvs { 536 // Query is only supported and tested on the CouchDB testEnv 537 if testEnv.getName() == couchDBtestEnvName { 538 t.Logf("Running test for TestEnv = %s", testEnv.getName()) 539 testLedgerID := "testexecutequery" 540 testEnv.init(t, testLedgerID) 541 testExecuteQuery(t, testEnv) 542 testEnv.cleanup() 543 } 544 } 545 } 546 547 func testExecuteQuery(t *testing.T, env testEnv) { 548 549 type Asset struct { 550 ID string `json:"_id"` 551 Rev string `json:"_rev"` 552 AssetName string `json:"asset_name"` 553 Color string `json:"color"` 554 Size string `json:"size"` 555 Owner string `json:"owner"` 556 } 557 558 txMgr := env.getTxMgr() 559 txMgrHelper := newTxMgrTestHelper(t, txMgr) 560 561 s1, _ := txMgr.NewTxSimulator() 562 563 s1.SetState("ns1", "key1", []byte("value1")) 564 s1.SetState("ns1", "key2", []byte("value2")) 565 s1.SetState("ns1", "key3", []byte("value3")) 566 s1.SetState("ns1", "key4", []byte("value4")) 567 s1.SetState("ns1", "key5", []byte("value5")) 568 s1.SetState("ns1", "key6", []byte("value6")) 569 s1.SetState("ns1", "key7", []byte("value7")) 570 s1.SetState("ns1", "key8", []byte("value8")) 571 572 s1.SetState("ns1", "key9", []byte(`{"asset_name":"marble1","color":"red","size":"25","owner":"jerry"}`)) 573 s1.SetState("ns1", "key10", []byte(`{"asset_name":"marble2","color":"blue","size":"10","owner":"bob"}`)) 574 s1.SetState("ns1", "key11", []byte(`{"asset_name":"marble3","color":"blue","size":"35","owner":"jerry"}`)) 575 s1.SetState("ns1", "key12", []byte(`{"asset_name":"marble4","color":"green","size":"15","owner":"bob"}`)) 576 s1.SetState("ns1", "key13", []byte(`{"asset_name":"marble5","color":"red","size":"35","owner":"jerry"}`)) 577 s1.SetState("ns1", "key14", []byte(`{"asset_name":"marble6","color":"blue","size":"25","owner":"bob"}`)) 578 579 s1.Done() 580 581 // validate and commit RWset 582 txRWSet, _ := s1.GetTxSimulationResults() 583 txMgrHelper.validateAndCommitRWSet(txRWSet) 584 585 queryExecuter, _ := txMgr.NewQueryExecutor() 586 queryString := "{\"selector\":{\"owner\": {\"$eq\": \"bob\"}},\"limit\": 10,\"skip\": 0}" 587 588 itr, err := queryExecuter.ExecuteQuery("ns1", queryString) 589 testutil.AssertNoError(t, err, "Error upon ExecuteQuery()") 590 counter := 0 591 for { 592 queryRecord, _ := itr.Next() 593 if queryRecord == nil { 594 break 595 } 596 //Unmarshal the document to Asset structure 597 assetResp := &Asset{} 598 json.Unmarshal(queryRecord.(*queryresult.KV).Value, &assetResp) 599 //Verify the owner retrieved matches 600 testutil.AssertEquals(t, assetResp.Owner, "bob") 601 counter++ 602 } 603 //Ensure the query returns 3 documents 604 testutil.AssertEquals(t, counter, 3) 605 } 606 607 func TestValidateKey(t *testing.T) { 608 nonUTF8Key := string([]byte{0xff, 0xff}) 609 dummyValue := []byte("dummyValue") 610 for _, testEnv := range testEnvs { 611 testLedgerID := "test.validate.key" 612 testEnv.init(t, testLedgerID) 613 txSimulator, _ := testEnv.getTxMgr().NewTxSimulator() 614 err := txSimulator.SetState("ns1", nonUTF8Key, dummyValue) 615 if testEnv.getName() == levelDBtestEnvName { 616 testutil.AssertNoError(t, err, "") 617 } 618 if testEnv.getName() == couchDBtestEnvName { 619 testutil.AssertError(t, err, "") 620 } 621 testEnv.cleanup() 622 } 623 }