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  }