github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/protos/utils/commonutils_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 utils
    18  
    19  import (
    20  	"bytes"
    21  	"errors"
    22  	"testing"
    23  
    24  	"github.com/golang/protobuf/proto"
    25  	"github.com/hyperledger/fabric/common/crypto"
    26  	cb "github.com/hyperledger/fabric/protos/common"
    27  	pb "github.com/hyperledger/fabric/protos/peer"
    28  	"github.com/stretchr/testify/assert"
    29  )
    30  
    31  func TestNonceRandomness(t *testing.T) {
    32  	n1, err := CreateNonce()
    33  	if err != nil {
    34  		t.Fatal(err)
    35  	}
    36  	n2, err := CreateNonce()
    37  	if err != nil {
    38  		t.Fatal(err)
    39  	}
    40  	if bytes.Equal(n1, n2) {
    41  		t.Fatalf("Expected nonces to be different, got %x and %x", n1, n2)
    42  	}
    43  }
    44  
    45  func TestNonceLength(t *testing.T) {
    46  	n, err := CreateNonce()
    47  	if err != nil {
    48  		t.Fatal(err)
    49  	}
    50  	actual := len(n)
    51  	expected := crypto.NonceSize
    52  	if actual != expected {
    53  		t.Fatalf("Expected nonce to be of size %d, got %d instead", expected, actual)
    54  	}
    55  
    56  }
    57  
    58  func TestUnmarshalPayload(t *testing.T) {
    59  	var payload *cb.Payload
    60  	good, _ := proto.Marshal(&cb.Payload{
    61  		Data: []byte("payload"),
    62  	})
    63  	payload, err := UnmarshalPayload(good)
    64  	assert.NoError(t, err, "Unexpected error unmarshaling payload")
    65  	assert.NotNil(t, payload, "Payload should not be nil")
    66  	payload = UnmarshalPayloadOrPanic(good)
    67  	assert.NotNil(t, payload, "Payload should not be nil")
    68  
    69  	bad := []byte("bad payload")
    70  	assert.Panics(t, func() {
    71  		_ = UnmarshalPayloadOrPanic(bad)
    72  	}, "Expected panic unmarshaling malformed payload")
    73  
    74  }
    75  
    76  func TestUnmarshalEnvelope(t *testing.T) {
    77  	var env *cb.Envelope
    78  	good, _ := proto.Marshal(&cb.Envelope{})
    79  	env, err := UnmarshalEnvelope(good)
    80  	assert.NoError(t, err, "Unexpected error unmarshaling envelope")
    81  	assert.NotNil(t, env, "Envelope should not be nil")
    82  	env = UnmarshalEnvelopeOrPanic(good)
    83  	assert.NotNil(t, env, "Envelope should not be nil")
    84  
    85  	bad := []byte("bad envelope")
    86  	assert.Panics(t, func() {
    87  		_ = UnmarshalEnvelopeOrPanic(bad)
    88  	}, "Expected panic unmarshaling malformed envelope")
    89  
    90  }
    91  
    92  func TestUnmarshalEnvelopeOfType(t *testing.T) {
    93  	env := &cb.Envelope{}
    94  
    95  	env.Payload = []byte("bad payload")
    96  	_, err := UnmarshalEnvelopeOfType(env, cb.HeaderType_CONFIG, nil)
    97  	assert.Error(t, err, "Expected error unmarshaling malformed envelope")
    98  
    99  	payload, _ := proto.Marshal(&cb.Payload{
   100  		Header: nil,
   101  	})
   102  	env.Payload = payload
   103  	_, err = UnmarshalEnvelopeOfType(env, cb.HeaderType_CONFIG, nil)
   104  	assert.Error(t, err, "Expected error with missing payload header")
   105  
   106  	payload, _ = proto.Marshal(&cb.Payload{
   107  		Header: &cb.Header{
   108  			ChannelHeader: []byte("bad header"),
   109  		},
   110  	})
   111  	env.Payload = payload
   112  	_, err = UnmarshalEnvelopeOfType(env, cb.HeaderType_CONFIG, nil)
   113  	assert.Error(t, err, "Expected error for malformed channel header")
   114  
   115  	chdr, _ := proto.Marshal(&cb.ChannelHeader{
   116  		Type: int32(cb.HeaderType_CHAINCODE_PACKAGE),
   117  	})
   118  	payload, _ = proto.Marshal(&cb.Payload{
   119  		Header: &cb.Header{
   120  			ChannelHeader: chdr,
   121  		},
   122  	})
   123  	env.Payload = payload
   124  	_, err = UnmarshalEnvelopeOfType(env, cb.HeaderType_CONFIG, nil)
   125  	assert.Error(t, err, "Expected error for wrong channel header type")
   126  
   127  	chdr, _ = proto.Marshal(&cb.ChannelHeader{
   128  		Type: int32(cb.HeaderType_CONFIG),
   129  	})
   130  	payload, _ = proto.Marshal(&cb.Payload{
   131  		Header: &cb.Header{
   132  			ChannelHeader: chdr,
   133  		},
   134  		Data: []byte("bad data"),
   135  	})
   136  	env.Payload = payload
   137  	_, err = UnmarshalEnvelopeOfType(env, cb.HeaderType_CONFIG, &cb.ConfigEnvelope{})
   138  	assert.Error(t, err, "Expected error for malformed payload data")
   139  
   140  	chdr, _ = proto.Marshal(&cb.ChannelHeader{
   141  		Type: int32(cb.HeaderType_CONFIG),
   142  	})
   143  	configEnv, _ := proto.Marshal(&cb.ConfigEnvelope{})
   144  	payload, _ = proto.Marshal(&cb.Payload{
   145  		Header: &cb.Header{
   146  			ChannelHeader: chdr,
   147  		},
   148  		Data: configEnv,
   149  	})
   150  	env.Payload = payload
   151  	_, err = UnmarshalEnvelopeOfType(env, cb.HeaderType_CONFIG, &cb.ConfigEnvelope{})
   152  	assert.NoError(t, err, "Unexpected error unmarshaling envelope")
   153  
   154  }
   155  
   156  func TestExtractEnvelopeNilData(t *testing.T) {
   157  	block := &cb.Block{}
   158  	_, err := ExtractEnvelope(block, 0)
   159  	assert.Error(t, err, "Nil data")
   160  }
   161  
   162  func TestExtractEnvelopeWrongIndex(t *testing.T) {
   163  	block := testBlock()
   164  	if _, err := ExtractEnvelope(block, len(block.GetData().Data)); err == nil {
   165  		t.Fatal("Expected envelope extraction to fail (wrong index)")
   166  	}
   167  }
   168  
   169  func TestExtractEnvelopeWrongIndexOrPanic(t *testing.T) {
   170  	defer func() {
   171  		if r := recover(); r == nil {
   172  			t.Fatal("Expected envelope extraction to panic (wrong index)")
   173  		}
   174  	}()
   175  
   176  	block := testBlock()
   177  	ExtractEnvelopeOrPanic(block, len(block.GetData().Data))
   178  }
   179  
   180  func TestExtractEnvelope(t *testing.T) {
   181  	if envelope, err := ExtractEnvelope(testBlock(), 0); err != nil {
   182  		t.Fatalf("Expected envelop extraction to succeed: %s", err)
   183  	} else if !proto.Equal(envelope, testEnvelope()) {
   184  		t.Fatal("Expected extracted envelope to match test envelope")
   185  	}
   186  }
   187  
   188  func TestExtractEnvelopeOrPanic(t *testing.T) {
   189  	defer func() {
   190  		if r := recover(); r != nil {
   191  			t.Fatal("Expected envelope extraction to succeed")
   192  		}
   193  	}()
   194  
   195  	if !proto.Equal(ExtractEnvelopeOrPanic(testBlock(), 0), testEnvelope()) {
   196  		t.Fatal("Expected extracted envelope to match test envelope")
   197  	}
   198  }
   199  
   200  func TestExtractPayload(t *testing.T) {
   201  	if payload, err := ExtractPayload(testEnvelope()); err != nil {
   202  		t.Fatalf("Expected payload extraction to succeed: %s", err)
   203  	} else if !proto.Equal(payload, testPayload()) {
   204  		t.Fatal("Expected extracted payload to match test payload")
   205  	}
   206  }
   207  
   208  func TestExtractPayloadOrPanic(t *testing.T) {
   209  	defer func() {
   210  		if r := recover(); r != nil {
   211  			t.Fatal("Expected payload extraction to succeed")
   212  		}
   213  	}()
   214  
   215  	if !proto.Equal(ExtractPayloadOrPanic(testEnvelope()), testPayload()) {
   216  		t.Fatal("Expected extracted payload to match test payload")
   217  	}
   218  }
   219  
   220  func TestUnmarshalChaincodeID(t *testing.T) {
   221  	ccname := "mychaincode"
   222  	ccversion := "myversion"
   223  	ccidbytes, _ := proto.Marshal(&pb.ChaincodeID{
   224  		Name:    ccname,
   225  		Version: ccversion,
   226  	})
   227  	ccid, err := UnmarshalChaincodeID(ccidbytes)
   228  	assert.Equal(t, ccname, ccid.Name, "Expected ccid names to match")
   229  	assert.Equal(t, ccversion, ccid.Version, "Expected ccid versions to match")
   230  
   231  	_, err = UnmarshalChaincodeID([]byte("bad chaincodeID"))
   232  	assert.Error(t, err, "Expected error marshaling malformed chaincode ID")
   233  }
   234  
   235  func TestNewSignatureHeaderOrPanic(t *testing.T) {
   236  	var sigHeader *cb.SignatureHeader
   237  
   238  	sigHeader = NewSignatureHeaderOrPanic(goodSigner)
   239  	assert.NotNil(t, sigHeader, "Signature header should not be nil")
   240  
   241  	assert.Panics(t, func() {
   242  		_ = NewSignatureHeaderOrPanic(nil)
   243  	}, "Expected panic with nil signer")
   244  
   245  	assert.Panics(t, func() {
   246  		_ = NewSignatureHeaderOrPanic(badSigner)
   247  	}, "Expected panic with signature header error")
   248  
   249  }
   250  
   251  func TestSignOrPanic(t *testing.T) {
   252  	msg := []byte("sign me")
   253  	sig := SignOrPanic(goodSigner, msg)
   254  	// mock signer returns message to be signed
   255  	assert.Equal(t, msg, sig, "Signature does not match expected value")
   256  
   257  	assert.Panics(t, func() {
   258  		_ = SignOrPanic(nil, []byte("sign me"))
   259  	}, "Expected panic with nil signer")
   260  
   261  	assert.Panics(t, func() {
   262  		_ = SignOrPanic(badSigner, []byte("sign me"))
   263  	}, "Expected panic with sign error")
   264  }
   265  
   266  // Helper functions
   267  
   268  func testPayload() *cb.Payload {
   269  	return &cb.Payload{
   270  		Header: MakePayloadHeader(
   271  			MakeChannelHeader(cb.HeaderType_MESSAGE, int32(1), "test", 0),
   272  			MakeSignatureHeader([]byte("creator"), []byte("nonce"))),
   273  		Data: []byte("test"),
   274  	}
   275  }
   276  
   277  func testEnvelope() *cb.Envelope {
   278  	// No need to set the signature
   279  	return &cb.Envelope{Payload: MarshalOrPanic(testPayload())}
   280  }
   281  
   282  func testBlock() *cb.Block {
   283  	// No need to set the block's Header, or Metadata
   284  	return &cb.Block{
   285  		Data: &cb.BlockData{
   286  			Data: [][]byte{MarshalOrPanic(testEnvelope())},
   287  		},
   288  	}
   289  }
   290  
   291  // mock
   292  var badSigner = &mockLocalSigner{
   293  	returnError: true,
   294  }
   295  
   296  var goodSigner = &mockLocalSigner{
   297  	returnError: false,
   298  }
   299  
   300  type mockLocalSigner struct {
   301  	returnError bool
   302  }
   303  
   304  func (m *mockLocalSigner) NewSignatureHeader() (*cb.SignatureHeader, error) {
   305  	if m.returnError {
   306  		return nil, errors.New("signature header error")
   307  	}
   308  	return &cb.SignatureHeader{}, nil
   309  }
   310  
   311  func (m *mockLocalSigner) Sign(message []byte) ([]byte, error) {
   312  	if m.returnError {
   313  		return nil, errors.New("sign error")
   314  	}
   315  	return message, nil
   316  }