Skip to content

Commit

Permalink
[FAB-12545] Fix mock stub PutState on empty value
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
srderson committed Oct 19, 2018
1 parent cb21dcd commit 6fc968f
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
6 changes: 6 additions & 0 deletions core/chaincode/shim/mockstub.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,12 @@ func (stub *MockStub) PutState(key string, value []byte) error {
return err
}

// If the value is nil or empty, delete the key
if len(value) == 0 {
mockLogger.Debug("MockStub", stub.Name, "PutState called, but value is nil or empty. Delete ", key)
return stub.DelState(key)
}

mockLogger.Debug("MockStub", stub.Name, "Putting", key, value)
stub.State[key] = value

Expand Down
59 changes: 59 additions & 0 deletions core/chaincode/shim/mockstub_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (

"github.com/hyperledger/fabric/common/flogging"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
)

func TestMockStateRangeQueryIterator(t *testing.T) {
Expand Down Expand Up @@ -235,6 +236,64 @@ func TestGetTxTimestamp(t *testing.T) {
stub.MockTransactionEnd("init")
}

// TestPutEmptyState confirms that setting a key value to empty or nil in the mock state deletes the key
// instead of storing an empty key.
func TestPutEmptyState(t *testing.T) {
stub := NewMockStub("FAB-12545", nil)

// Put an empty and nil state value
stub.MockTransactionStart("1")
err := stub.PutState("empty", []byte{})
assert.NoError(t, err)
err = stub.PutState("nil", nil)
assert.NoError(t, err)
stub.MockTransactionEnd("1")

// Confirm both are nil
stub.MockTransactionStart("2")
val, err := stub.GetState("empty")
assert.NoError(t, err)
assert.Nil(t, val)
val, err = stub.GetState("nil")
assert.NoError(t, err)
assert.Nil(t, val)
// Add a value to both empty and nil
err = stub.PutState("empty", []byte{0})
assert.NoError(t, err)
err = stub.PutState("nil", []byte{0})
assert.NoError(t, err)
stub.MockTransactionEnd("2")

// Confirm the value is in both
stub.MockTransactionStart("3")
val, err = stub.GetState("empty")
assert.NoError(t, err)
assert.Equal(t, val, []byte{0})
val, err = stub.GetState("nil")
assert.NoError(t, err)
assert.Equal(t, val, []byte{0})
stub.MockTransactionEnd("3")

// Set both back to empty / nil
stub.MockTransactionStart("4")
err = stub.PutState("empty", []byte{})
assert.NoError(t, err)
err = stub.PutState("nil", nil)
assert.NoError(t, err)
stub.MockTransactionEnd("4")

// Confirm both are nil
stub.MockTransactionStart("5")
val, err = stub.GetState("empty")
assert.NoError(t, err)
assert.Nil(t, val)
val, err = stub.GetState("nil")
assert.NoError(t, err)
assert.Nil(t, val)
stub.MockTransactionEnd("5")

}

//TestMockMock clearly cheating for coverage... but not. Mock should
//be tucked away under common/mocks package which is not
//included for coverage. Moving mockstub to another package
Expand Down

0 comments on commit 6fc968f

Please sign in to comment.