go.temporal.io/server@v1.23.0/common/headers/version_checker_test.go (about)

     1  // The MIT License
     2  //
     3  // Copyright (c) 2020 Temporal Technologies Inc.  All rights reserved.
     4  //
     5  // Copyright (c) 2020 Uber Technologies, Inc.
     6  //
     7  // Permission is hereby granted, free of charge, to any person obtaining a copy
     8  // of this software and associated documentation files (the "Software"), to deal
     9  // in the Software without restriction, including without limitation the rights
    10  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    11  // copies of the Software, and to permit persons to whom the Software is
    12  // furnished to do so, subject to the following conditions:
    13  //
    14  // The above copyright notice and this permission notice shall be included in
    15  // all copies or substantial portions of the Software.
    16  //
    17  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    18  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    19  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    20  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    21  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    22  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    23  // THE SOFTWARE.
    24  
    25  package headers
    26  
    27  import (
    28  	"context"
    29  	"strings"
    30  	"testing"
    31  
    32  	"github.com/stretchr/testify/require"
    33  	"github.com/stretchr/testify/suite"
    34  	"go.temporal.io/api/serviceerror"
    35  )
    36  
    37  type (
    38  	VersionCheckerSuite struct {
    39  		*require.Assertions
    40  		suite.Suite
    41  	}
    42  )
    43  
    44  func TestVersionCheckerSuite(t *testing.T) {
    45  	suite.Run(t, new(VersionCheckerSuite))
    46  }
    47  
    48  func (s *VersionCheckerSuite) SetupTest() {
    49  	s.Assertions = require.New(s.T())
    50  }
    51  
    52  func (s *VersionCheckerSuite) TestClientSupported() {
    53  	serverVersion := "22.8.78"
    54  	myFeature := "my-new-feature-flag"
    55  
    56  	testCases := []struct {
    57  		callContext       context.Context
    58  		expectErr         bool
    59  		supportsMyFeature bool
    60  	}{
    61  		{
    62  			callContext: context.Background(),
    63  			expectErr:   false,
    64  		},
    65  		{
    66  			callContext: s.constructCallContext("", "unknown-client", "", ""),
    67  			expectErr:   false,
    68  		},
    69  		{
    70  			callContext: s.constructCallContext("0.0.0", "", "", ""),
    71  			expectErr:   false,
    72  		},
    73  		{
    74  			callContext: s.constructCallContext("0.0.0", "unknown-client", "", ""),
    75  			expectErr:   false,
    76  		},
    77  		{
    78  			callContext: s.constructCallContext("malformed-version", ClientNameGoSDK, "", ""),
    79  			expectErr:   true,
    80  		},
    81  		{
    82  			callContext: s.constructCallContext("3.0.1", ClientNameGoSDK, "", ""),
    83  			expectErr:   true,
    84  		},
    85  		{
    86  			callContext: s.constructCallContext("2.4.5", ClientNameGoSDK, "", ""),
    87  			expectErr:   false,
    88  		},
    89  		{
    90  			callContext: s.constructCallContext("2.4.5", ClientNameGoSDK, "<23.1.0", ""),
    91  			expectErr:   false,
    92  		},
    93  		{
    94  			callContext: s.constructCallContext("2.4.5", ClientNameGoSDK, ">23.1.0", ""),
    95  			expectErr:   true,
    96  		},
    97  		{
    98  			callContext: s.constructCallContext("2.4.5", ClientNameGoSDK, "<1.0.0 >=3.5.6 || >22.0.0", ""),
    99  			expectErr:   false,
   100  		},
   101  		{
   102  			callContext: s.constructCallContext("", ClientNameGoSDK, "<1.0.0 >=3.5.6 || >22.0.0", ""),
   103  			expectErr:   false,
   104  		},
   105  		{
   106  			callContext:       s.constructCallContext("2.4.5", ClientNameGoSDK, "", myFeature),
   107  			supportsMyFeature: true,
   108  		},
   109  		{
   110  			callContext: s.constructCallContext("2.4.5", ClientNameGoSDK, "",
   111  				strings.Join([]string{"another-feature", myFeature, "third-feature"}, SupportedFeaturesHeaderDelim)),
   112  			supportsMyFeature: true,
   113  		},
   114  	}
   115  
   116  	versionChecker := NewVersionChecker(map[string]string{
   117  		ClientNameGoSDK: "<3.0.0",
   118  	}, serverVersion)
   119  
   120  	for caseIndex, tc := range testCases {
   121  		err := versionChecker.ClientSupported(tc.callContext)
   122  		if tc.expectErr {
   123  			s.Errorf(err, "Case #%d", caseIndex)
   124  			switch err.(type) {
   125  			case *serviceerror.InvalidArgument, *serviceerror.ClientVersionNotSupported, *serviceerror.ServerVersionNotSupported:
   126  			default:
   127  				s.Fail("error has wrong type: %T", err)
   128  			}
   129  		} else {
   130  			s.NoErrorf(err, "Case #%d", caseIndex)
   131  		}
   132  
   133  		if tc.callContext != nil {
   134  			s.Equal(tc.supportsMyFeature, versionChecker.ClientSupportsFeature(tc.callContext, myFeature))
   135  		}
   136  	}
   137  }
   138  
   139  func (s *VersionCheckerSuite) constructCallContext(clientVersion, clientName, supportedServerVersions, supportedFeatures string) context.Context {
   140  	return SetVersionsForTests(context.Background(), clientVersion, clientName, supportedServerVersions, supportedFeatures)
   141  }