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 }