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