go.temporal.io/server@v1.23.0/common/rpc/interceptor/namespace_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 interceptor
    26  
    27  import (
    28  	"errors"
    29  	"fmt"
    30  	"reflect"
    31  	"testing"
    32  
    33  	"github.com/golang/mock/gomock"
    34  	"github.com/stretchr/testify/require"
    35  	"github.com/stretchr/testify/suite"
    36  	"go.temporal.io/api/workflowservice/v1"
    37  
    38  	"go.temporal.io/server/api/historyservice/v1"
    39  	"go.temporal.io/server/api/matchingservice/v1"
    40  	"go.temporal.io/server/common/namespace"
    41  )
    42  
    43  type (
    44  	namespaceSuite struct {
    45  		suite.Suite
    46  		*require.Assertions
    47  	}
    48  )
    49  
    50  var (
    51  	frontendAPIExcluded = map[string]struct{}{
    52  		"GetClusterInfo":      {},
    53  		"GetSystemInfo":       {},
    54  		"GetSearchAttributes": {},
    55  		"ListNamespaces":      {},
    56  	}
    57  
    58  	matchingAPIExcluded = map[string]struct{}{
    59  		"ListTaskQueuePartitions": {},
    60  	}
    61  
    62  	historyAPIExcluded = map[string]struct{}{
    63  		"CloseShard":                {},
    64  		"GetShard":                  {},
    65  		"GetDLQMessages":            {},
    66  		"GetDLQReplicationMessages": {},
    67  		"GetReplicationMessages":    {},
    68  		"MergeDLQMessages":          {},
    69  		"PurgeDLQMessages":          {},
    70  		"RemoveTask":                {},
    71  		"SyncShardStatus":           {},
    72  		"GetReplicationStatus":      {},
    73  		"GetDLQTasks":               {},
    74  		"DeleteDLQTasks":            {},
    75  		"AddTasks":                  {},
    76  		"ListQueues":                {},
    77  	}
    78  )
    79  
    80  func TestNamespaceSuite(t *testing.T) {
    81  	s := new(namespaceSuite)
    82  	suite.Run(t, s)
    83  }
    84  
    85  func (s *namespaceSuite) SetupTest() {
    86  	s.Assertions = require.New(s.T())
    87  }
    88  
    89  func (s *namespaceSuite) TearDownTest() {
    90  
    91  }
    92  
    93  func (s *namespaceSuite) TestFrontendAPIMetrics() {
    94  	namespaceNameGetter := reflect.TypeOf((*NamespaceNameGetter)(nil)).Elem()
    95  
    96  	var service workflowservice.WorkflowServiceServer
    97  	t := reflect.TypeOf(&service).Elem()
    98  	for i := 0; i < t.NumMethod(); i++ {
    99  		method := t.Method(i)
   100  		methodName := method.Name
   101  		methodType := method.Type
   102  
   103  		// 0th parameter is context.Context
   104  		// 1th parameter is the request
   105  		if _, ok := frontendAPIExcluded[methodName]; ok {
   106  			continue
   107  		}
   108  		if methodType.NumIn() < 2 {
   109  			continue
   110  		}
   111  		request := methodType.In(1)
   112  		if !request.Implements(namespaceNameGetter) {
   113  			s.Fail(fmt.Sprintf("API: %v not implementing NamespaceNameGetter", methodName))
   114  		}
   115  	}
   116  }
   117  
   118  func (s *namespaceSuite) TestMatchingAPIMetrics() {
   119  	namespaceIDGetter := reflect.TypeOf((*NamespaceIDGetter)(nil)).Elem()
   120  
   121  	var service matchingservice.MatchingServiceServer
   122  	t := reflect.TypeOf(&service).Elem()
   123  	for i := 0; i < t.NumMethod(); i++ {
   124  		method := t.Method(i)
   125  		methodName := method.Name
   126  		methodType := method.Type
   127  
   128  		// 0th parameter is context.Context
   129  		// 1th parameter is the request
   130  		if _, ok := matchingAPIExcluded[methodName]; ok {
   131  			continue
   132  		}
   133  		if methodType.NumIn() < 2 {
   134  			continue
   135  		}
   136  		request := methodType.In(1)
   137  		if !request.Implements(namespaceIDGetter) {
   138  			s.Fail(fmt.Sprintf("API: %v not implementing NamespaceIDGetter", methodName))
   139  		}
   140  	}
   141  }
   142  
   143  func (s *namespaceSuite) TestHistoryAPIMetrics() {
   144  	namespaceIDGetter := reflect.TypeOf((*NamespaceIDGetter)(nil)).Elem()
   145  
   146  	var service historyservice.HistoryServiceServer
   147  	t := reflect.TypeOf(&service).Elem()
   148  	for i := 0; i < t.NumMethod(); i++ {
   149  		method := t.Method(i)
   150  		methodName := method.Name
   151  		methodType := method.Type
   152  
   153  		// 0th parameter is context.Context
   154  		// 1th parameter is the request
   155  		if _, ok := historyAPIExcluded[methodName]; ok {
   156  			continue
   157  		}
   158  		if methodType.NumIn() < 2 {
   159  			continue
   160  		}
   161  		request := methodType.In(1)
   162  		if !request.Implements(namespaceIDGetter) {
   163  			s.Fail(fmt.Sprintf("API: %v not implementing NamespaceIDGetter", methodName))
   164  		}
   165  	}
   166  }
   167  
   168  func (s *namespaceSuite) TestGetNamespace() {
   169  	register := namespace.NewMockRegistry(gomock.NewController(s.T()))
   170  	register.EXPECT().GetNamespace(namespace.Name("exist")).Return(nil, nil)
   171  	register.EXPECT().GetNamespace(namespace.Name("nonexist")).Return(nil, errors.New("not found"))
   172  	register.EXPECT().GetNamespaceName(namespace.ID("exist")).Return(namespace.Name("exist"), nil)
   173  	register.EXPECT().GetNamespaceName(namespace.ID("nonexist")).Return(namespace.EmptyName, errors.New("not found"))
   174  	testCases := []struct {
   175  		method        interface{}
   176  		namespaceName namespace.Name
   177  	}{
   178  		{
   179  			&workflowservice.DescribeNamespaceRequest{Namespace: "exist"},
   180  			namespace.Name("exist"),
   181  		},
   182  		{
   183  			&workflowservice.DescribeNamespaceRequest{Namespace: "nonexist"},
   184  			namespace.EmptyName,
   185  		},
   186  		{
   187  			&historyservice.DescribeMutableStateRequest{NamespaceId: "exist"},
   188  			namespace.Name("exist"),
   189  		},
   190  		{
   191  			&historyservice.DescribeMutableStateRequest{NamespaceId: "nonexist"},
   192  			namespace.EmptyName,
   193  		},
   194  	}
   195  
   196  	for _, testCase := range testCases {
   197  		extractedNamespace := MustGetNamespaceName(register, testCase.method)
   198  		s.Equal(testCase.namespaceName, extractedNamespace)
   199  	}
   200  }