github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/core/chaincode/shim/mockstub_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 shim
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"reflect"
    23  	"testing"
    24  
    25  	"github.com/hyperledger/fabric/common/flogging"
    26  	"github.com/spf13/viper"
    27  )
    28  
    29  func TestMockStateRangeQueryIterator(t *testing.T) {
    30  	stub := NewMockStub("rangeTest", nil)
    31  	stub.MockTransactionStart("init")
    32  	stub.PutState("1", []byte{61})
    33  	stub.PutState("0", []byte{62})
    34  	stub.PutState("5", []byte{65})
    35  	stub.PutState("3", []byte{63})
    36  	stub.PutState("4", []byte{64})
    37  	stub.PutState("6", []byte{66})
    38  	stub.MockTransactionEnd("init")
    39  
    40  	expectKeys := []string{"3", "4"}
    41  	expectValues := [][]byte{{63}, {64}}
    42  
    43  	rqi := NewMockStateRangeQueryIterator(stub, "2", "4")
    44  
    45  	fmt.Println("Running loop")
    46  	for i := 0; i < 2; i++ {
    47  		response, err := rqi.Next()
    48  		fmt.Println("Loop", i, "got", response.Key, response.Value, err)
    49  		if expectKeys[i] != response.Key {
    50  			fmt.Println("Expected key", expectKeys[i], "got", response.Key)
    51  			t.FailNow()
    52  		}
    53  		if expectValues[i][0] != response.Value[0] {
    54  			fmt.Println("Expected value", expectValues[i], "got", response.Value)
    55  		}
    56  	}
    57  }
    58  
    59  // TestMockStateRangeQueryIterator_openEnded tests running an open-ended query
    60  // for all keys on the MockStateRangeQueryIterator
    61  func TestMockStateRangeQueryIterator_openEnded(t *testing.T) {
    62  	stub := NewMockStub("rangeTest", nil)
    63  	stub.MockTransactionStart("init")
    64  	stub.PutState("1", []byte{61})
    65  	stub.PutState("0", []byte{62})
    66  	stub.PutState("5", []byte{65})
    67  	stub.PutState("3", []byte{63})
    68  	stub.PutState("4", []byte{64})
    69  	stub.PutState("6", []byte{66})
    70  	stub.MockTransactionEnd("init")
    71  
    72  	rqi := NewMockStateRangeQueryIterator(stub, "", "")
    73  
    74  	count := 0
    75  	for rqi.HasNext() {
    76  		rqi.Next()
    77  		count++
    78  	}
    79  
    80  	if count != rqi.Stub.Keys.Len() {
    81  		t.FailNow()
    82  	}
    83  }
    84  
    85  // TestSetupChaincodeLogging uses the utlity function defined in chaincode.go to
    86  // set the chaincodeLogger's logging format and level
    87  func TestSetupChaincodeLogging_blankLevel(t *testing.T) {
    88  	// set log level to a non-default level
    89  	testLogLevelString := ""
    90  	testLogFormat := "%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"
    91  
    92  	viper.Set("chaincode.logging.level", testLogLevelString)
    93  	viper.Set("chaincode.logging.format", testLogFormat)
    94  
    95  	SetupChaincodeLogging()
    96  
    97  	if !IsEnabledForLogLevel(flogging.DefaultLevel()) {
    98  		t.FailNow()
    99  	}
   100  }
   101  
   102  // TestSetupChaincodeLogging uses the utlity function defined in chaincode.go to
   103  // set the chaincodeLogger's logging format and level
   104  func TestSetupChaincodeLogging(t *testing.T) {
   105  	// set log level to a non-default level
   106  	testLogLevel := "debug"
   107  	testShimLogLevel := "warning"
   108  	testLogFormat := "%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"
   109  
   110  	viper.Set("chaincode.logging.level", testLogLevel)
   111  	viper.Set("chaincode.logging.format", testLogFormat)
   112  	viper.Set("chaincode.logging.shim", testShimLogLevel)
   113  
   114  	SetupChaincodeLogging()
   115  
   116  	if !IsEnabledForLogLevel(testShimLogLevel) {
   117  		t.FailNow()
   118  	}
   119  }
   120  
   121  type Marble struct {
   122  	ObjectType string `json:"docType"` //docType is used to distinguish the various types of objects in state database
   123  	Name       string `json:"name"`    //the fieldtags are needed to keep case from bouncing around
   124  	Color      string `json:"color"`
   125  	Size       int    `json:"size"`
   126  	Owner      string `json:"owner"`
   127  }
   128  
   129  // JSONBytesEqual compares the JSON in two byte slices.
   130  func jsonBytesEqual(expected []byte, actual []byte) bool {
   131  	var infExpected, infActual interface{}
   132  	if err := json.Unmarshal(expected, &infExpected); err != nil {
   133  		return false
   134  	}
   135  	if err := json.Unmarshal(actual, &infActual); err != nil {
   136  		return false
   137  	}
   138  	return reflect.DeepEqual(infActual, infExpected)
   139  }
   140  
   141  func TestGetStateByPartialCompositeKey(t *testing.T) {
   142  	stub := NewMockStub("GetStateByPartialCompositeKeyTest", nil)
   143  	stub.MockTransactionStart("init")
   144  
   145  	marble1 := &Marble{"marble", "set-1", "red", 5, "tom"}
   146  	// Convert marble1 to JSON with Color and Name as composite key
   147  	compositeKey1, _ := stub.CreateCompositeKey(marble1.ObjectType, []string{marble1.Name, marble1.Color})
   148  	marbleJSONBytes1, _ := json.Marshal(marble1)
   149  	// Add marble1 JSON to state
   150  	stub.PutState(compositeKey1, marbleJSONBytes1)
   151  
   152  	marble2 := &Marble{"marble", "set-1", "blue", 5, "jerry"}
   153  	compositeKey2, _ := stub.CreateCompositeKey(marble2.ObjectType, []string{marble2.Name, marble2.Color})
   154  	marbleJSONBytes2, _ := json.Marshal(marble2)
   155  	stub.PutState(compositeKey2, marbleJSONBytes2)
   156  
   157  	marble3 := &Marble{"marble", "set-2", "red", 5, "tom-jerry"}
   158  	compositeKey3, _ := stub.CreateCompositeKey(marble3.ObjectType, []string{marble3.Name, marble3.Color})
   159  	marbleJSONBytes3, _ := json.Marshal(marble3)
   160  	stub.PutState(compositeKey3, marbleJSONBytes3)
   161  
   162  	stub.MockTransactionEnd("init")
   163  	// should return in sorted order of attributes
   164  	expectKeys := []string{compositeKey2, compositeKey1}
   165  	expectKeysAttributes := [][]string{{"set-1", "blue"}, {"set-1", "red"}}
   166  	expectValues := [][]byte{marbleJSONBytes2, marbleJSONBytes1}
   167  
   168  	rqi, _ := stub.GetStateByPartialCompositeKey("marble", []string{"set-1"})
   169  	fmt.Println("Running loop")
   170  	for i := 0; i < 2; i++ {
   171  		response, err := rqi.Next()
   172  		fmt.Println("Loop", i, "got", response.Key, response.Value, err)
   173  		if expectKeys[i] != response.Key {
   174  			fmt.Println("Expected key", expectKeys[i], "got", response.Key)
   175  			t.FailNow()
   176  		}
   177  		objectType, attributes, _ := stub.SplitCompositeKey(response.Key)
   178  		if objectType != "marble" {
   179  			fmt.Println("Expected objectType", "marble", "got", objectType)
   180  			t.FailNow()
   181  		}
   182  		fmt.Println(attributes)
   183  		for index, attr := range attributes {
   184  			if expectKeysAttributes[i][index] != attr {
   185  				fmt.Println("Expected keys attribute", expectKeysAttributes[index][i], "got", attr)
   186  				t.FailNow()
   187  			}
   188  		}
   189  		if jsonBytesEqual(expectValues[i], response.Value) != true {
   190  			fmt.Println("Expected value", expectValues[i], "got", response.Value)
   191  			t.FailNow()
   192  		}
   193  	}
   194  }
   195  
   196  func TestGetStateByPartialCompositeKeyCollision(t *testing.T) {
   197  	stub := NewMockStub("GetStateByPartialCompositeKeyCollisionTest", nil)
   198  	stub.MockTransactionStart("init")
   199  
   200  	vehicle1Bytes := []byte("vehicle1")
   201  	compositeKeyVehicle1, _ := stub.CreateCompositeKey("Vehicle", []string{"VIN_1234"})
   202  	stub.PutState(compositeKeyVehicle1, vehicle1Bytes)
   203  
   204  	vehicleListing1Bytes := []byte("vehicleListing1")
   205  	compositeKeyVehicleListing1, _ := stub.CreateCompositeKey("VehicleListing", []string{"LIST_1234"})
   206  	stub.PutState(compositeKeyVehicleListing1, vehicleListing1Bytes)
   207  
   208  	stub.MockTransactionEnd("init")
   209  
   210  	// Only the single "Vehicle" object should be returned, not the "VehicleListing" object
   211  	rqi, _ := stub.GetStateByPartialCompositeKey("Vehicle", []string{})
   212  	i := 0
   213  	fmt.Println("Running loop")
   214  	for rqi.HasNext() {
   215  		i++
   216  		response, err := rqi.Next()
   217  		fmt.Println("Loop", i, "got", response.Key, response.Value, err)
   218  	}
   219  	// Only the single "Vehicle" object should be returned, not the "VehicleListing" object
   220  	if i != 1 {
   221  		fmt.Println("Expected 1, got", i)
   222  		t.FailNow()
   223  	}
   224  }
   225  
   226  func TestGetTxTimestamp(t *testing.T) {
   227  	stub := NewMockStub("GetTxTimestamp", nil)
   228  	stub.MockTransactionStart("init")
   229  
   230  	timestamp, err := stub.GetTxTimestamp()
   231  	if timestamp == nil || err != nil {
   232  		t.FailNow()
   233  	}
   234  
   235  	stub.MockTransactionEnd("init")
   236  }
   237  
   238  //TestMockMock clearly cheating for coverage... but not. Mock should
   239  //be tucked away under common/mocks package which is not
   240  //included for coverage. Moving mockstub to another package
   241  //will cause upheaval in other code best dealt with separately
   242  //For now, call all the methods to get mock covered in this
   243  //package
   244  func TestMockMock(t *testing.T) {
   245  	stub := NewMockStub("MOCKMOCK", &shimTestCC{})
   246  	stub.args = [][]byte{[]byte("a"), []byte("b")}
   247  	stub.MockInit("id", nil)
   248  	stub.GetArgs()
   249  	stub.GetStringArgs()
   250  	stub.GetFunctionAndParameters()
   251  	stub.GetTxID()
   252  	stub.MockInvoke("id", nil)
   253  	stub.MockInvokeWithSignedProposal("id", nil, nil)
   254  	stub.DelState("dummy")
   255  	stub.GetStateByRange("start", "end")
   256  	stub.GetQueryResult("q")
   257  	stub2 := NewMockStub("othercc", &shimTestCC{})
   258  	stub.MockPeerChaincode("othercc/mychan", stub2)
   259  	stub.InvokeChaincode("othercc", nil, "mychan")
   260  	stub.GetCreator()
   261  	stub.GetTransient()
   262  	stub.GetBinding()
   263  	stub.GetSignedProposal()
   264  	stub.GetArgsSlice()
   265  	stub.SetEvent("e", nil)
   266  	stub.GetHistoryForKey("k")
   267  	iter := &MockStateRangeQueryIterator{}
   268  	iter.HasNext()
   269  	iter.Close()
   270  	getBytes("f", []string{"a", "b"})
   271  	getFuncArgs([][]byte{[]byte("a")})
   272  }