go.temporal.io/server@v1.23.0/common/namespace/replication_task_executor_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 namespace
    26  
    27  import (
    28  	"context"
    29  	"errors"
    30  	"testing"
    31  	"time"
    32  
    33  	"github.com/golang/mock/gomock"
    34  	"github.com/pborman/uuid"
    35  	"github.com/stretchr/testify/suite"
    36  	enumspb "go.temporal.io/api/enums/v1"
    37  	namespacepb "go.temporal.io/api/namespace/v1"
    38  	replicationpb "go.temporal.io/api/replication/v1"
    39  	"go.temporal.io/api/serviceerror"
    40  	"google.golang.org/protobuf/types/known/durationpb"
    41  	"google.golang.org/protobuf/types/known/timestamppb"
    42  
    43  	enumsspb "go.temporal.io/server/api/enums/v1"
    44  	persistencespb "go.temporal.io/server/api/persistence/v1"
    45  	replicationspb "go.temporal.io/server/api/replication/v1"
    46  	"go.temporal.io/server/common/log"
    47  	"go.temporal.io/server/common/persistence"
    48  )
    49  
    50  type (
    51  	namespaceReplicationTaskExecutorSuite struct {
    52  		suite.Suite
    53  		controller *gomock.Controller
    54  
    55  		mockMetadataMgr     *persistence.MockMetadataManager
    56  		namespaceReplicator *namespaceReplicationTaskExecutorImpl
    57  	}
    58  )
    59  
    60  func TestNamespaceReplicationTaskExecutorSuite(t *testing.T) {
    61  	s := new(namespaceReplicationTaskExecutorSuite)
    62  	suite.Run(t, s)
    63  }
    64  
    65  func (s *namespaceReplicationTaskExecutorSuite) SetupSuite() {
    66  }
    67  
    68  func (s *namespaceReplicationTaskExecutorSuite) TearDownSuite() {
    69  
    70  }
    71  
    72  func (s *namespaceReplicationTaskExecutorSuite) SetupTest() {
    73  	s.controller = gomock.NewController(s.T())
    74  	s.mockMetadataMgr = persistence.NewMockMetadataManager(s.controller)
    75  	logger := log.NewTestLogger()
    76  	s.namespaceReplicator = NewReplicationTaskExecutor(
    77  		"some random standby cluster name",
    78  		s.mockMetadataMgr,
    79  		logger,
    80  	).(*namespaceReplicationTaskExecutorImpl)
    81  }
    82  
    83  func (s *namespaceReplicationTaskExecutorSuite) TearDownTest() {
    84  	s.controller.Finish()
    85  }
    86  
    87  func (s *namespaceReplicationTaskExecutorSuite) TestExecute_RegisterNamespaceTask_NameUUIDCollision() {
    88  	operation := enumsspb.NAMESPACE_OPERATION_CREATE
    89  	id := uuid.New()
    90  	name := "some random namespace test name"
    91  	state := enumspb.NAMESPACE_STATE_REGISTERED
    92  	description := "some random test description"
    93  	ownerEmail := "some random test owner"
    94  	data := map[string]string{"k": "v"}
    95  	retention := 10 * time.Hour * 24
    96  	historyArchivalState := enumspb.ARCHIVAL_STATE_ENABLED
    97  	historyArchivalURI := "some random history archival uri"
    98  	visibilityArchivalState := enumspb.ARCHIVAL_STATE_ENABLED
    99  	visibilityArchivalURI := "some random visibility archival uri"
   100  	clusterActive := "some random active cluster name"
   101  	clusterStandby := "some random standby cluster name"
   102  	configVersion := int64(0)
   103  	failoverVersion := int64(59)
   104  	clusters := []*replicationpb.ClusterReplicationConfig{
   105  		{
   106  			ClusterName: clusterActive,
   107  		},
   108  		{
   109  			ClusterName: clusterStandby,
   110  		},
   111  	}
   112  
   113  	task := &replicationspb.NamespaceTaskAttributes{
   114  		NamespaceOperation: operation,
   115  		Id:                 id,
   116  		Info: &namespacepb.NamespaceInfo{
   117  			Name:        name,
   118  			State:       state,
   119  			Description: description,
   120  			OwnerEmail:  ownerEmail,
   121  			Data:        data,
   122  		},
   123  		Config: &namespacepb.NamespaceConfig{
   124  			WorkflowExecutionRetentionTtl: durationpb.New(retention),
   125  			HistoryArchivalState:          historyArchivalState,
   126  			HistoryArchivalUri:            historyArchivalURI,
   127  			VisibilityArchivalState:       visibilityArchivalState,
   128  			VisibilityArchivalUri:         visibilityArchivalURI,
   129  		},
   130  		ReplicationConfig: &replicationpb.NamespaceReplicationConfig{
   131  			ActiveClusterName: clusterActive,
   132  			Clusters:          clusters,
   133  		},
   134  		ConfigVersion:   configVersion,
   135  		FailoverVersion: failoverVersion,
   136  	}
   137  	s.mockMetadataMgr.EXPECT().GetNamespace(gomock.Any(), &persistence.GetNamespaceRequest{
   138  		Name: name,
   139  	}).Return(&persistence.GetNamespaceResponse{Namespace: &persistencespb.NamespaceDetail{
   140  		Info: &persistencespb.NamespaceInfo{
   141  			Id: uuid.New(),
   142  		},
   143  	}}, nil)
   144  	task.Id = uuid.New()
   145  	task.Info.Name = name
   146  	err := s.namespaceReplicator.Execute(context.Background(), task)
   147  	s.NotNil(err)
   148  	s.IsType(&serviceerror.InvalidArgument{}, err)
   149  
   150  	task.Id = id
   151  	task.Info.Name = "other random namespace test name"
   152  	var count int
   153  	s.mockMetadataMgr.EXPECT().GetNamespace(gomock.Any(), &persistence.GetNamespaceRequest{
   154  		Name: task.Info.Name,
   155  	}).DoAndReturn(func(_ context.Context, request *persistence.GetNamespaceRequest) (*persistence.GetNamespaceResponse, error) {
   156  		nsID := id
   157  		if count != 0 {
   158  			nsID = uuid.New()
   159  		}
   160  		count++
   161  		return &persistence.GetNamespaceResponse{Namespace: &persistencespb.NamespaceDetail{
   162  			Info: &persistencespb.NamespaceInfo{
   163  				Id: nsID,
   164  			},
   165  		}}, nil
   166  	}).Times(2)
   167  	s.mockMetadataMgr.EXPECT().CreateNamespace(gomock.Any(), gomock.Any()).Return(nil, errors.New("test"))
   168  	err = s.namespaceReplicator.Execute(context.Background(), task)
   169  	s.NotNil(err)
   170  	s.IsType(&serviceerror.InvalidArgument{}, err)
   171  }
   172  
   173  func (s *namespaceReplicationTaskExecutorSuite) TestExecute_RegisterNamespaceTask_Success() {
   174  	operation := enumsspb.NAMESPACE_OPERATION_CREATE
   175  	id := uuid.New()
   176  	name := "some random namespace test name"
   177  	state := enumspb.NAMESPACE_STATE_REGISTERED
   178  	description := "some random test description"
   179  	ownerEmail := "some random test owner"
   180  	data := map[string]string{"k": "v"}
   181  	retention := 10 * time.Hour * 24
   182  	historyArchivalState := enumspb.ARCHIVAL_STATE_ENABLED
   183  	historyArchivalURI := "some random history archival uri"
   184  	visibilityArchivalState := enumspb.ARCHIVAL_STATE_ENABLED
   185  	visibilityArchivalURI := "some random visibility archival uri"
   186  	clusterActive := "some random active cluster name"
   187  	clusterStandby := "some random standby cluster name"
   188  	configVersion := int64(0)
   189  	failoverVersion := int64(59)
   190  	clusters := []*replicationpb.ClusterReplicationConfig{
   191  		{
   192  			ClusterName: clusterActive,
   193  		},
   194  		{
   195  			ClusterName: clusterStandby,
   196  		},
   197  	}
   198  
   199  	task := &replicationspb.NamespaceTaskAttributes{
   200  		NamespaceOperation: operation,
   201  		Id:                 id,
   202  		Info: &namespacepb.NamespaceInfo{
   203  			Name:        name,
   204  			State:       state,
   205  			Description: description,
   206  			OwnerEmail:  ownerEmail,
   207  			Data:        data,
   208  		},
   209  		Config: &namespacepb.NamespaceConfig{
   210  			WorkflowExecutionRetentionTtl: durationpb.New(retention),
   211  			HistoryArchivalState:          historyArchivalState,
   212  			HistoryArchivalUri:            historyArchivalURI,
   213  			VisibilityArchivalState:       visibilityArchivalState,
   214  			VisibilityArchivalUri:         visibilityArchivalURI,
   215  		},
   216  		ReplicationConfig: &replicationpb.NamespaceReplicationConfig{
   217  			ActiveClusterName: clusterActive,
   218  			Clusters:          clusters,
   219  		},
   220  		ConfigVersion:   configVersion,
   221  		FailoverVersion: failoverVersion,
   222  	}
   223  
   224  	s.mockMetadataMgr.EXPECT().GetNamespace(gomock.Any(), &persistence.GetNamespaceRequest{Name: name}).Return(
   225  		nil, &serviceerror.NamespaceNotFound{}).Times(1)
   226  	s.mockMetadataMgr.EXPECT().CreateNamespace(gomock.Any(), &persistence.CreateNamespaceRequest{
   227  		Namespace: &persistencespb.NamespaceDetail{
   228  			Info: &persistencespb.NamespaceInfo{
   229  				Id:          id,
   230  				State:       task.Info.State,
   231  				Name:        task.Info.Name,
   232  				Description: task.Info.Description,
   233  				Owner:       task.Info.OwnerEmail,
   234  				Data:        task.Info.Data,
   235  			},
   236  			Config: &persistencespb.NamespaceConfig{
   237  				Retention:               task.Config.WorkflowExecutionRetentionTtl,
   238  				HistoryArchivalState:    task.Config.HistoryArchivalState,
   239  				HistoryArchivalUri:      task.Config.HistoryArchivalUri,
   240  				VisibilityArchivalState: task.Config.VisibilityArchivalState,
   241  				VisibilityArchivalUri:   task.Config.VisibilityArchivalUri,
   242  			},
   243  			ReplicationConfig: &persistencespb.NamespaceReplicationConfig{
   244  				ActiveClusterName: task.ReplicationConfig.ActiveClusterName,
   245  				Clusters:          []string{clusterActive, clusterStandby},
   246  			},
   247  			ConfigVersion:               configVersion,
   248  			FailoverNotificationVersion: 0,
   249  			FailoverVersion:             failoverVersion,
   250  		},
   251  		IsGlobalNamespace: true,
   252  	})
   253  	err := s.namespaceReplicator.Execute(context.Background(), task)
   254  	s.Nil(err)
   255  }
   256  
   257  func (s *namespaceReplicationTaskExecutorSuite) TestExecute_RegisterNamespaceTask_Duplicate() {
   258  	name := uuid.New()
   259  	id := uuid.New()
   260  	clusterActive := "some random active cluster name"
   261  	clusterStandby := "some random standby cluster name"
   262  	clusters := []*replicationpb.ClusterReplicationConfig{
   263  		{
   264  			ClusterName: clusterActive,
   265  		},
   266  		{
   267  			ClusterName: clusterStandby,
   268  		},
   269  	}
   270  	task := &replicationspb.NamespaceTaskAttributes{
   271  		Id:                 id,
   272  		NamespaceOperation: enumsspb.NAMESPACE_OPERATION_CREATE,
   273  		Info: &namespacepb.NamespaceInfo{
   274  			Name:  name,
   275  			State: enumspb.NAMESPACE_STATE_REGISTERED,
   276  		},
   277  		Config: &namespacepb.NamespaceConfig{},
   278  		ReplicationConfig: &replicationpb.NamespaceReplicationConfig{
   279  			ActiveClusterName: clusterActive,
   280  			Clusters:          clusters,
   281  		},
   282  	}
   283  	s.mockMetadataMgr.EXPECT().GetNamespace(gomock.Any(), &persistence.GetNamespaceRequest{
   284  		Name: name,
   285  	}).Return(&persistence.GetNamespaceResponse{Namespace: &persistencespb.NamespaceDetail{
   286  		Info: &persistencespb.NamespaceInfo{
   287  			Id: id,
   288  		},
   289  	}}, nil).Times(2)
   290  	s.mockMetadataMgr.EXPECT().GetNamespace(gomock.Any(), &persistence.GetNamespaceRequest{
   291  		ID: id,
   292  	}).Return(&persistence.GetNamespaceResponse{Namespace: &persistencespb.NamespaceDetail{
   293  		Info: &persistencespb.NamespaceInfo{
   294  			Name: name,
   295  		},
   296  	}}, nil).Times(1)
   297  	s.mockMetadataMgr.EXPECT().CreateNamespace(gomock.Any(), gomock.Any()).Return(nil, errors.New("test"))
   298  	err := s.namespaceReplicator.Execute(context.Background(), task)
   299  	s.Nil(err)
   300  }
   301  
   302  func (s *namespaceReplicationTaskExecutorSuite) TestExecute_UpdateNamespaceTask_NamespaceNotExist() {
   303  	operation := enumsspb.NAMESPACE_OPERATION_UPDATE
   304  	id := uuid.New()
   305  	name := "some random namespace test name"
   306  	state := enumspb.NAMESPACE_STATE_REGISTERED
   307  	description := "some random test description"
   308  	ownerEmail := "some random test owner"
   309  	retention := 10 * time.Hour * 24
   310  	historyArchivalState := enumspb.ARCHIVAL_STATE_ENABLED
   311  	historyArchivalURI := "some random history archival uri"
   312  	visibilityArchivalState := enumspb.ARCHIVAL_STATE_ENABLED
   313  	visibilityArchivalURI := "some random visibility archival uri"
   314  	clusterActive := "some random active cluster name"
   315  	clusterStandby := "some random standby cluster name"
   316  	configVersion := int64(12)
   317  	failoverVersion := int64(59)
   318  	namespaceData := map[string]string{"k1": "v1", "k2": "v2"}
   319  	clusters := []*replicationpb.ClusterReplicationConfig{
   320  		{
   321  			ClusterName: clusterActive,
   322  		},
   323  		{
   324  			ClusterName: clusterStandby,
   325  		},
   326  	}
   327  
   328  	updateTask := &replicationspb.NamespaceTaskAttributes{
   329  		NamespaceOperation: operation,
   330  		Id:                 id,
   331  		Info: &namespacepb.NamespaceInfo{
   332  			Name:        name,
   333  			State:       state,
   334  			Description: description,
   335  			OwnerEmail:  ownerEmail,
   336  			Data:        namespaceData,
   337  		},
   338  		Config: &namespacepb.NamespaceConfig{
   339  			WorkflowExecutionRetentionTtl: durationpb.New(retention),
   340  			HistoryArchivalState:          historyArchivalState,
   341  			HistoryArchivalUri:            historyArchivalURI,
   342  			VisibilityArchivalState:       visibilityArchivalState,
   343  			VisibilityArchivalUri:         visibilityArchivalURI,
   344  		},
   345  		ReplicationConfig: &replicationpb.NamespaceReplicationConfig{
   346  			ActiveClusterName: clusterActive,
   347  			Clusters:          clusters,
   348  		},
   349  		ConfigVersion:   configVersion,
   350  		FailoverVersion: failoverVersion,
   351  	}
   352  
   353  	s.mockMetadataMgr.EXPECT().GetMetadata(gomock.Any()).Return(&persistence.GetMetadataResponse{NotificationVersion: 0}, nil)
   354  	s.mockMetadataMgr.EXPECT().GetNamespace(gomock.Any(), &persistence.GetNamespaceRequest{Name: name}).Return(
   355  		nil, &serviceerror.NamespaceNotFound{}).Times(2)
   356  	s.mockMetadataMgr.EXPECT().CreateNamespace(gomock.Any(), &persistence.CreateNamespaceRequest{
   357  		Namespace: &persistencespb.NamespaceDetail{
   358  			Info: &persistencespb.NamespaceInfo{
   359  				Id:          id,
   360  				State:       updateTask.Info.State,
   361  				Name:        updateTask.Info.Name,
   362  				Description: updateTask.Info.Description,
   363  				Owner:       updateTask.Info.OwnerEmail,
   364  				Data:        updateTask.Info.Data,
   365  			},
   366  			Config: &persistencespb.NamespaceConfig{
   367  				Retention:               updateTask.Config.WorkflowExecutionRetentionTtl,
   368  				HistoryArchivalState:    updateTask.Config.HistoryArchivalState,
   369  				HistoryArchivalUri:      updateTask.Config.HistoryArchivalUri,
   370  				VisibilityArchivalState: updateTask.Config.VisibilityArchivalState,
   371  				VisibilityArchivalUri:   updateTask.Config.VisibilityArchivalUri,
   372  			},
   373  			ReplicationConfig: &persistencespb.NamespaceReplicationConfig{
   374  				ActiveClusterName: updateTask.ReplicationConfig.ActiveClusterName,
   375  				Clusters:          []string{clusterActive, clusterStandby},
   376  			},
   377  			ConfigVersion:               configVersion,
   378  			FailoverNotificationVersion: 0,
   379  			FailoverVersion:             failoverVersion,
   380  		},
   381  		IsGlobalNamespace: true,
   382  	})
   383  	err := s.namespaceReplicator.Execute(context.Background(), updateTask)
   384  	s.Nil(err)
   385  }
   386  
   387  func (s *namespaceReplicationTaskExecutorSuite) TestExecute_UpdateNamespaceTask_UpdateConfig_UpdateActiveCluster() {
   388  	id := uuid.New()
   389  	name := "some random namespace test name"
   390  	updateOperation := enumsspb.NAMESPACE_OPERATION_UPDATE
   391  	updateState := enumspb.NAMESPACE_STATE_DEPRECATED
   392  	updateDescription := "other random namespace test description"
   393  	updateOwnerEmail := "other random namespace test owner"
   394  	updatedData := map[string]string{"k": "v1"}
   395  	updateRetention := 122 * time.Hour * 24
   396  	updateHistoryArchivalState := enumspb.ARCHIVAL_STATE_DISABLED
   397  	updateHistoryArchivalURI := "some updated history archival uri"
   398  	updateVisibilityArchivalState := enumspb.ARCHIVAL_STATE_DISABLED
   399  	updateVisibilityArchivalURI := "some updated visibility archival uri"
   400  	updateClusterActive := "other random active cluster name"
   401  	updateClusterStandby := "other random standby cluster name"
   402  	updateConfigVersion := int64(1)
   403  	updateFailoverVersion := int64(59)
   404  	failoverTime := time.Now()
   405  	failoverHistory := []*replicationpb.FailoverStatus{
   406  		{
   407  			FailoverTime:    timestamppb.New(failoverTime),
   408  			FailoverVersion: 999,
   409  		},
   410  	}
   411  	updateClusters := []*replicationpb.ClusterReplicationConfig{
   412  		{
   413  			ClusterName: updateClusterActive,
   414  		},
   415  		{
   416  			ClusterName: updateClusterStandby,
   417  		},
   418  	}
   419  	updateTask := &replicationspb.NamespaceTaskAttributes{
   420  		NamespaceOperation: updateOperation,
   421  		Id:                 id,
   422  		Info: &namespacepb.NamespaceInfo{
   423  			Name:        name,
   424  			State:       updateState,
   425  			Description: updateDescription,
   426  			OwnerEmail:  updateOwnerEmail,
   427  			Data:        updatedData,
   428  		},
   429  		Config: &namespacepb.NamespaceConfig{
   430  			WorkflowExecutionRetentionTtl: durationpb.New(updateRetention),
   431  			HistoryArchivalState:          updateHistoryArchivalState,
   432  			HistoryArchivalUri:            updateHistoryArchivalURI,
   433  			VisibilityArchivalState:       updateVisibilityArchivalState,
   434  			VisibilityArchivalUri:         updateVisibilityArchivalURI,
   435  		},
   436  		ReplicationConfig: &replicationpb.NamespaceReplicationConfig{
   437  			ActiveClusterName: updateClusterActive,
   438  			Clusters:          updateClusters,
   439  		},
   440  		ConfigVersion:   updateConfigVersion,
   441  		FailoverVersion: updateFailoverVersion,
   442  		FailoverHistory: failoverHistory,
   443  	}
   444  
   445  	s.namespaceReplicator.currentCluster = updateClusterStandby
   446  	s.mockMetadataMgr.EXPECT().GetNamespace(gomock.Any(), &persistence.GetNamespaceRequest{
   447  		Name: name,
   448  	}).Return(&persistence.GetNamespaceResponse{Namespace: &persistencespb.NamespaceDetail{
   449  		Info: &persistencespb.NamespaceInfo{
   450  			Id: id,
   451  		},
   452  		ReplicationConfig: &persistencespb.NamespaceReplicationConfig{},
   453  	}}, nil).Times(2)
   454  	s.mockMetadataMgr.EXPECT().GetMetadata(gomock.Any()).Return(&persistence.GetMetadataResponse{
   455  		NotificationVersion: updateFailoverVersion,
   456  	}, nil).Times(1)
   457  	s.mockMetadataMgr.EXPECT().UpdateNamespace(gomock.Any(), &persistence.UpdateNamespaceRequest{
   458  		Namespace: &persistencespb.NamespaceDetail{
   459  			Info: &persistencespb.NamespaceInfo{
   460  				Id:          id,
   461  				State:       updateTask.Info.State,
   462  				Name:        updateTask.Info.Name,
   463  				Description: updateTask.Info.Description,
   464  				Owner:       updateTask.Info.OwnerEmail,
   465  				Data:        updateTask.Info.Data,
   466  			},
   467  			Config: &persistencespb.NamespaceConfig{
   468  				Retention:               updateTask.Config.WorkflowExecutionRetentionTtl,
   469  				HistoryArchivalState:    updateTask.Config.HistoryArchivalState,
   470  				HistoryArchivalUri:      updateTask.Config.HistoryArchivalUri,
   471  				VisibilityArchivalState: updateTask.Config.VisibilityArchivalState,
   472  				VisibilityArchivalUri:   updateTask.Config.VisibilityArchivalUri,
   473  			},
   474  			ReplicationConfig: &persistencespb.NamespaceReplicationConfig{
   475  				ActiveClusterName: updateTask.ReplicationConfig.ActiveClusterName,
   476  				Clusters:          []string{updateClusterActive, updateClusterStandby},
   477  				FailoverHistory:   convertFailoverHistoryToPersistenceProto(failoverHistory),
   478  			},
   479  			ConfigVersion:               updateConfigVersion,
   480  			FailoverNotificationVersion: updateFailoverVersion,
   481  			FailoverVersion:             updateFailoverVersion,
   482  		},
   483  		IsGlobalNamespace:   false,
   484  		NotificationVersion: updateFailoverVersion,
   485  	})
   486  	err := s.namespaceReplicator.Execute(context.Background(), updateTask)
   487  	s.Nil(err)
   488  }
   489  
   490  func (s *namespaceReplicationTaskExecutorSuite) TestExecute_UpdateNamespaceTask_UpdateConfig_NoUpdateActiveCluster() {
   491  	id := uuid.New()
   492  	name := "some random namespace test name"
   493  	updateOperation := enumsspb.NAMESPACE_OPERATION_UPDATE
   494  	updateState := enumspb.NAMESPACE_STATE_DEPRECATED
   495  	updateDescription := "other random namespace test description"
   496  	updateOwnerEmail := "other random namespace test owner"
   497  	updatedData := map[string]string{"k": "v1"}
   498  	updateRetention := 122 * time.Hour * 24
   499  	updateHistoryArchivalState := enumspb.ARCHIVAL_STATE_DISABLED
   500  	updateHistoryArchivalURI := "some updated history archival uri"
   501  	updateVisibilityArchivalState := enumspb.ARCHIVAL_STATE_DISABLED
   502  	updateVisibilityArchivalURI := "some updated visibility archival uri"
   503  	updateClusterActive := "other random active cluster name"
   504  	updateClusterStandby := "other random standby cluster name"
   505  	updateConfigVersion := int64(1)
   506  	updateFailoverVersion := int64(59)
   507  	updateClusters := []*replicationpb.ClusterReplicationConfig{
   508  		{
   509  			ClusterName: updateClusterActive,
   510  		},
   511  		{
   512  			ClusterName: updateClusterStandby,
   513  		},
   514  	}
   515  	updateTask := &replicationspb.NamespaceTaskAttributes{
   516  		NamespaceOperation: updateOperation,
   517  		Id:                 id,
   518  		Info: &namespacepb.NamespaceInfo{
   519  			Name:        name,
   520  			State:       updateState,
   521  			Description: updateDescription,
   522  			OwnerEmail:  updateOwnerEmail,
   523  			Data:        updatedData,
   524  		},
   525  		Config: &namespacepb.NamespaceConfig{
   526  			WorkflowExecutionRetentionTtl: durationpb.New(updateRetention),
   527  			HistoryArchivalState:          updateHistoryArchivalState,
   528  			HistoryArchivalUri:            updateHistoryArchivalURI,
   529  			VisibilityArchivalState:       updateVisibilityArchivalState,
   530  			VisibilityArchivalUri:         updateVisibilityArchivalURI,
   531  		},
   532  		ReplicationConfig: &replicationpb.NamespaceReplicationConfig{
   533  			ActiveClusterName: updateClusterActive,
   534  			Clusters:          updateClusters,
   535  		},
   536  		ConfigVersion:   updateConfigVersion,
   537  		FailoverVersion: updateFailoverVersion,
   538  	}
   539  
   540  	s.namespaceReplicator.currentCluster = updateClusterStandby
   541  	s.mockMetadataMgr.EXPECT().GetNamespace(gomock.Any(), &persistence.GetNamespaceRequest{
   542  		Name: name,
   543  	}).Return(&persistence.GetNamespaceResponse{Namespace: &persistencespb.NamespaceDetail{
   544  		Info: &persistencespb.NamespaceInfo{
   545  			Id: id,
   546  		},
   547  		ReplicationConfig: &persistencespb.NamespaceReplicationConfig{},
   548  		FailoverVersion:   updateFailoverVersion + 1,
   549  	}}, nil).Times(2)
   550  	s.mockMetadataMgr.EXPECT().GetMetadata(gomock.Any()).Return(&persistence.GetMetadataResponse{
   551  		NotificationVersion: updateFailoverVersion,
   552  	}, nil).Times(1)
   553  	s.mockMetadataMgr.EXPECT().UpdateNamespace(gomock.Any(), &persistence.UpdateNamespaceRequest{
   554  		Namespace: &persistencespb.NamespaceDetail{
   555  			Info: &persistencespb.NamespaceInfo{
   556  				Id:          id,
   557  				State:       updateTask.Info.State,
   558  				Name:        updateTask.Info.Name,
   559  				Description: updateTask.Info.Description,
   560  				Owner:       updateTask.Info.OwnerEmail,
   561  				Data:        updateTask.Info.Data,
   562  			},
   563  			Config: &persistencespb.NamespaceConfig{
   564  				Retention:               updateTask.Config.WorkflowExecutionRetentionTtl,
   565  				HistoryArchivalState:    updateTask.Config.HistoryArchivalState,
   566  				HistoryArchivalUri:      updateTask.Config.HistoryArchivalUri,
   567  				VisibilityArchivalState: updateTask.Config.VisibilityArchivalState,
   568  				VisibilityArchivalUri:   updateTask.Config.VisibilityArchivalUri,
   569  			},
   570  			ReplicationConfig: &persistencespb.NamespaceReplicationConfig{
   571  				Clusters: []string{updateClusterActive, updateClusterStandby},
   572  			},
   573  			ConfigVersion:               updateConfigVersion,
   574  			FailoverNotificationVersion: 0,
   575  			FailoverVersion:             updateFailoverVersion + 1,
   576  		},
   577  		IsGlobalNamespace:   false,
   578  		NotificationVersion: updateFailoverVersion,
   579  	})
   580  	err := s.namespaceReplicator.Execute(context.Background(), updateTask)
   581  	s.Nil(err)
   582  }
   583  
   584  func (s *namespaceReplicationTaskExecutorSuite) TestExecute_UpdateNamespaceTask_NoUpdateConfig_UpdateActiveCluster() {
   585  	id := uuid.New()
   586  	name := "some random namespace test name"
   587  	updateOperation := enumsspb.NAMESPACE_OPERATION_UPDATE
   588  	updateState := enumspb.NAMESPACE_STATE_DEPRECATED
   589  	updateDescription := "other random namespace test description"
   590  	updateOwnerEmail := "other random namespace test owner"
   591  	updatedData := map[string]string{"k": "v1"}
   592  	updateRetention := 122 * time.Hour * 24
   593  	updateHistoryArchivalState := enumspb.ARCHIVAL_STATE_DISABLED
   594  	updateHistoryArchivalURI := "some updated history archival uri"
   595  	updateVisibilityArchivalState := enumspb.ARCHIVAL_STATE_DISABLED
   596  	updateVisibilityArchivalURI := "some updated visibility archival uri"
   597  	updateClusterActive := "other random active cluster name"
   598  	updateClusterStandby := "other random standby cluster name"
   599  	updateConfigVersion := int64(1)
   600  	updateFailoverVersion := int64(59)
   601  	updateClusters := []*replicationpb.ClusterReplicationConfig{
   602  		{
   603  			ClusterName: updateClusterActive,
   604  		},
   605  		{
   606  			ClusterName: updateClusterStandby,
   607  		},
   608  	}
   609  	updateTask := &replicationspb.NamespaceTaskAttributes{
   610  		NamespaceOperation: updateOperation,
   611  		Id:                 id,
   612  		Info: &namespacepb.NamespaceInfo{
   613  			Name:        name,
   614  			State:       updateState,
   615  			Description: updateDescription,
   616  			OwnerEmail:  updateOwnerEmail,
   617  			Data:        updatedData,
   618  		},
   619  		Config: &namespacepb.NamespaceConfig{
   620  			WorkflowExecutionRetentionTtl: durationpb.New(updateRetention),
   621  			HistoryArchivalState:          updateHistoryArchivalState,
   622  			HistoryArchivalUri:            updateHistoryArchivalURI,
   623  			VisibilityArchivalState:       updateVisibilityArchivalState,
   624  			VisibilityArchivalUri:         updateVisibilityArchivalURI,
   625  		},
   626  		ReplicationConfig: &replicationpb.NamespaceReplicationConfig{
   627  			ActiveClusterName: updateClusterActive,
   628  			Clusters:          updateClusters,
   629  		},
   630  		ConfigVersion:   updateConfigVersion,
   631  		FailoverVersion: updateFailoverVersion,
   632  	}
   633  
   634  	s.namespaceReplicator.currentCluster = updateClusterStandby
   635  	s.mockMetadataMgr.EXPECT().GetNamespace(gomock.Any(), &persistence.GetNamespaceRequest{
   636  		Name: name,
   637  	}).Return(&persistence.GetNamespaceResponse{Namespace: &persistencespb.NamespaceDetail{
   638  		Info: &persistencespb.NamespaceInfo{
   639  			Id: id,
   640  		},
   641  		ReplicationConfig: &persistencespb.NamespaceReplicationConfig{},
   642  		ConfigVersion:     updateConfigVersion + 1,
   643  	}}, nil).Times(2)
   644  	s.mockMetadataMgr.EXPECT().GetMetadata(gomock.Any()).Return(&persistence.GetMetadataResponse{
   645  		NotificationVersion: updateFailoverVersion,
   646  	}, nil).Times(1)
   647  	s.mockMetadataMgr.EXPECT().UpdateNamespace(gomock.Any(), &persistence.UpdateNamespaceRequest{
   648  		Namespace: &persistencespb.NamespaceDetail{
   649  			Info: &persistencespb.NamespaceInfo{
   650  				Id: id,
   651  			},
   652  			ReplicationConfig: &persistencespb.NamespaceReplicationConfig{
   653  				ActiveClusterName: updateClusterActive,
   654  			},
   655  			ConfigVersion:               updateConfigVersion + 1,
   656  			FailoverNotificationVersion: updateFailoverVersion,
   657  			FailoverVersion:             updateFailoverVersion,
   658  		},
   659  		IsGlobalNamespace:   false,
   660  		NotificationVersion: updateFailoverVersion,
   661  	})
   662  	err := s.namespaceReplicator.Execute(context.Background(), updateTask)
   663  	s.Nil(err)
   664  }
   665  
   666  func (s *namespaceReplicationTaskExecutorSuite) TestExecute_UpdateNamespaceTask_NoUpdateConfig_NoUpdateActiveCluster() {
   667  	id := uuid.New()
   668  	name := "some random namespace test name"
   669  	updateOperation := enumsspb.NAMESPACE_OPERATION_UPDATE
   670  	updateState := enumspb.NAMESPACE_STATE_DEPRECATED
   671  	updateDescription := "other random namespace test description"
   672  	updateOwnerEmail := "other random namespace test owner"
   673  	updatedData := map[string]string{"k": "v1"}
   674  	updateRetention := 122 * time.Hour * 24
   675  	updateHistoryArchivalState := enumspb.ARCHIVAL_STATE_DISABLED
   676  	updateHistoryArchivalURI := "some updated history archival uri"
   677  	updateVisibilityArchivalState := enumspb.ARCHIVAL_STATE_DISABLED
   678  	updateVisibilityArchivalURI := "some updated visibility archival uri"
   679  	updateClusterActive := "other random active cluster name"
   680  	updateClusterStandby := "other random standby cluster name"
   681  	updateConfigVersion := int64(1)
   682  	updateFailoverVersion := int64(59)
   683  	updateClusters := []*replicationpb.ClusterReplicationConfig{
   684  		{
   685  			ClusterName: updateClusterActive,
   686  		},
   687  		{
   688  			ClusterName: updateClusterStandby,
   689  		},
   690  	}
   691  	updateTask := &replicationspb.NamespaceTaskAttributes{
   692  		NamespaceOperation: updateOperation,
   693  		Id:                 id,
   694  		Info: &namespacepb.NamespaceInfo{
   695  			Name:        name,
   696  			State:       updateState,
   697  			Description: updateDescription,
   698  			OwnerEmail:  updateOwnerEmail,
   699  			Data:        updatedData,
   700  		},
   701  		Config: &namespacepb.NamespaceConfig{
   702  			WorkflowExecutionRetentionTtl: durationpb.New(updateRetention),
   703  			HistoryArchivalState:          updateHistoryArchivalState,
   704  			HistoryArchivalUri:            updateHistoryArchivalURI,
   705  			VisibilityArchivalState:       updateVisibilityArchivalState,
   706  			VisibilityArchivalUri:         updateVisibilityArchivalURI,
   707  		},
   708  		ReplicationConfig: &replicationpb.NamespaceReplicationConfig{
   709  			ActiveClusterName: updateClusterActive,
   710  			Clusters:          updateClusters,
   711  		},
   712  		ConfigVersion:   updateConfigVersion,
   713  		FailoverVersion: updateFailoverVersion,
   714  	}
   715  
   716  	s.namespaceReplicator.currentCluster = updateClusterStandby
   717  	s.mockMetadataMgr.EXPECT().GetNamespace(gomock.Any(), &persistence.GetNamespaceRequest{
   718  		Name: name,
   719  	}).Return(&persistence.GetNamespaceResponse{Namespace: &persistencespb.NamespaceDetail{
   720  		Info: &persistencespb.NamespaceInfo{
   721  			Id: id,
   722  		},
   723  		ReplicationConfig: &persistencespb.NamespaceReplicationConfig{},
   724  		ConfigVersion:     updateConfigVersion + 1,
   725  		FailoverVersion:   updateFailoverVersion + 1,
   726  	}}, nil).Times(2)
   727  	s.mockMetadataMgr.EXPECT().GetMetadata(gomock.Any()).Return(&persistence.GetMetadataResponse{
   728  		NotificationVersion: updateFailoverVersion,
   729  	}, nil).Times(1)
   730  
   731  	s.mockMetadataMgr.EXPECT().UpdateNamespace(gomock.Any(), gomock.Any()).Times(0)
   732  	err := s.namespaceReplicator.Execute(context.Background(), updateTask)
   733  	s.Nil(err)
   734  }