Skip to content

Commit 6fc968f

Browse files
committed
[FAB-12545] Fix mock stub PutState on empty value
The chaincode shim mock stub should delete the state key if the value supplied to PutState is empty. Currently, it stores the key with an empty value. Change-Id: Ib5fe46b84ed4ad8befac94491515d3dd55a94d2d Signed-off-by: Sheehan Anderson <sranderson@gmail.com>
1 parent cb21dcd commit 6fc968f

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

core/chaincode/shim/mockstub.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,12 @@ func (stub *MockStub) PutState(key string, value []byte) error {
211211
return err
212212
}
213213

214+
// If the value is nil or empty, delete the key
215+
if len(value) == 0 {
216+
mockLogger.Debug("MockStub", stub.Name, "PutState called, but value is nil or empty. Delete ", key)
217+
return stub.DelState(key)
218+
}
219+
214220
mockLogger.Debug("MockStub", stub.Name, "Putting", key, value)
215221
stub.State[key] = value
216222

core/chaincode/shim/mockstub_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424

2525
"github.com/hyperledger/fabric/common/flogging"
2626
"github.com/spf13/viper"
27+
"github.com/stretchr/testify/assert"
2728
)
2829

2930
func TestMockStateRangeQueryIterator(t *testing.T) {
@@ -235,6 +236,64 @@ func TestGetTxTimestamp(t *testing.T) {
235236
stub.MockTransactionEnd("init")
236237
}
237238

239+
// TestPutEmptyState confirms that setting a key value to empty or nil in the mock state deletes the key
240+
// instead of storing an empty key.
241+
func TestPutEmptyState(t *testing.T) {
242+
stub := NewMockStub("FAB-12545", nil)
243+
244+
// Put an empty and nil state value
245+
stub.MockTransactionStart("1")
246+
err := stub.PutState("empty", []byte{})
247+
assert.NoError(t, err)
248+
err = stub.PutState("nil", nil)
249+
assert.NoError(t, err)
250+
stub.MockTransactionEnd("1")
251+
252+
// Confirm both are nil
253+
stub.MockTransactionStart("2")
254+
val, err := stub.GetState("empty")
255+
assert.NoError(t, err)
256+
assert.Nil(t, val)
257+
val, err = stub.GetState("nil")
258+
assert.NoError(t, err)
259+
assert.Nil(t, val)
260+
// Add a value to both empty and nil
261+
err = stub.PutState("empty", []byte{0})
262+
assert.NoError(t, err)
263+
err = stub.PutState("nil", []byte{0})
264+
assert.NoError(t, err)
265+
stub.MockTransactionEnd("2")
266+
267+
// Confirm the value is in both
268+
stub.MockTransactionStart("3")
269+
val, err = stub.GetState("empty")
270+
assert.NoError(t, err)
271+
assert.Equal(t, val, []byte{0})
272+
val, err = stub.GetState("nil")
273+
assert.NoError(t, err)
274+
assert.Equal(t, val, []byte{0})
275+
stub.MockTransactionEnd("3")
276+
277+
// Set both back to empty / nil
278+
stub.MockTransactionStart("4")
279+
err = stub.PutState("empty", []byte{})
280+
assert.NoError(t, err)
281+
err = stub.PutState("nil", nil)
282+
assert.NoError(t, err)
283+
stub.MockTransactionEnd("4")
284+
285+
// Confirm both are nil
286+
stub.MockTransactionStart("5")
287+
val, err = stub.GetState("empty")
288+
assert.NoError(t, err)
289+
assert.Nil(t, val)
290+
val, err = stub.GetState("nil")
291+
assert.NoError(t, err)
292+
assert.Nil(t, val)
293+
stub.MockTransactionEnd("5")
294+
295+
}
296+
238297
//TestMockMock clearly cheating for coverage... but not. Mock should
239298
//be tucked away under common/mocks package which is not
240299
//included for coverage. Moving mockstub to another package

0 commit comments

Comments
 (0)