github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/common/errors/errors_test.go (about)

     1  /*
     2   Copyright Digital Asset Holdings, LLC 2016 All Rights Reserved.
     3   Copyright IBM Corp. 2017 All Rights Reserved.
     4  
     5   Licensed under the Apache License, Version 2.0 (the "License");
     6   you may not use this file except in compliance with the License.
     7   You may obtain a copy of the License at
     8  
     9        http://www.apache.org/licenses/LICENSE-2.0
    10  
    11   Unless required by applicable law or agreed to in writing, software
    12   distributed under the License is distributed on an "AS IS" BASIS,
    13   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   See the License for the specific language governing permissions and
    15   limitations under the License.
    16  */
    17  
    18  package errors
    19  
    20  import (
    21  	"fmt"
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  )
    26  
    27  type testCase struct {
    28  	name               string
    29  	errorArgs          []string
    30  	messageArgs        []string
    31  	wrappedErrorArgs   []string
    32  	wrappedMessageArgs []string
    33  	generateStack      []bool
    34  }
    35  
    36  func TestError(t *testing.T) {
    37  	var tc []testCase
    38  
    39  	tc = append(tc,
    40  		testCase{"UnknownErrorWithCallstack", []string{Core, NotFound, "An unknown error occurred."}, nil, nil, nil, []bool{true}},
    41  		testCase{"UnknownError", []string{MSP, Forbidden, "An unknown error occurred."}, nil, nil, nil, []bool{false}},
    42  		testCase{"UnknownErrorWithCallstackAndArg", []string{Ledger, Conflict, "An error occurred: %s"}, []string{"arg1"}, nil, nil, []bool{true}},
    43  		testCase{"UnknownErrorWithArg", []string{SystemChaincode, Internal, "An error occurred: %s"}, []string{"arg1"}, nil, nil, []bool{false}},
    44  		testCase{"CallStackErrorWrappedCallstackError", []string{BCCSP, NotImplemented, "An unknown error occurred."}, nil, []string{Peer, UpgradeRequired, "An unknown error occurred."}, nil, []bool{true, true}},
    45  		testCase{"ErrorWrappedError", []string{Common, Unavailable, "An unknown error occurred."}, nil, []string{SystemChaincode, Gone, "An unknown error occurred."}, nil, []bool{false, false}},
    46  		testCase{"CallStackErrorWrappedError", []string{Event, Timeout, "An unknown error occurred."}, nil, []string{Orderer, NetworkIO, "An unknown error occurred."}, nil, []bool{true, false}},
    47  		testCase{"ErrorWrappedCallStackError", []string{Orderer, UnprocessableEntity, "An unknown error occurred."}, nil, []string{"UNK", "404", "An unknown error occurred."}, nil, []bool{false, true}},
    48  		testCase{"ErrorWrappedStandardError", []string{DeliveryService, Unavailable, "An unknown error occurred."}, nil, []string{"grpc timed out: %s"}, []string{"failed to connect to server"}, []bool{false, true}},
    49  	)
    50  
    51  	assert := assert.New(t)
    52  
    53  	for i := 0; i < len(tc); i++ {
    54  		t.Run(tc[i].name, func(t *testing.T) {
    55  			var err, wrappedErr CallStackError
    56  			var wrappedStandardError error
    57  
    58  			// generate callstack
    59  			if tc[i].generateStack[0] {
    60  				if tc[i].messageArgs != nil {
    61  					err = ErrorWithCallstack(tc[i].errorArgs[0], tc[i].errorArgs[1], tc[i].errorArgs[2], tc[i].messageArgs)
    62  				} else {
    63  					err = ErrorWithCallstack(tc[i].errorArgs[0], tc[i].errorArgs[1], tc[i].errorArgs[2])
    64  				}
    65  				assert.NotEqual("", err.GetStack(), "Test case '%s' failed", tc[i].name)
    66  				assert.Contains(err.Error(), "github.com/hyperledger/fabric/common/errors", "Test case '%s' failed", tc[i].name)
    67  			} else {
    68  				if tc[i].messageArgs != nil {
    69  					err = Error(tc[i].errorArgs[0], tc[i].errorArgs[1], tc[i].errorArgs[2], tc[i].messageArgs)
    70  				} else {
    71  					err = Error(tc[i].errorArgs[0], tc[i].errorArgs[1], tc[i].errorArgs[2])
    72  				}
    73  				assert.Equal("", err.GetStack(), "Test case '%s' failed", tc[i].name)
    74  				assert.NotContains(err.Error(), "github.com/hyperledger/fabric/common/errors", "Test case '%s' failed", tc[i].name)
    75  			}
    76  			assert.Equal(tc[i].errorArgs[0], err.GetComponentCode(), "Test case '%s' failed", tc[i].name)
    77  			assert.Equal(tc[i].errorArgs[1], err.GetReasonCode(), "Test case '%s' failed", tc[i].name)
    78  			if tc[i].messageArgs != nil {
    79  				assert.Contains(err.Error(), fmt.Sprintf(tc[i].errorArgs[2], tc[i].messageArgs), "Test case '%s' failed", tc[i].name)
    80  			} else {
    81  				assert.Contains(err.Error(), tc[i].errorArgs[2], "Test case '%s' failed", tc[i].name)
    82  			}
    83  			assert.NotContains(err.Message(), "github.com/hyperledger/fabric/common/errors", "Test case '%s' failed", tc[i].name)
    84  
    85  			if tc[i].wrappedErrorArgs != nil {
    86  				if len(tc[i].wrappedErrorArgs) == 3 {
    87  					if tc[i].generateStack[1] {
    88  						if tc[i].wrappedMessageArgs != nil {
    89  							wrappedErr = ErrorWithCallstack(tc[i].wrappedErrorArgs[0], tc[i].wrappedErrorArgs[1], tc[i].wrappedErrorArgs[2], tc[i].wrappedMessageArgs)
    90  						} else {
    91  							wrappedErr = ErrorWithCallstack(tc[i].wrappedErrorArgs[0], tc[i].wrappedErrorArgs[1], tc[i].wrappedErrorArgs[2])
    92  						}
    93  						assert.NotEqual("", wrappedErr.GetStack(), "Test case '%s' failed", tc[i].name)
    94  						assert.Contains(wrappedErr.Error(), "github.com/hyperledger/fabric/common/errors", "Test case '%s' failed", tc[i].name)
    95  					} else {
    96  						if tc[i].wrappedMessageArgs != nil {
    97  							wrappedErr = Error(tc[i].wrappedErrorArgs[0], tc[i].wrappedErrorArgs[1], tc[i].wrappedErrorArgs[2], tc[i].wrappedMessageArgs)
    98  						} else {
    99  							wrappedErr = Error(tc[i].wrappedErrorArgs[0], tc[i].wrappedErrorArgs[1], tc[i].wrappedErrorArgs[2])
   100  						}
   101  						assert.Equal("", wrappedErr.GetStack(), "Test case '%s' failed", tc[i].name)
   102  						assert.NotContains(wrappedErr.Error(), "github.com/hyperledger/fabric/common/errors", "Test case '%s' failed", tc[i].name)
   103  					}
   104  					assert.Equal(tc[i].wrappedErrorArgs[0], wrappedErr.GetComponentCode(), "Test case '%s' failed", tc[i].name)
   105  					assert.Equal(tc[i].wrappedErrorArgs[1], wrappedErr.GetReasonCode(), "Test case '%s' failed", tc[i].name)
   106  					err = err.WrapError(wrappedErr)
   107  					if tc[i].wrappedMessageArgs != nil {
   108  						assert.Contains(err.Error(), fmt.Sprintf(tc[i].wrappedErrorArgs[2], tc[i].wrappedMessageArgs), "Test case '%s' failed", tc[i].name)
   109  					} else {
   110  						assert.Contains(err.Error(), tc[i].wrappedErrorArgs[2], "Test case '%s' failed", tc[i].name)
   111  					}
   112  				} else {
   113  					wrappedStandardError = fmt.Errorf(tc[i].wrappedErrorArgs[0], tc[i].wrappedMessageArgs)
   114  					err = err.WrapError(wrappedStandardError)
   115  					assert.Contains(err.Error(), fmt.Sprintf(tc[i].wrappedErrorArgs[0], tc[i].wrappedMessageArgs), "Test case '%s' failed", tc[i].name)
   116  
   117  				}
   118  				assert.Contains(err.Error(), "Caused by:", "Test case '%s' failed", tc[i].name)
   119  				assert.NotContains(err.Message(), "github.com/hyperledger/fabric/common/errors", "Test case '%s' failed", tc[i].name)
   120  			}
   121  		})
   122  	}
   123  }
   124  
   125  func TestIsValidComponentOrReasonCode(t *testing.T) {
   126  	validComponents := []string{"LGR", "CHA", "PER", "xyz", "aBc"}
   127  	for _, component := range validComponents {
   128  		if ok := isValidComponentOrReasonCode(component, componentPattern); !ok {
   129  			t.FailNow()
   130  		}
   131  	}
   132  
   133  	validReasons := []string{"404", "500", "999"}
   134  	for _, reason := range validReasons {
   135  		if ok := isValidComponentOrReasonCode(reason, reasonPattern); !ok {
   136  			t.FailNow()
   137  		}
   138  	}
   139  
   140  	invalidComponents := []string{"LEDG", "CH", "P3R", "123", ""}
   141  	for _, component := range invalidComponents {
   142  		if ok := isValidComponentOrReasonCode(component, componentPattern); ok {
   143  			t.FailNow()
   144  		}
   145  	}
   146  
   147  	invalidReasons := []string{"4045", "E12", "ZZZ", "1", ""}
   148  	for _, reason := range invalidReasons {
   149  		if ok := isValidComponentOrReasonCode(reason, reasonPattern); ok {
   150  			t.FailNow()
   151  		}
   152  	}
   153  
   154  }