github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/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/spf13/viper"
    26  )
    27  
    28  func TestMockStateRangeQueryIterator(t *testing.T) {
    29  	stub := NewMockStub("rangeTest", nil)
    30  	stub.MockTransactionStart("init")
    31  	stub.PutState("1", []byte{61})
    32  	stub.PutState("0", []byte{62})
    33  	stub.PutState("5", []byte{65})
    34  	stub.PutState("3", []byte{63})
    35  	stub.PutState("4", []byte{64})
    36  	stub.PutState("6", []byte{66})
    37  	stub.MockTransactionEnd("init")
    38  
    39  	expectKeys := []string{"3", "4"}
    40  	expectValues := [][]byte{{63}, {64}}
    41  
    42  	rqi := NewMockStateRangeQueryIterator(stub, "2", "4")
    43  
    44  	fmt.Println("Running loop")
    45  	for i := 0; i < 2; i++ {
    46  		response, err := rqi.Next()
    47  		fmt.Println("Loop", i, "got", response.Key, response.Value, err)
    48  		if expectKeys[i] != response.Key {
    49  			fmt.Println("Expected key", expectKeys[i], "got", response.Key)
    50  			t.FailNow()
    51  		}
    52  		if expectValues[i][0] != response.Value[0] {
    53  			fmt.Println("Expected value", expectValues[i], "got", response.Value)
    54  		}
    55  	}
    56  }
    57  
    58  // TestMockStateRangeQueryIterator_openEnded tests running an open-ended query
    59  // for all keys on the MockStateRangeQueryIterator
    60  func TestMockStateRangeQueryIterator_openEnded(t *testing.T) {
    61  	stub := NewMockStub("rangeTest", nil)
    62  	stub.MockTransactionStart("init")
    63  	stub.PutState("1", []byte{61})
    64  	stub.PutState("0", []byte{62})
    65  	stub.PutState("5", []byte{65})
    66  	stub.PutState("3", []byte{63})
    67  	stub.PutState("4", []byte{64})
    68  	stub.PutState("6", []byte{66})
    69  	stub.MockTransactionEnd("init")
    70  
    71  	rqi := NewMockStateRangeQueryIterator(stub, "", "")
    72  
    73  	count := 0
    74  	for rqi.HasNext() {
    75  		rqi.Next()
    76  		count++
    77  	}
    78  
    79  	if count != rqi.Stub.Keys.Len() {
    80  		t.FailNow()
    81  	}
    82  }
    83  
    84  // TestSetupChaincodeLogging uses the utlity function defined in chaincode.go to
    85  // set the chaincodeLogger's logging format and level
    86  func TestSetupChaincodeLogging_blankLevel(t *testing.T) {
    87  	// set log level to a non-default level
    88  	testLogLevelString := ""
    89  	testLogFormat := "%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"
    90  
    91  	viper.Set("chaincode.logLevel", testLogLevelString)
    92  	viper.Set("chaincode.logFormat", testLogFormat)
    93  
    94  	SetupChaincodeLogging()
    95  
    96  	if !IsEnabledForLogLevel("info") {
    97  		t.FailNow()
    98  	}
    99  }
   100  
   101  // TestSetupChaincodeLogging uses the utlity function defined in chaincode.go to
   102  // set the chaincodeLogger's logging format and level
   103  func TestSetupChaincodeLogging(t *testing.T) {
   104  	// set log level to a non-default level
   105  	testLogLevelString := "debug"
   106  	testLogFormat := "%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"
   107  
   108  	viper.Set("chaincode.logLevel", testLogLevelString)
   109  	viper.Set("chaincode.logFormat", testLogFormat)
   110  
   111  	SetupChaincodeLogging()
   112  
   113  	if !IsEnabledForLogLevel(testLogLevelString) {
   114  		t.FailNow()
   115  	}
   116  }
   117  
   118  type Marble struct {
   119  	ObjectType string `json:"docType"` //docType is used to distinguish the various types of objects in state database
   120  	Name       string `json:"name"`    //the fieldtags are needed to keep case from bouncing around
   121  	Color      string `json:"color"`
   122  	Size       int    `json:"size"`
   123  	Owner      string `json:"owner"`
   124  }
   125  
   126  // JSONBytesEqual compares the JSON in two byte slices.
   127  func jsonBytesEqual(expected []byte, actual []byte) bool {
   128  	var infExpected, infActual interface{}
   129  	if err := json.Unmarshal(expected, &infExpected); err != nil {
   130  		return false
   131  	}
   132  	if err := json.Unmarshal(actual, &infActual); err != nil {
   133  		return false
   134  	}
   135  	return reflect.DeepEqual(infActual, infExpected)
   136  }
   137  
   138  func TestGetStateByPartialCompositeKey(t *testing.T) {
   139  	stub := NewMockStub("GetStateByPartialCompositeKeyTest", nil)
   140  	stub.MockTransactionStart("init")
   141  
   142  	marble1 := &Marble{"marble", "set-1", "red", 5, "tom"}
   143  	// Convert marble1 to JSON with Color and Name as composite key
   144  	compositeKey1, _ := stub.CreateCompositeKey(marble1.ObjectType, []string{marble1.Name, marble1.Color})
   145  	marbleJSONBytes1, _ := json.Marshal(marble1)
   146  	// Add marble1 JSON to state
   147  	stub.PutState(compositeKey1, marbleJSONBytes1)
   148  
   149  	marble2 := &Marble{"marble", "set-1", "blue", 5, "jerry"}
   150  	compositeKey2, _ := stub.CreateCompositeKey(marble2.ObjectType, []string{marble2.Name, marble2.Color})
   151  	marbleJSONBytes2, _ := json.Marshal(marble2)
   152  	stub.PutState(compositeKey2, marbleJSONBytes2)
   153  
   154  	marble3 := &Marble{"marble", "set-2", "red", 5, "tom-jerry"}
   155  	compositeKey3, _ := stub.CreateCompositeKey(marble3.ObjectType, []string{marble3.Name, marble3.Color})
   156  	marbleJSONBytes3, _ := json.Marshal(marble3)
   157  	stub.PutState(compositeKey3, marbleJSONBytes3)
   158  
   159  	stub.MockTransactionEnd("init")
   160  	// should return in sorted order of attributes
   161  	expectKeys := []string{compositeKey2, compositeKey1}
   162  	expectKeysAttributes := [][]string{{"set-1", "blue"}, {"set-1", "red"}}
   163  	expectValues := [][]byte{marbleJSONBytes2, marbleJSONBytes1}
   164  
   165  	rqi, _ := stub.GetStateByPartialCompositeKey("marble", []string{"set-1"})
   166  	fmt.Println("Running loop")
   167  	for i := 0; i < 2; i++ {
   168  		response, err := rqi.Next()
   169  		fmt.Println("Loop", i, "got", response.Key, response.Value, err)
   170  		if expectKeys[i] != response.Key {
   171  			fmt.Println("Expected key", expectKeys[i], "got", response.Key)
   172  			t.FailNow()
   173  		}
   174  		objectType, attributes, _ := stub.SplitCompositeKey(response.Key)
   175  		if objectType != "marble" {
   176  			fmt.Println("Expected objectType", "marble", "got", objectType)
   177  			t.FailNow()
   178  		}
   179  		fmt.Println(attributes)
   180  		for index, attr := range attributes {
   181  			if expectKeysAttributes[i][index] != attr {
   182  				fmt.Println("Expected keys attribute", expectKeysAttributes[index][i], "got", attr)
   183  				t.FailNow()
   184  			}
   185  		}
   186  		if jsonBytesEqual(expectValues[i], response.Value) != true {
   187  			fmt.Println("Expected value", expectValues[i], "got", response.Value)
   188  			t.FailNow()
   189  		}
   190  	}
   191  }
   192  
   193  func TestGetStateByPartialCompositeKeyCollision(t *testing.T) {
   194  	stub := NewMockStub("GetStateByPartialCompositeKeyCollisionTest", nil)
   195  	stub.MockTransactionStart("init")
   196  
   197  	vehicle1Bytes := []byte("vehicle1")
   198  	compositeKeyVehicle1, _ := stub.CreateCompositeKey("Vehicle", []string{"VIN_1234"})
   199  	stub.PutState(compositeKeyVehicle1, vehicle1Bytes)
   200  
   201  	vehicleListing1Bytes := []byte("vehicleListing1")
   202  	compositeKeyVehicleListing1, _ := stub.CreateCompositeKey("VehicleListing", []string{"LIST_1234"})
   203  	stub.PutState(compositeKeyVehicleListing1, vehicleListing1Bytes)
   204  
   205  	stub.MockTransactionEnd("init")
   206  
   207  	// Only the single "Vehicle" object should be returned, not the "VehicleListing" object
   208  	rqi, _ := stub.GetStateByPartialCompositeKey("Vehicle", []string{})
   209  	i := 0
   210  	fmt.Println("Running loop")
   211  	for rqi.HasNext() {
   212  		i++
   213  		response, err := rqi.Next()
   214  		fmt.Println("Loop", i, "got", response.Key, response.Value, err)
   215  	}
   216  	// Only the single "Vehicle" object should be returned, not the "VehicleListing" object
   217  	if i != 1 {
   218  		fmt.Println("Expected 1, got", i)
   219  		t.FailNow()
   220  	}
   221  }
   222  
   223  func TestGetTxTimestamp(t *testing.T) {
   224  	stub := NewMockStub("GetTxTimestamp", nil)
   225  	stub.MockTransactionStart("init")
   226  
   227  	timestamp, err := stub.GetTxTimestamp()
   228  	if timestamp == nil || err != nil {
   229  		t.FailNow()
   230  	}
   231  
   232  	stub.MockTransactionEnd("init")
   233  }