Skip to content

Commit f330daa

Browse files
committed
Enable additional ledger txmgr unit tests
Some tests were disabled while CouchDB was getting fully functional. This changeset re-enables all txmgr tests, fixes some of the tests, and ensures that all tests are run against both LevelDB and CouchDB environmnents, to ensure consistent results against the different state databases. Change-Id: I5fedbb1457bc45dfd1b33c950e1b4041b3749c64 Signed-off-by: denyeart <enyeart@us.ibm.com>
1 parent 820e2cb commit f330daa

File tree

2 files changed

+95
-87
lines changed

2 files changed

+95
-87
lines changed

core/ledger/kvledger/txmgmt/txmgr/commontests/pkg_test.go

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ import (
2525
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/statedb/stateleveldb"
2626
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/txmgr"
2727
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/txmgr/lockbasedtxmgr"
28-
"github.com/hyperledger/fabric/core/ledger/ledgerconfig"
29-
ledgertestutil "github.com/hyperledger/fabric/core/ledger/testutil"
3028
"github.com/hyperledger/fabric/core/ledger/util"
3129
"github.com/hyperledger/fabric/protos/common"
3230
"github.com/spf13/viper"
@@ -37,48 +35,40 @@ const (
3735
)
3836

3937
type testEnv interface {
40-
init(t *testing.T)
38+
init(t *testing.T, testLedgerID string)
4139
getName() string
4240
getTxMgr() txmgr.TxMgr
4341
getVDB() statedb.VersionedDB
4442
cleanup()
4543
}
4644

47-
var testEnvs = []testEnv{}
48-
49-
func init() {
50-
//call a helper method to load the core.yaml so that we can detect whether couch is configured
51-
ledgertestutil.SetupCoreYAMLConfig("./../../../../../../peer")
52-
53-
//Only run the tests if CouchDB is explitily enabled in the code,
54-
//otherwise CouchDB may not be installed and all the tests would fail
55-
if ledgerconfig.IsCouchDBEnabled() == true {
56-
testEnvs = []testEnv{&levelDBLockBasedEnv{}, &couchDBLockBasedEnv{}}
57-
} else {
58-
testEnvs = []testEnv{&levelDBLockBasedEnv{}}
59-
}
60-
61-
}
45+
// Tests will be run against each environment in this array
46+
// For example, to skip CouchDB tests, remove &couchDBLockBasedEnv{}
47+
var testEnvs = []testEnv{&levelDBLockBasedEnv{}, &couchDBLockBasedEnv{}}
6248

6349
///////////// LevelDB Environment //////////////
6450

51+
const levelDBtestEnvName = "levelDB_LockBasedTxMgr"
52+
6553
type levelDBLockBasedEnv struct {
66-
testDBEnv *stateleveldb.TestVDBEnv
67-
testDB statedb.VersionedDB
68-
txmgr txmgr.TxMgr
54+
testLedgerID string
55+
testDBEnv *stateleveldb.TestVDBEnv
56+
testDB statedb.VersionedDB
57+
txmgr txmgr.TxMgr
6958
}
7059

7160
func (env *levelDBLockBasedEnv) getName() string {
72-
return "levelDB_LockBasedTxMgr"
61+
return levelDBtestEnvName
7362
}
7463

75-
func (env *levelDBLockBasedEnv) init(t *testing.T) {
64+
func (env *levelDBLockBasedEnv) init(t *testing.T, testLedgerID string) {
7665
viper.Set("peer.fileSystemPath", testFilesystemPath)
7766
testDBEnv := stateleveldb.NewTestVDBEnv(t)
78-
testDB, err := testDBEnv.DBProvider.GetDBHandle("TestDB")
67+
testDB, err := testDBEnv.DBProvider.GetDBHandle(testLedgerID)
7968
testutil.AssertNoError(t, err, "")
8069

8170
txMgr := lockbasedtxmgr.NewLockBasedTxMgr(testDB)
71+
env.testLedgerID = testLedgerID
8272
env.testDBEnv = testDBEnv
8373
env.testDB = testDB
8474
env.txmgr = txMgr
@@ -99,27 +89,29 @@ func (env *levelDBLockBasedEnv) cleanup() {
9989

10090
///////////// CouchDB Environment //////////////
10191

102-
var couchTestChainID = "TxmgrTestDB"
92+
const couchDBtestEnvName = "couchDB_LockBasedTxMgr"
10393

10494
type couchDBLockBasedEnv struct {
105-
testDBEnv *statecouchdb.TestVDBEnv
106-
testDB statedb.VersionedDB
107-
txmgr txmgr.TxMgr
95+
testLedgerID string
96+
testDBEnv *statecouchdb.TestVDBEnv
97+
testDB statedb.VersionedDB
98+
txmgr txmgr.TxMgr
10899
}
109100

110101
func (env *couchDBLockBasedEnv) getName() string {
111-
return "couchDB_LockBasedTxMgr"
102+
return couchDBtestEnvName
112103
}
113104

114-
func (env *couchDBLockBasedEnv) init(t *testing.T) {
105+
func (env *couchDBLockBasedEnv) init(t *testing.T, testLedgerID string) {
115106
viper.Set("peer.fileSystemPath", testFilesystemPath)
116107
// both vagrant and CI have couchdb configured at host "couchdb"
117108
viper.Set("ledger.state.couchDBConfig.couchDBAddress", "couchdb:5984")
118109
testDBEnv := statecouchdb.NewTestVDBEnv(t)
119-
testDB, err := testDBEnv.DBProvider.GetDBHandle(couchTestChainID)
110+
testDB, err := testDBEnv.DBProvider.GetDBHandle(testLedgerID)
120111
testutil.AssertNoError(t, err, "")
121112

122113
txMgr := lockbasedtxmgr.NewLockBasedTxMgr(testDB)
114+
env.testLedgerID = testLedgerID
123115
env.testDBEnv = testDBEnv
124116
env.testDB = testDB
125117
env.txmgr = txMgr
@@ -135,7 +127,7 @@ func (env *couchDBLockBasedEnv) getVDB() statedb.VersionedDB {
135127

136128
func (env *couchDBLockBasedEnv) cleanup() {
137129
defer env.txmgr.Shutdown()
138-
defer env.testDBEnv.Cleanup(couchTestChainID)
130+
defer env.testDBEnv.Cleanup(env.testLedgerID)
139131
}
140132

141133
//////////// txMgrTestHelper /////////////

core/ledger/kvledger/txmgmt/txmgr/commontests/txmgr_test.go

Lines changed: 71 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ import (
2424
"github.com/hyperledger/fabric/common/ledger/testutil"
2525
"github.com/hyperledger/fabric/core/ledger"
2626
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/version"
27-
"github.com/hyperledger/fabric/core/ledger/ledgerconfig"
2827
)
2928

3029
func TestTxSimulatorWithNoExistingData(t *testing.T) {
30+
// run the tests for each environment configured in pkg_test.go
3131
for _, testEnv := range testEnvs {
3232
t.Logf("Running test for TestEnv = %s", testEnv.getName())
33-
testEnv.init(t)
33+
testLedgerID := "testtxsimulatorwithnoexistingdata"
34+
testEnv.init(t, testLedgerID)
3435
testTxSimulatorWithNoExistingData(t, testEnv)
3536
testEnv.cleanup()
3637
}
@@ -55,7 +56,8 @@ func testTxSimulatorWithNoExistingData(t *testing.T, env testEnv) {
5556
func TestTxSimulatorWithExistingData(t *testing.T) {
5657
for _, testEnv := range testEnvs {
5758
t.Run(testEnv.getName(), func(t *testing.T) {
58-
testEnv.init(t)
59+
testLedgerID := "testtxsimulatorwithexistingdata"
60+
testEnv.init(t, testLedgerID)
5961
testTxSimulatorWithExistingData(t, testEnv)
6062
testEnv.cleanup()
6163
})
@@ -99,16 +101,16 @@ func testTxSimulatorWithExistingData(t *testing.T, env testEnv) {
99101

100102
// verify the versions of keys in persistence
101103
vv, _ := env.getVDB().GetState("ns1", "key1")
102-
//TODO re-enable after adding couch version wrapper
103-
//testutil.AssertEquals(t, vv.Version, version.NewHeight(2, 1))
104+
testutil.AssertEquals(t, vv.Version, version.NewHeight(1, 1))
104105
vv, _ = env.getVDB().GetState("ns1", "key2")
105106
testutil.AssertEquals(t, vv.Version, version.NewHeight(0, 1))
106107
}
107108

108109
func TestTxValidation(t *testing.T) {
109110
for _, testEnv := range testEnvs {
110111
t.Logf("Running test for TestEnv = %s", testEnv.getName())
111-
testEnv.init(t)
112+
testLedgerID := "testtxvalidation"
113+
testEnv.init(t, testLedgerID)
112114
testTxValidation(t, testEnv)
113115
testEnv.cleanup()
114116
}
@@ -128,7 +130,8 @@ func testTxValidation(t *testing.T, env testEnv) {
128130
txRWSet1, _ := s1.GetTxSimulationResults()
129131
txMgrHelper.validateAndCommitRWSet(txRWSet1)
130132

131-
// simulate tx2 that make changes to existing data
133+
// simulate tx2 that make changes to existing data.
134+
// tx2: Read/Update ns1:key1, Delete ns2:key3.
132135
s2, _ := txMgr.NewTxSimulator()
133136
value, _ := s2.GetState("ns1", "key1")
134137
testutil.AssertEquals(t, value, []byte("value1"))
@@ -137,55 +140,64 @@ func testTxValidation(t *testing.T, env testEnv) {
137140
s2.DeleteState("ns2", "key3")
138141
s2.Done()
139142

140-
// simulate tx3 before committing tx2 changes. Reads and modifies the key changed by tx2
143+
// simulate tx3 before committing tx2 changes. Reads and modifies the key changed by tx2.
144+
// tx3: Read/Update ns1:key1
141145
s3, _ := txMgr.NewTxSimulator()
142146
s3.GetState("ns1", "key1")
143147
s3.SetState("ns1", "key1", []byte("value1_3"))
144148
s3.Done()
145149

146150
// simulate tx4 before committing tx2 changes. Reads and Deletes the key changed by tx2
151+
// tx4: Read/Delete ns2:key3
147152
s4, _ := txMgr.NewTxSimulator()
148153
s4.GetState("ns2", "key3")
149154
s4.DeleteState("ns2", "key3")
150155
s4.Done()
151156

152157
// simulate tx5 before committing tx2 changes. Modifies and then Reads the key changed by tx2 and writes a new key
158+
// tx5: Update/Read ns1:key1
153159
s5, _ := txMgr.NewTxSimulator()
154160
s5.SetState("ns1", "key1", []byte("new_value"))
155161
s5.GetState("ns1", "key1")
156162
s5.Done()
157163

158164
// simulate tx6 before committing tx2 changes. Only writes a new key, does not reads/writes a key changed by tx2
165+
// tx6: Update ns1:new_key
159166
s6, _ := txMgr.NewTxSimulator()
160167
s6.SetState("ns1", "new_key", []byte("new_value"))
161168
s6.Done()
162169

170+
// Summary of simulated transactions
171+
// tx2: Read/Update ns1:key1, Delete ns2:key3.
172+
// tx3: Read/Update ns1:key1
173+
// tx4: Read/Delete ns2:key3
174+
// tx5: Update/Read ns1:key1
175+
// tx6: Update ns1:new_key
176+
163177
// validate and commit RWset for tx2
164178
txRWSet2, _ := s2.GetTxSimulationResults()
165179
txMgrHelper.validateAndCommitRWSet(txRWSet2)
166-
//TODO re-enable after adding couch version wrapper
167-
/*
168-
//RWSet for tx3 and tx4 should not be invalid now
169-
txRWSet3, _ := s3.GetTxSimulationResults()
170-
txMgrHelper.checkRWsetInvalid(txRWSet3)
171-
172-
txRWSet4, _ := s4.GetTxSimulationResults()
173-
txMgrHelper.checkRWsetInvalid(txRWSet4)
174-
175-
//tx5 shold still be valid as it over-writes the key first and then reads
176-
txRWSet5, _ := s5.GetTxSimulationResults()
177-
txMgrHelper.validateAndCommitRWSet(txRWSet5)
178-
179-
// tx6 should still be valid as it only writes a new key
180-
txRWSet6, _ := s6.GetTxSimulationResults()
181-
txMgrHelper.validateAndCommitRWSet(txRWSet6)
182-
*/
180+
181+
//RWSet for tx3 and tx4 and tx5 should be invalid now due to read conflicts
182+
txRWSet3, _ := s3.GetTxSimulationResults()
183+
txMgrHelper.checkRWsetInvalid(txRWSet3)
184+
185+
txRWSet4, _ := s4.GetTxSimulationResults()
186+
txMgrHelper.checkRWsetInvalid(txRWSet4)
187+
188+
txRWSet5, _ := s5.GetTxSimulationResults()
189+
txMgrHelper.checkRWsetInvalid(txRWSet5)
190+
191+
// tx6 should still be valid as it only writes a new key
192+
txRWSet6, _ := s6.GetTxSimulationResults()
193+
txMgrHelper.validateAndCommitRWSet(txRWSet6)
183194
}
184195

185196
func TestTxPhantomValidation(t *testing.T) {
186197
for _, testEnv := range testEnvs {
187198
t.Logf("Running test for TestEnv = %s", testEnv.getName())
188-
testEnv.init(t)
199+
testLedgerID := "testtxphantomvalidation"
200+
testEnv.init(t, testLedgerID)
189201
testTxPhantomValidation(t, testEnv)
190202
testEnv.cleanup()
191203
}
@@ -254,23 +266,29 @@ func testTxPhantomValidation(t *testing.T, env testEnv) {
254266
func TestIterator(t *testing.T) {
255267
for _, testEnv := range testEnvs {
256268
t.Logf("Running test for TestEnv = %s", testEnv.getName())
257-
testEnv.init(t)
269+
270+
testLedgerID := "testiterator_1"
271+
testEnv.init(t, testLedgerID)
258272
testIterator(t, testEnv, 10, 2, 7)
259273
testEnv.cleanup()
260274

261-
testEnv.init(t)
275+
testLedgerID = "testiterator_2"
276+
testEnv.init(t, testLedgerID)
262277
testIterator(t, testEnv, 10, 1, 11)
263278
testEnv.cleanup()
264279

265-
testEnv.init(t)
280+
testLedgerID = "testiterator_3"
281+
testEnv.init(t, testLedgerID)
266282
testIterator(t, testEnv, 10, 0, 0)
267283
testEnv.cleanup()
268284

269-
testEnv.init(t)
285+
testLedgerID = "testiterator_4"
286+
testEnv.init(t, testLedgerID)
270287
testIterator(t, testEnv, 10, 5, 0)
271288
testEnv.cleanup()
272289

273-
testEnv.init(t)
290+
testLedgerID = "testiterator_5"
291+
testEnv.init(t, testLedgerID)
274292
testIterator(t, testEnv, 10, 0, 5)
275293
testEnv.cleanup()
276294
}
@@ -337,7 +355,8 @@ func testIterator(t *testing.T, env testEnv, numKeys int, startKeyNum int, endKe
337355
func TestIteratorWithDeletes(t *testing.T) {
338356
for _, testEnv := range testEnvs {
339357
t.Logf("Running test for TestEnv = %s", testEnv.getName())
340-
testEnv.init(t)
358+
testLedgerID := "testiteratorwithdeletes"
359+
testEnv.init(t, testLedgerID)
341360
testIteratorWithDeletes(t, testEnv)
342361
testEnv.cleanup()
343362
}
@@ -371,15 +390,16 @@ func testIteratorWithDeletes(t *testing.T, env testEnv) {
371390
defer itr.Close()
372391
kv, _ := itr.Next()
373392
testutil.AssertEquals(t, kv.(*ledger.KV).Key, createTestKey(3))
374-
//TODO re-enable after adding couch delete function
375-
//kv, _ = itr.Next()
376-
//testutil.AssertEquals(t, kv.(*ledger.KV).Key, createTestKey(5))
393+
394+
kv, _ = itr.Next()
395+
testutil.AssertEquals(t, kv.(*ledger.KV).Key, createTestKey(5))
377396
}
378397

379398
func TestTxValidationWithItr(t *testing.T) {
380399
for _, testEnv := range testEnvs {
381400
t.Logf("Running test for TestEnv = %s", testEnv.getName())
382-
testEnv.init(t)
401+
testLedgerID := "testtxvalidationwithitr"
402+
testEnv.init(t, testLedgerID)
383403
testTxValidationWithItr(t, testEnv)
384404
testEnv.cleanup()
385405
}
@@ -430,12 +450,9 @@ func testTxValidationWithItr(t *testing.T, env testEnv) {
430450
txRWSet4, _ := s4.GetTxSimulationResults()
431451
txMgrHelper.validateAndCommitRWSet(txRWSet4)
432452

433-
//TODO re-enable after adding couch version wrapper
434-
/*
435-
//RWSet tx3 should not be invalid now
436-
txRWSet3, _ := s3.GetTxSimulationResults()
437-
txMgrHelper.checkRWsetInvalid(txRWSet3)
438-
*/
453+
//RWSet tx3 should be invalid now
454+
txRWSet3, _ := s3.GetTxSimulationResults()
455+
txMgrHelper.checkRWsetInvalid(txRWSet3)
439456

440457
// tx2 should still be valid
441458
txRWSet2, _ := s2.GetTxSimulationResults()
@@ -446,7 +463,8 @@ func testTxValidationWithItr(t *testing.T, env testEnv) {
446463
func TestGetSetMultipeKeys(t *testing.T) {
447464
for _, testEnv := range testEnvs {
448465
t.Logf("Running test for TestEnv = %s", testEnv.getName())
449-
testEnv.init(t)
466+
testLedgerID := "testgetsetmultipekeys"
467+
testEnv.init(t, testLedgerID)
450468
testGetSetMultipeKeys(t, testEnv)
451469
testEnv.cleanup()
452470
}
@@ -504,18 +522,15 @@ func createTestValue(i int) []byte {
504522
//TestExecuteQueryQuery is only tested on the CouchDB testEnv
505523
func TestExecuteQuery(t *testing.T) {
506524

507-
// Query is only tested on the CouchDB testEnv
508-
if ledgerconfig.IsCouchDBEnabled() == true {
509-
testEnvs = []testEnv{&couchDBLockBasedEnv{}}
510-
} else {
511-
testEnvs = []testEnv{}
512-
}
513-
514525
for _, testEnv := range testEnvs {
515-
t.Logf("Running test for TestEnv = %s", testEnv.getName())
516-
testEnv.init(t)
517-
testExecuteQuery(t, testEnv)
518-
testEnv.cleanup()
526+
// Query is only supported and tested on the CouchDB testEnv
527+
if testEnv.getName() == couchDBtestEnvName {
528+
t.Logf("Running test for TestEnv = %s", testEnv.getName())
529+
testLedgerID := "testexecutequery"
530+
testEnv.init(t, testLedgerID)
531+
testExecuteQuery(t, testEnv)
532+
testEnv.cleanup()
533+
}
519534
}
520535
}
521536

@@ -560,7 +575,8 @@ func testExecuteQuery(t *testing.T, env testEnv) {
560575
queryExecuter, _ := txMgr.NewQueryExecutor()
561576
queryString := "{\"selector\":{\"owner\": {\"$eq\": \"bob\"}},\"limit\": 10,\"skip\": 0}"
562577

563-
itr, _ := queryExecuter.ExecuteQuery("ns1", queryString)
578+
itr, err := queryExecuter.ExecuteQuery("ns1", queryString)
579+
testutil.AssertNoError(t, err, "Error upon ExecuteQuery()")
564580

565581
counter := 0
566582
for {

0 commit comments

Comments
 (0)