go.temporal.io/server@v1.23.0/common/persistence/persistence-tests/metadata_persistence_v2.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 persistencetests 26 27 import ( 28 "context" 29 "fmt" 30 "strconv" 31 "strings" 32 "sync" 33 "sync/atomic" 34 "time" 35 36 "github.com/pborman/uuid" 37 "github.com/stretchr/testify/require" 38 enumspb "go.temporal.io/api/enums/v1" 39 namespacepb "go.temporal.io/api/namespace/v1" 40 "go.temporal.io/api/serviceerror" 41 "google.golang.org/protobuf/types/known/timestamppb" 42 43 persistencespb "go.temporal.io/server/api/persistence/v1" 44 "go.temporal.io/server/common/cluster" 45 "go.temporal.io/server/common/debug" 46 p "go.temporal.io/server/common/persistence" 47 "go.temporal.io/server/common/persistence/cassandra" 48 "go.temporal.io/server/common/primitives/timestamp" 49 "go.temporal.io/server/common/testing/protorequire" 50 ) 51 52 type ( 53 // MetadataPersistenceSuiteV2 is test of the V2 version of metadata persistence 54 MetadataPersistenceSuiteV2 struct { 55 *TestBase 56 // override suite.Suite.Assertions with require.Assertions; this means that s.NotNil(nil) will stop the test, 57 // not merely log an error 58 *require.Assertions 59 protorequire.ProtoAssertions 60 61 ctx context.Context 62 cancel context.CancelFunc 63 } 64 ) 65 66 // SetupSuite implementation 67 func (m *MetadataPersistenceSuiteV2) SetupSuite() { 68 } 69 70 // SetupTest implementation 71 func (m *MetadataPersistenceSuiteV2) SetupTest() { 72 // Have to define our overridden assertions in the test setup. If we did it earlier, s.T() will return nil 73 m.Assertions = require.New(m.T()) 74 m.ProtoAssertions = protorequire.New(m.T()) 75 m.ctx, m.cancel = context.WithTimeout(context.Background(), 30*time.Second*debug.TimeoutMultiplier) 76 77 // cleanup the namespace created 78 var token []byte 79 pageSize := 10 80 ListLoop: 81 for { 82 resp, err := m.ListNamespaces(pageSize, token) 83 m.NoError(err) 84 token = resp.NextPageToken 85 for _, n := range resp.Namespaces { 86 m.NoError(m.DeleteNamespace(n.Namespace.Info.Id, "")) 87 } 88 if len(token) == 0 { 89 break ListLoop 90 } 91 } 92 } 93 94 // TearDownTest implementation 95 func (m *MetadataPersistenceSuiteV2) TearDownTest() { 96 m.cancel() 97 } 98 99 // TearDownSuite implementation 100 func (m *MetadataPersistenceSuiteV2) TearDownSuite() { 101 m.TearDownWorkflowStore() 102 } 103 104 // Partial namespace creation is only relevant for Cassandra, the following tests will only run when the underlying cluster is cassandra 105 func (m *MetadataPersistenceSuiteV2) createPartialNamespace(id string, name string) { 106 // only add the namespace to namespaces_by_id table and not namespaces table 107 const constNamespacePartition = 0 108 const templateCreateNamespaceQuery = `INSERT INTO namespaces_by_id (` + 109 `id, name) ` + 110 `VALUES(?, ?) IF NOT EXISTS` 111 query := m.DefaultTestCluster.(*cassandra.TestCluster).GetSession().Query(templateCreateNamespaceQuery, id, name).WithContext(context.Background()) 112 err := query.Exec() 113 m.NoError(err) 114 115 } 116 117 func (m *MetadataPersistenceSuiteV2) truncatePartialNamespace() { 118 query := m.DefaultTestCluster.(*cassandra.TestCluster).GetSession().Query("TRUNCATE namespaces_by_id").WithContext(context.Background()) 119 err := query.Exec() 120 m.NoError(err) 121 122 query = m.DefaultTestCluster.(*cassandra.TestCluster).GetSession().Query("TRUNCATE namespaces").WithContext(context.Background()) 123 err = query.Exec() 124 m.NoError(err) 125 } 126 127 func (m *MetadataPersistenceSuiteV2) TestCreateWithPartialNamespaceSameNameSameID() { 128 // This is only relevant for cassandra 129 switch m.DefaultTestCluster.(type) { 130 case *cassandra.TestCluster: 131 default: 132 return 133 } 134 id := uuid.New() 135 name := "create-partial-namespace-test-name" 136 m.createPartialNamespace(id, name) 137 138 state := enumspb.NAMESPACE_STATE_REGISTERED 139 description := "create-namespace-test-description" 140 owner := "create-namespace-test-owner" 141 data := map[string]string{"k1": "v1"} 142 retention := int32(10) 143 historyArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 144 historyArchivalURI := "test://history/uri" 145 visibilityArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 146 visibilityArchivalURI := "test://visibility/uri" 147 badBinaries := &namespacepb.BadBinaries{Binaries: map[string]*namespacepb.BadBinaryInfo{}} 148 isGlobalNamespace := false 149 configVersion := int64(0) 150 failoverVersion := int64(0) 151 152 resp0, err0 := m.CreateNamespace( 153 &persistencespb.NamespaceInfo{ 154 Id: id, 155 Name: name, 156 State: state, 157 Description: description, 158 Owner: owner, 159 Data: data, 160 }, 161 &persistencespb.NamespaceConfig{ 162 Retention: timestamp.DurationFromDays(retention), 163 HistoryArchivalState: historyArchivalState, 164 HistoryArchivalUri: historyArchivalURI, 165 VisibilityArchivalState: visibilityArchivalState, 166 VisibilityArchivalUri: visibilityArchivalURI, 167 BadBinaries: badBinaries, 168 }, 169 &persistencespb.NamespaceReplicationConfig{}, 170 isGlobalNamespace, 171 configVersion, 172 failoverVersion, 173 ) 174 m.NoError(err0) 175 m.NotNil(resp0) 176 m.EqualValues(id, resp0.ID) 177 178 // for namespace which do not have replication config set, will default to 179 // use current cluster as active, with current cluster as all clusters 180 resp1, err1 := m.GetNamespace(id, "") 181 m.NoError(err1) 182 m.NotNil(resp1) 183 m.EqualValues(id, resp1.Namespace.Info.Id) 184 m.Equal(name, resp1.Namespace.Info.Name) 185 m.Equal(state, resp1.Namespace.Info.State) 186 m.Equal(description, resp1.Namespace.Info.Description) 187 m.Equal(owner, resp1.Namespace.Info.Owner) 188 m.Equal(data, resp1.Namespace.Info.Data) 189 m.EqualValues(time.Duration(retention)*time.Hour*24, resp1.Namespace.Config.Retention.AsDuration()) 190 m.Equal(historyArchivalState, resp1.Namespace.Config.HistoryArchivalState) 191 m.Equal(historyArchivalURI, resp1.Namespace.Config.HistoryArchivalUri) 192 m.Equal(visibilityArchivalState, resp1.Namespace.Config.VisibilityArchivalState) 193 m.Equal(visibilityArchivalURI, resp1.Namespace.Config.VisibilityArchivalUri) 194 m.Equal(badBinaries, resp1.Namespace.Config.BadBinaries) 195 m.Equal(cluster.TestCurrentClusterName, resp1.Namespace.ReplicationConfig.ActiveClusterName) 196 m.Equal(1, len(resp1.Namespace.ReplicationConfig.Clusters)) 197 m.Equal(isGlobalNamespace, resp1.IsGlobalNamespace) 198 m.Equal(configVersion, resp1.Namespace.ConfigVersion) 199 m.Equal(failoverVersion, resp1.Namespace.FailoverVersion) 200 m.True(resp1.Namespace.ReplicationConfig.Clusters[0] == cluster.TestCurrentClusterName) 201 m.Equal(p.InitialFailoverNotificationVersion, resp1.Namespace.FailoverNotificationVersion) 202 m.truncatePartialNamespace() 203 } 204 205 func (m *MetadataPersistenceSuiteV2) TestCreateWithPartialNamespaceSameNameDifferentID() { 206 // This is only relevant for cassandra 207 switch m.DefaultTestCluster.(type) { 208 case *cassandra.TestCluster: 209 default: 210 return 211 } 212 213 id := uuid.New() 214 partialID := uuid.New() 215 name := "create-partial-namespace-test-name" 216 m.createPartialNamespace(partialID, name) 217 state := enumspb.NAMESPACE_STATE_REGISTERED 218 description := "create-namespace-test-description" 219 owner := "create-namespace-test-owner" 220 data := map[string]string{"k1": "v1"} 221 retention := int32(10) 222 historyArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 223 historyArchivalURI := "test://history/uri" 224 visibilityArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 225 visibilityArchivalURI := "test://visibility/uri" 226 badBinaries := &namespacepb.BadBinaries{Binaries: map[string]*namespacepb.BadBinaryInfo{}} 227 isGlobalNamespace := false 228 configVersion := int64(0) 229 failoverVersion := int64(0) 230 231 resp0, err0 := m.CreateNamespace( 232 &persistencespb.NamespaceInfo{ 233 Id: id, 234 Name: name, 235 State: state, 236 Description: description, 237 Owner: owner, 238 Data: data, 239 }, 240 &persistencespb.NamespaceConfig{ 241 Retention: timestamp.DurationFromDays(retention), 242 HistoryArchivalState: historyArchivalState, 243 HistoryArchivalUri: historyArchivalURI, 244 VisibilityArchivalState: visibilityArchivalState, 245 VisibilityArchivalUri: visibilityArchivalURI, 246 BadBinaries: badBinaries, 247 }, 248 &persistencespb.NamespaceReplicationConfig{}, 249 isGlobalNamespace, 250 configVersion, 251 failoverVersion, 252 ) 253 m.NoError(err0) 254 m.NotNil(resp0) 255 m.EqualValues(id, resp0.ID) 256 257 // for namespace which do not have replication config set, will default to 258 // use current cluster as active, with current cluster as all clusters 259 resp1, err1 := m.GetNamespace(id, "") 260 m.NoError(err1) 261 m.NotNil(resp1) 262 m.EqualValues(id, resp1.Namespace.Info.Id) 263 m.Equal(name, resp1.Namespace.Info.Name) 264 m.Equal(state, resp1.Namespace.Info.State) 265 m.Equal(description, resp1.Namespace.Info.Description) 266 m.Equal(owner, resp1.Namespace.Info.Owner) 267 m.Equal(data, resp1.Namespace.Info.Data) 268 m.EqualValues(time.Duration(retention)*time.Hour*24, resp1.Namespace.Config.Retention.AsDuration()) 269 m.Equal(historyArchivalState, resp1.Namespace.Config.HistoryArchivalState) 270 m.Equal(historyArchivalURI, resp1.Namespace.Config.HistoryArchivalUri) 271 m.Equal(visibilityArchivalState, resp1.Namespace.Config.VisibilityArchivalState) 272 m.Equal(visibilityArchivalURI, resp1.Namespace.Config.VisibilityArchivalUri) 273 m.Equal(badBinaries, resp1.Namespace.Config.BadBinaries) 274 m.Equal(cluster.TestCurrentClusterName, resp1.Namespace.ReplicationConfig.ActiveClusterName) 275 m.Equal(1, len(resp1.Namespace.ReplicationConfig.Clusters)) 276 m.Equal(isGlobalNamespace, resp1.IsGlobalNamespace) 277 m.Equal(configVersion, resp1.Namespace.ConfigVersion) 278 m.Equal(failoverVersion, resp1.Namespace.FailoverVersion) 279 m.True(resp1.Namespace.ReplicationConfig.Clusters[0] == cluster.TestCurrentClusterName) 280 m.Equal(p.InitialFailoverNotificationVersion, resp1.Namespace.FailoverNotificationVersion) 281 m.truncatePartialNamespace() 282 } 283 284 func (m *MetadataPersistenceSuiteV2) TestCreateWithPartialNamespaceDifferentNameSameID() { 285 // This is only relevant for cassandra 286 switch m.DefaultTestCluster.(type) { 287 case *cassandra.TestCluster: 288 default: 289 return 290 } 291 id := uuid.New() 292 name := "create-namespace-test-name-for-partial-test" 293 partialName := "create-partial-namespace-test-name" 294 m.createPartialNamespace(id, partialName) 295 state := enumspb.NAMESPACE_STATE_REGISTERED 296 description := "create-namespace-test-description" 297 owner := "create-namespace-test-owner" 298 data := map[string]string{"k1": "v1"} 299 retention := int32(10) 300 historyArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 301 historyArchivalURI := "test://history/uri" 302 visibilityArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 303 visibilityArchivalURI := "test://visibility/uri" 304 badBinaries := &namespacepb.BadBinaries{Binaries: map[string]*namespacepb.BadBinaryInfo{}} 305 isGlobalNamespace := false 306 configVersion := int64(0) 307 failoverVersion := int64(0) 308 309 resp0, err0 := m.CreateNamespace( 310 &persistencespb.NamespaceInfo{ 311 Id: id, 312 Name: name, 313 State: state, 314 Description: description, 315 Owner: owner, 316 Data: data, 317 }, 318 &persistencespb.NamespaceConfig{ 319 Retention: timestamp.DurationFromDays(retention), 320 HistoryArchivalState: historyArchivalState, 321 HistoryArchivalUri: historyArchivalURI, 322 VisibilityArchivalState: visibilityArchivalState, 323 VisibilityArchivalUri: visibilityArchivalURI, 324 BadBinaries: badBinaries, 325 }, 326 &persistencespb.NamespaceReplicationConfig{}, 327 isGlobalNamespace, 328 configVersion, 329 failoverVersion, 330 ) 331 m.Error(err0) 332 m.IsType(&serviceerror.NamespaceAlreadyExists{}, err0) 333 m.Nil(resp0) 334 m.truncatePartialNamespace() 335 } 336 337 // TestCreateNamespace test 338 func (m *MetadataPersistenceSuiteV2) TestCreateNamespace() { 339 id := uuid.New() 340 name := "create-namespace-test-name-for-partial-test" 341 state := enumspb.NAMESPACE_STATE_REGISTERED 342 description := "create-namespace-test-description" 343 owner := "create-namespace-test-owner" 344 data := map[string]string{"k1": "v1"} 345 retention := int32(10) 346 historyArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 347 historyArchivalURI := "test://history/uri" 348 visibilityArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 349 visibilityArchivalURI := "test://visibility/uri" 350 badBinaries := &namespacepb.BadBinaries{Binaries: map[string]*namespacepb.BadBinaryInfo{}} 351 isGlobalNamespace := false 352 configVersion := int64(0) 353 failoverVersion := int64(0) 354 355 resp0, err0 := m.CreateNamespace( 356 &persistencespb.NamespaceInfo{ 357 Id: id, 358 Name: name, 359 State: state, 360 Description: description, 361 Owner: owner, 362 Data: data, 363 }, 364 &persistencespb.NamespaceConfig{ 365 Retention: timestamp.DurationFromDays(retention), 366 HistoryArchivalState: historyArchivalState, 367 HistoryArchivalUri: historyArchivalURI, 368 VisibilityArchivalState: visibilityArchivalState, 369 VisibilityArchivalUri: visibilityArchivalURI, 370 BadBinaries: badBinaries, 371 }, 372 &persistencespb.NamespaceReplicationConfig{}, 373 isGlobalNamespace, 374 configVersion, 375 failoverVersion, 376 ) 377 m.NoError(err0) 378 m.NotNil(resp0) 379 m.EqualValues(id, resp0.ID) 380 381 // for namespace which do not have replication config set, will default to 382 // use current cluster as active, with current cluster as all clusters 383 resp1, err1 := m.GetNamespace(id, "") 384 m.NoError(err1) 385 m.NotNil(resp1) 386 m.EqualValues(id, resp1.Namespace.Info.Id) 387 m.Equal(name, resp1.Namespace.Info.Name) 388 m.Equal(state, resp1.Namespace.Info.State) 389 m.Equal(description, resp1.Namespace.Info.Description) 390 m.Equal(owner, resp1.Namespace.Info.Owner) 391 m.Equal(data, resp1.Namespace.Info.Data) 392 m.EqualValues(time.Duration(retention)*time.Hour*24, resp1.Namespace.Config.Retention.AsDuration()) 393 m.Equal(historyArchivalState, resp1.Namespace.Config.HistoryArchivalState) 394 m.Equal(historyArchivalURI, resp1.Namespace.Config.HistoryArchivalUri) 395 m.Equal(visibilityArchivalState, resp1.Namespace.Config.VisibilityArchivalState) 396 m.Equal(visibilityArchivalURI, resp1.Namespace.Config.VisibilityArchivalUri) 397 m.Equal(badBinaries, resp1.Namespace.Config.BadBinaries) 398 m.Equal(cluster.TestCurrentClusterName, resp1.Namespace.ReplicationConfig.ActiveClusterName) 399 m.Equal(1, len(resp1.Namespace.ReplicationConfig.Clusters)) 400 m.Equal(isGlobalNamespace, resp1.IsGlobalNamespace) 401 m.Equal(configVersion, resp1.Namespace.ConfigVersion) 402 m.Equal(failoverVersion, resp1.Namespace.FailoverVersion) 403 m.True(resp1.Namespace.ReplicationConfig.Clusters[0] == cluster.TestCurrentClusterName) 404 m.Equal(p.InitialFailoverNotificationVersion, resp1.Namespace.FailoverNotificationVersion) 405 406 resp2, err2 := m.CreateNamespace( 407 &persistencespb.NamespaceInfo{ 408 Id: uuid.New(), 409 Name: name, 410 State: state, 411 Description: "fail", 412 Owner: "fail", 413 Data: map[string]string{}, 414 }, 415 &persistencespb.NamespaceConfig{ 416 Retention: timestamp.DurationFromDays(100), 417 HistoryArchivalState: enumspb.ARCHIVAL_STATE_DISABLED, 418 HistoryArchivalUri: "", 419 VisibilityArchivalState: enumspb.ARCHIVAL_STATE_DISABLED, 420 VisibilityArchivalUri: "", 421 }, 422 &persistencespb.NamespaceReplicationConfig{}, 423 isGlobalNamespace, 424 configVersion, 425 failoverVersion, 426 ) 427 m.Error(err2) 428 m.IsType(&serviceerror.NamespaceAlreadyExists{}, err2) 429 m.Nil(resp2) 430 } 431 432 // TestGetNamespace test 433 func (m *MetadataPersistenceSuiteV2) TestGetNamespace() { 434 id := uuid.New() 435 name := "get-namespace-test-name" 436 state := enumspb.NAMESPACE_STATE_REGISTERED 437 description := "get-namespace-test-description" 438 owner := "get-namespace-test-owner" 439 data := map[string]string{"k1": "v1"} 440 retention := int32(10) 441 historyArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 442 historyArchivalURI := "test://history/uri" 443 visibilityArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 444 visibilityArchivalURI := "test://visibility/uri" 445 446 clusterActive := "some random active cluster name" 447 clusterStandby := "some random standby cluster name" 448 configVersion := int64(11) 449 failoverVersion := int64(59) 450 isGlobalNamespace := true 451 clusters := []string{clusterActive, clusterStandby} 452 453 resp0, err0 := m.GetNamespace("", "does-not-exist") 454 m.Nil(resp0) 455 m.Error(err0) 456 m.IsType(&serviceerror.NamespaceNotFound{}, err0) 457 testBinaries := &namespacepb.BadBinaries{ 458 Binaries: map[string]*namespacepb.BadBinaryInfo{ 459 "abc": { 460 Reason: "test-reason", 461 Operator: "test-operator", 462 CreateTime: timestamppb.New(time.Date(2020, 8, 22, 0, 0, 0, 0, time.UTC)), 463 }, 464 }, 465 } 466 467 resp1, err1 := m.CreateNamespace( 468 &persistencespb.NamespaceInfo{ 469 Id: id, 470 Name: name, 471 State: state, 472 Description: description, 473 Owner: owner, 474 Data: data, 475 }, 476 &persistencespb.NamespaceConfig{ 477 Retention: timestamp.DurationFromDays(retention), 478 HistoryArchivalState: historyArchivalState, 479 HistoryArchivalUri: historyArchivalURI, 480 VisibilityArchivalState: visibilityArchivalState, 481 VisibilityArchivalUri: visibilityArchivalURI, 482 BadBinaries: testBinaries, 483 }, 484 &persistencespb.NamespaceReplicationConfig{ 485 ActiveClusterName: clusterActive, 486 Clusters: clusters, 487 }, 488 isGlobalNamespace, 489 configVersion, 490 failoverVersion, 491 ) 492 m.NoError(err1) 493 m.NotNil(resp1) 494 m.EqualValues(id, resp1.ID) 495 496 resp2, err2 := m.GetNamespace(id, "") 497 m.NoError(err2) 498 m.NotNil(resp2) 499 m.EqualValues(id, resp2.Namespace.Info.Id) 500 m.Equal(name, resp2.Namespace.Info.Name) 501 m.Equal(state, resp2.Namespace.Info.State) 502 m.Equal(description, resp2.Namespace.Info.Description) 503 m.Equal(owner, resp2.Namespace.Info.Owner) 504 m.Equal(data, resp2.Namespace.Info.Data) 505 m.EqualValues(time.Duration(retention)*time.Hour*24, resp2.Namespace.Config.Retention.AsDuration()) 506 m.Equal(historyArchivalState, resp2.Namespace.Config.HistoryArchivalState) 507 m.Equal(historyArchivalURI, resp2.Namespace.Config.HistoryArchivalUri) 508 m.Equal(visibilityArchivalState, resp2.Namespace.Config.VisibilityArchivalState) 509 m.Equal(visibilityArchivalURI, resp2.Namespace.Config.VisibilityArchivalUri) 510 m.ProtoEqual(testBinaries, resp2.Namespace.Config.BadBinaries) 511 m.Equal(clusterActive, resp2.Namespace.ReplicationConfig.ActiveClusterName) 512 m.Equal(len(clusters), len(resp2.Namespace.ReplicationConfig.Clusters)) 513 for index := range clusters { 514 m.Equal(clusters[index], resp2.Namespace.ReplicationConfig.Clusters[index]) 515 } 516 m.Equal(isGlobalNamespace, resp2.IsGlobalNamespace) 517 m.Equal(configVersion, resp2.Namespace.ConfigVersion) 518 m.Equal(failoverVersion, resp2.Namespace.FailoverVersion) 519 m.Equal(p.InitialFailoverNotificationVersion, resp2.Namespace.FailoverNotificationVersion) 520 521 resp3, err3 := m.GetNamespace("", name) 522 m.NoError(err3) 523 m.NotNil(resp3) 524 m.EqualValues(id, resp3.Namespace.Info.Id) 525 m.Equal(name, resp3.Namespace.Info.Name) 526 m.Equal(state, resp3.Namespace.Info.State) 527 m.Equal(description, resp3.Namespace.Info.Description) 528 m.Equal(owner, resp3.Namespace.Info.Owner) 529 m.Equal(data, resp3.Namespace.Info.Data) 530 m.EqualValues(time.Duration(retention)*time.Hour*24, resp3.Namespace.Config.Retention.AsDuration()) 531 m.Equal(historyArchivalState, resp3.Namespace.Config.HistoryArchivalState) 532 m.Equal(historyArchivalURI, resp3.Namespace.Config.HistoryArchivalUri) 533 m.Equal(visibilityArchivalState, resp3.Namespace.Config.VisibilityArchivalState) 534 m.Equal(visibilityArchivalURI, resp3.Namespace.Config.VisibilityArchivalUri) 535 m.Equal(clusterActive, resp3.Namespace.ReplicationConfig.ActiveClusterName) 536 m.Equal(len(clusters), len(resp3.Namespace.ReplicationConfig.Clusters)) 537 for index := range clusters { 538 m.Equal(clusters[index], resp3.Namespace.ReplicationConfig.Clusters[index]) 539 } 540 m.Equal(isGlobalNamespace, resp3.IsGlobalNamespace) 541 m.Equal(configVersion, resp3.Namespace.ConfigVersion) 542 m.Equal(failoverVersion, resp3.Namespace.FailoverVersion) 543 m.Equal(p.InitialFailoverNotificationVersion, resp3.Namespace.FailoverNotificationVersion) 544 545 resp4, err4 := m.GetNamespace(id, name) 546 m.Error(err4) 547 m.IsType(&serviceerror.InvalidArgument{}, err4) 548 m.Nil(resp4) 549 550 resp5, err5 := m.GetNamespace("", "") 551 m.Nil(resp5) 552 m.IsType(&serviceerror.InvalidArgument{}, err5) 553 } 554 555 // TestConcurrentCreateNamespace test 556 func (m *MetadataPersistenceSuiteV2) TestConcurrentCreateNamespace() { 557 id := uuid.New() 558 559 name := "concurrent-create-namespace-test-name" 560 state := enumspb.NAMESPACE_STATE_REGISTERED 561 description := "concurrent-create-namespace-test-description" 562 owner := "create-namespace-test-owner" 563 retention := int32(10) 564 historyArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 565 historyArchivalURI := "test://history/uri" 566 visibilityArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 567 visibilityArchivalURI := "test://visibility/uri" 568 569 clusterActive := "some random active cluster name" 570 clusterStandby := "some random standby cluster name" 571 configVersion := int64(10) 572 failoverVersion := int64(59) 573 isGlobalNamespace := true 574 clusters := []string{clusterActive, clusterStandby} 575 576 testBinaries := &namespacepb.BadBinaries{ 577 Binaries: map[string]*namespacepb.BadBinaryInfo{ 578 "abc": { 579 Reason: "test-reason", 580 Operator: "test-operator", 581 CreateTime: timestamppb.New(time.Date(2020, 8, 22, 0, 0, 0, 0, time.UTC)), 582 }, 583 }, 584 } 585 concurrency := 16 586 successCount := int32(0) 587 var wg sync.WaitGroup 588 for i := 1; i <= concurrency; i++ { 589 newValue := fmt.Sprintf("v-%v", i) 590 wg.Add(1) 591 go func(data map[string]string) { 592 _, err1 := m.CreateNamespace( 593 &persistencespb.NamespaceInfo{ 594 Id: id, 595 Name: name, 596 State: state, 597 Description: description, 598 Owner: owner, 599 Data: data, 600 }, 601 &persistencespb.NamespaceConfig{ 602 Retention: timestamp.DurationFromDays(retention), 603 HistoryArchivalState: historyArchivalState, 604 HistoryArchivalUri: historyArchivalURI, 605 VisibilityArchivalState: visibilityArchivalState, 606 VisibilityArchivalUri: visibilityArchivalURI, 607 BadBinaries: testBinaries, 608 }, 609 &persistencespb.NamespaceReplicationConfig{ 610 ActiveClusterName: clusterActive, 611 Clusters: clusters, 612 }, 613 isGlobalNamespace, 614 configVersion, 615 failoverVersion, 616 ) 617 if err1 == nil { 618 atomic.AddInt32(&successCount, 1) 619 } 620 wg.Done() 621 }(map[string]string{"k0": newValue}) 622 } 623 wg.Wait() 624 m.Equal(int32(1), successCount) 625 626 resp, err3 := m.GetNamespace("", name) 627 m.NoError(err3) 628 m.NotNil(resp) 629 m.Equal(name, resp.Namespace.Info.Name) 630 m.Equal(state, resp.Namespace.Info.State) 631 m.Equal(description, resp.Namespace.Info.Description) 632 m.Equal(owner, resp.Namespace.Info.Owner) 633 m.EqualValues(time.Duration(retention)*time.Hour*24, resp.Namespace.Config.Retention.AsDuration()) 634 m.Equal(historyArchivalState, resp.Namespace.Config.HistoryArchivalState) 635 m.Equal(historyArchivalURI, resp.Namespace.Config.HistoryArchivalUri) 636 m.Equal(visibilityArchivalState, resp.Namespace.Config.VisibilityArchivalState) 637 m.Equal(visibilityArchivalURI, resp.Namespace.Config.VisibilityArchivalUri) 638 m.ProtoEqual(testBinaries, resp.Namespace.Config.BadBinaries) 639 m.Equal(clusterActive, resp.Namespace.ReplicationConfig.ActiveClusterName) 640 m.Equal(len(clusters), len(resp.Namespace.ReplicationConfig.Clusters)) 641 for index := range clusters { 642 m.Equal(clusters[index], resp.Namespace.ReplicationConfig.Clusters[index]) 643 } 644 m.Equal(isGlobalNamespace, resp.IsGlobalNamespace) 645 m.Equal(configVersion, resp.Namespace.ConfigVersion) 646 m.Equal(failoverVersion, resp.Namespace.FailoverVersion) 647 648 // check namespace data 649 ss := strings.Split(resp.Namespace.Info.Data["k0"], "-") 650 m.Equal(2, len(ss)) 651 vi, err := strconv.Atoi(ss[1]) 652 m.NoError(err) 653 m.Equal(true, vi > 0 && vi <= concurrency) 654 } 655 656 // TestConcurrentUpdateNamespace test 657 func (m *MetadataPersistenceSuiteV2) TestConcurrentUpdateNamespace() { 658 id := uuid.New() 659 name := "concurrent-update-namespace-test-name" 660 state := enumspb.NAMESPACE_STATE_REGISTERED 661 description := "update-namespace-test-description" 662 owner := "update-namespace-test-owner" 663 data := map[string]string{"k1": "v1"} 664 retention := int32(10) 665 historyArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 666 historyArchivalURI := "test://history/uri" 667 visibilityArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 668 visibilityArchivalURI := "test://visibility/uri" 669 badBinaries := &namespacepb.BadBinaries{Binaries: map[string]*namespacepb.BadBinaryInfo{}} 670 671 clusterActive := "some random active cluster name" 672 clusterStandby := "some random standby cluster name" 673 configVersion := int64(10) 674 failoverVersion := int64(59) 675 isGlobalNamespace := true 676 clusters := []string{clusterActive, clusterStandby} 677 678 resp1, err1 := m.CreateNamespace( 679 &persistencespb.NamespaceInfo{ 680 Id: id, 681 Name: name, 682 State: state, 683 Description: description, 684 Owner: owner, 685 Data: data, 686 }, 687 &persistencespb.NamespaceConfig{ 688 Retention: timestamp.DurationFromDays(retention), 689 HistoryArchivalState: historyArchivalState, 690 HistoryArchivalUri: historyArchivalURI, 691 VisibilityArchivalState: visibilityArchivalState, 692 VisibilityArchivalUri: visibilityArchivalURI, 693 BadBinaries: badBinaries, 694 }, 695 &persistencespb.NamespaceReplicationConfig{ 696 ActiveClusterName: clusterActive, 697 Clusters: clusters, 698 }, 699 isGlobalNamespace, 700 configVersion, 701 failoverVersion, 702 ) 703 m.NoError(err1) 704 m.EqualValues(id, resp1.ID) 705 706 resp2, err2 := m.GetNamespace(id, "") 707 m.NoError(err2) 708 m.Equal(badBinaries, resp2.Namespace.Config.BadBinaries) 709 metadata, err := m.MetadataManager.GetMetadata(m.ctx) 710 m.NoError(err) 711 notificationVersion := metadata.NotificationVersion 712 713 testBinaries := &namespacepb.BadBinaries{ 714 Binaries: map[string]*namespacepb.BadBinaryInfo{ 715 "abc": { 716 Reason: "test-reason", 717 Operator: "test-operator", 718 CreateTime: timestamppb.New(time.Date(2020, 8, 22, 0, 0, 0, 0, time.UTC)), 719 }, 720 }, 721 } 722 concurrency := 16 723 successCount := int32(0) 724 var wg sync.WaitGroup 725 for i := 1; i <= concurrency; i++ { 726 newValue := fmt.Sprintf("v-%v", i) 727 wg.Add(1) 728 go func(updatedData map[string]string) { 729 err3 := m.UpdateNamespace( 730 &persistencespb.NamespaceInfo{ 731 Id: resp2.Namespace.Info.Id, 732 Name: resp2.Namespace.Info.Name, 733 State: resp2.Namespace.Info.State, 734 Description: resp2.Namespace.Info.Description, 735 Owner: resp2.Namespace.Info.Owner, 736 Data: updatedData, 737 }, 738 &persistencespb.NamespaceConfig{ 739 Retention: resp2.Namespace.Config.Retention, 740 HistoryArchivalState: resp2.Namespace.Config.HistoryArchivalState, 741 HistoryArchivalUri: resp2.Namespace.Config.HistoryArchivalUri, 742 VisibilityArchivalState: resp2.Namespace.Config.VisibilityArchivalState, 743 VisibilityArchivalUri: resp2.Namespace.Config.VisibilityArchivalUri, 744 BadBinaries: testBinaries, 745 }, 746 &persistencespb.NamespaceReplicationConfig{ 747 ActiveClusterName: resp2.Namespace.ReplicationConfig.ActiveClusterName, 748 Clusters: resp2.Namespace.ReplicationConfig.Clusters, 749 }, 750 resp2.Namespace.ConfigVersion, 751 resp2.Namespace.FailoverVersion, 752 resp2.Namespace.FailoverNotificationVersion, 753 time.Time{}, 754 notificationVersion, 755 isGlobalNamespace, 756 ) 757 if err3 == nil { 758 atomic.AddInt32(&successCount, 1) 759 } 760 wg.Done() 761 }(map[string]string{"k0": newValue}) 762 } 763 wg.Wait() 764 m.Equal(int32(1), successCount) 765 766 resp3, err3 := m.GetNamespace("", name) 767 m.NoError(err3) 768 m.NotNil(resp3) 769 m.EqualValues(id, resp3.Namespace.Info.Id) 770 m.Equal(name, resp3.Namespace.Info.Name) 771 m.Equal(state, resp3.Namespace.Info.State) 772 m.Equal(isGlobalNamespace, resp3.IsGlobalNamespace) 773 m.Equal(description, resp3.Namespace.Info.Description) 774 m.Equal(owner, resp3.Namespace.Info.Owner) 775 776 m.EqualValues(time.Duration(retention)*time.Hour*24, resp3.Namespace.Config.Retention.AsDuration()) 777 m.Equal(historyArchivalState, resp3.Namespace.Config.HistoryArchivalState) 778 m.Equal(historyArchivalURI, resp3.Namespace.Config.HistoryArchivalUri) 779 m.Equal(visibilityArchivalState, resp3.Namespace.Config.VisibilityArchivalState) 780 m.Equal(visibilityArchivalURI, resp3.Namespace.Config.VisibilityArchivalUri) 781 m.ProtoEqual(testBinaries, resp3.Namespace.Config.BadBinaries) 782 m.Equal(clusterActive, resp3.Namespace.ReplicationConfig.ActiveClusterName) 783 m.Equal(len(clusters), len(resp3.Namespace.ReplicationConfig.Clusters)) 784 for index := range clusters { 785 m.Equal(clusters[index], resp3.Namespace.ReplicationConfig.Clusters[index]) 786 } 787 m.Equal(isGlobalNamespace, resp3.IsGlobalNamespace) 788 m.Equal(configVersion, resp3.Namespace.ConfigVersion) 789 m.Equal(failoverVersion, resp3.Namespace.FailoverVersion) 790 791 // check namespace data 792 ss := strings.Split(resp3.Namespace.Info.Data["k0"], "-") 793 m.Equal(2, len(ss)) 794 vi, err := strconv.Atoi(ss[1]) 795 m.NoError(err) 796 m.Equal(true, vi > 0 && vi <= concurrency) 797 } 798 799 // TestUpdateNamespace test 800 func (m *MetadataPersistenceSuiteV2) TestUpdateNamespace() { 801 id := uuid.New() 802 name := "update-namespace-test-name" 803 state := enumspb.NAMESPACE_STATE_REGISTERED 804 description := "update-namespace-test-description" 805 owner := "update-namespace-test-owner" 806 data := map[string]string{"k1": "v1"} 807 retention := int32(10) 808 historyArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 809 historyArchivalURI := "test://history/uri" 810 visibilityArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 811 visibilityArchivalURI := "test://visibility/uri" 812 813 clusterActive := "some random active cluster name" 814 clusterStandby := "some random standby cluster name" 815 configVersion := int64(10) 816 failoverVersion := int64(59) 817 failoverEndTime := time.Now().UTC() 818 isGlobalNamespace := true 819 clusters := []string{clusterActive, clusterStandby} 820 821 resp1, err1 := m.CreateNamespace( 822 &persistencespb.NamespaceInfo{ 823 Id: id, 824 Name: name, 825 State: state, 826 Description: description, 827 Owner: owner, 828 Data: data, 829 }, 830 &persistencespb.NamespaceConfig{ 831 Retention: timestamp.DurationFromDays(retention), 832 HistoryArchivalState: historyArchivalState, 833 HistoryArchivalUri: historyArchivalURI, 834 VisibilityArchivalState: visibilityArchivalState, 835 VisibilityArchivalUri: visibilityArchivalURI, 836 }, 837 &persistencespb.NamespaceReplicationConfig{ 838 ActiveClusterName: clusterActive, 839 Clusters: clusters, 840 }, 841 isGlobalNamespace, 842 configVersion, 843 failoverVersion, 844 ) 845 m.NoError(err1) 846 m.EqualValues(id, resp1.ID) 847 848 resp2, err2 := m.GetNamespace(id, "") 849 m.NoError(err2) 850 metadata, err := m.MetadataManager.GetMetadata(m.ctx) 851 m.NoError(err) 852 notificationVersion := metadata.NotificationVersion 853 854 updatedState := enumspb.NAMESPACE_STATE_DEPRECATED 855 updatedDescription := "description-updated" 856 updatedOwner := "owner-updated" 857 // This will overriding the previous key-value pair 858 updatedData := map[string]string{"k1": "v2"} 859 updatedRetention := timestamp.DurationFromDays(20) 860 updatedHistoryArchivalState := enumspb.ARCHIVAL_STATE_DISABLED 861 updatedHistoryArchivalURI := "" 862 updatedVisibilityArchivalState := enumspb.ARCHIVAL_STATE_DISABLED 863 updatedVisibilityArchivalURI := "" 864 865 updateClusterActive := "other random active cluster name" 866 updateClusterStandby := "other random standby cluster name" 867 updateConfigVersion := int64(12) 868 updateFailoverVersion := int64(28) 869 updateFailoverNotificationVersion := int64(14) 870 updateClusters := []string{updateClusterActive, updateClusterStandby} 871 872 testBinaries := &namespacepb.BadBinaries{ 873 Binaries: map[string]*namespacepb.BadBinaryInfo{ 874 "abc": { 875 Reason: "test-reason", 876 Operator: "test-operator", 877 CreateTime: timestamppb.New(time.Date(2020, 8, 22, 0, 0, 0, 0, time.UTC)), 878 }, 879 }, 880 } 881 882 err3 := m.UpdateNamespace( 883 &persistencespb.NamespaceInfo{ 884 Id: resp2.Namespace.Info.Id, 885 Name: resp2.Namespace.Info.Name, 886 State: updatedState, 887 Description: updatedDescription, 888 Owner: updatedOwner, 889 Data: updatedData, 890 }, 891 &persistencespb.NamespaceConfig{ 892 Retention: updatedRetention, 893 HistoryArchivalState: updatedHistoryArchivalState, 894 HistoryArchivalUri: updatedHistoryArchivalURI, 895 VisibilityArchivalState: updatedVisibilityArchivalState, 896 VisibilityArchivalUri: updatedVisibilityArchivalURI, 897 BadBinaries: testBinaries, 898 }, 899 &persistencespb.NamespaceReplicationConfig{ 900 ActiveClusterName: updateClusterActive, 901 Clusters: updateClusters, 902 }, 903 updateConfigVersion, 904 updateFailoverVersion, 905 updateFailoverNotificationVersion, 906 failoverEndTime, 907 notificationVersion, 908 isGlobalNamespace, 909 ) 910 m.NoError(err3) 911 912 resp4, err4 := m.GetNamespace("", name) 913 m.NoError(err4) 914 m.NotNil(resp4) 915 m.EqualValues(id, resp4.Namespace.Info.Id) 916 m.Equal(name, resp4.Namespace.Info.Name) 917 m.Equal(isGlobalNamespace, resp4.IsGlobalNamespace) 918 m.Equal(updatedState, resp4.Namespace.Info.State) 919 m.Equal(updatedDescription, resp4.Namespace.Info.Description) 920 m.Equal(updatedOwner, resp4.Namespace.Info.Owner) 921 m.Equal(updatedData, resp4.Namespace.Info.Data) 922 m.ProtoEqual(updatedRetention, resp4.Namespace.Config.Retention) 923 m.Equal(updatedHistoryArchivalState, resp4.Namespace.Config.HistoryArchivalState) 924 m.Equal(updatedHistoryArchivalURI, resp4.Namespace.Config.HistoryArchivalUri) 925 m.Equal(updatedVisibilityArchivalState, resp4.Namespace.Config.VisibilityArchivalState) 926 m.Equal(updatedVisibilityArchivalURI, resp4.Namespace.Config.VisibilityArchivalUri) 927 m.ProtoEqual(testBinaries, resp4.Namespace.Config.BadBinaries) 928 m.Equal(updateClusterActive, resp4.Namespace.ReplicationConfig.ActiveClusterName) 929 m.Equal(len(updateClusters), len(resp4.Namespace.ReplicationConfig.Clusters)) 930 for index := range clusters { 931 m.Equal(updateClusters[index], resp4.Namespace.ReplicationConfig.Clusters[index]) 932 } 933 m.Equal(updateConfigVersion, resp4.Namespace.ConfigVersion) 934 m.Equal(updateFailoverVersion, resp4.Namespace.FailoverVersion) 935 m.Equal(updateFailoverNotificationVersion, resp4.Namespace.FailoverNotificationVersion) 936 m.Equal(notificationVersion, resp4.NotificationVersion) 937 m.EqualTimes(failoverEndTime, resp4.Namespace.FailoverEndTime.AsTime()) 938 939 resp5, err5 := m.GetNamespace(id, "") 940 m.NoError(err5) 941 m.NotNil(resp5) 942 m.EqualValues(id, resp5.Namespace.Info.Id) 943 m.Equal(name, resp5.Namespace.Info.Name) 944 m.Equal(isGlobalNamespace, resp5.IsGlobalNamespace) 945 m.Equal(updatedState, resp5.Namespace.Info.State) 946 m.Equal(updatedDescription, resp5.Namespace.Info.Description) 947 m.Equal(updatedOwner, resp5.Namespace.Info.Owner) 948 m.Equal(updatedData, resp5.Namespace.Info.Data) 949 m.ProtoEqual(updatedRetention, resp5.Namespace.Config.Retention) 950 m.Equal(updatedHistoryArchivalState, resp5.Namespace.Config.HistoryArchivalState) 951 m.Equal(updatedHistoryArchivalURI, resp5.Namespace.Config.HistoryArchivalUri) 952 m.Equal(updatedVisibilityArchivalState, resp5.Namespace.Config.VisibilityArchivalState) 953 m.Equal(updatedVisibilityArchivalURI, resp5.Namespace.Config.VisibilityArchivalUri) 954 m.Equal(updateClusterActive, resp5.Namespace.ReplicationConfig.ActiveClusterName) 955 m.Equal(len(updateClusters), len(resp5.Namespace.ReplicationConfig.Clusters)) 956 for index := range clusters { 957 m.Equal(updateClusters[index], resp5.Namespace.ReplicationConfig.Clusters[index]) 958 } 959 m.Equal(updateConfigVersion, resp5.Namespace.ConfigVersion) 960 m.Equal(updateFailoverVersion, resp5.Namespace.FailoverVersion) 961 m.Equal(updateFailoverNotificationVersion, resp5.Namespace.FailoverNotificationVersion) 962 m.Equal(notificationVersion, resp5.NotificationVersion) 963 m.EqualTimes(failoverEndTime, resp4.Namespace.FailoverEndTime.AsTime()) 964 965 notificationVersion++ 966 err6 := m.UpdateNamespace( 967 &persistencespb.NamespaceInfo{ 968 Id: resp2.Namespace.Info.Id, 969 Name: resp2.Namespace.Info.Name, 970 State: updatedState, 971 Description: updatedDescription, 972 Owner: updatedOwner, 973 Data: updatedData, 974 }, 975 &persistencespb.NamespaceConfig{ 976 Retention: updatedRetention, 977 HistoryArchivalState: updatedHistoryArchivalState, 978 HistoryArchivalUri: updatedHistoryArchivalURI, 979 VisibilityArchivalState: updatedVisibilityArchivalState, 980 VisibilityArchivalUri: updatedVisibilityArchivalURI, 981 BadBinaries: testBinaries, 982 }, 983 &persistencespb.NamespaceReplicationConfig{ 984 ActiveClusterName: updateClusterActive, 985 Clusters: updateClusters, 986 }, 987 updateConfigVersion, 988 updateFailoverVersion, 989 updateFailoverNotificationVersion, 990 time.Time{}, 991 notificationVersion, 992 isGlobalNamespace, 993 ) 994 m.NoError(err6) 995 996 resp6, err6 := m.GetNamespace(id, "") 997 m.NoError(err6) 998 m.NotNil(resp6) 999 m.EqualValues(id, resp6.Namespace.Info.Id) 1000 m.Equal(name, resp6.Namespace.Info.Name) 1001 m.Equal(isGlobalNamespace, resp6.IsGlobalNamespace) 1002 m.Equal(updatedState, resp6.Namespace.Info.State) 1003 m.Equal(updatedDescription, resp6.Namespace.Info.Description) 1004 m.Equal(updatedOwner, resp6.Namespace.Info.Owner) 1005 m.Equal(updatedData, resp6.Namespace.Info.Data) 1006 m.ProtoEqual(updatedRetention, resp6.Namespace.Config.Retention) 1007 m.Equal(updatedHistoryArchivalState, resp6.Namespace.Config.HistoryArchivalState) 1008 m.Equal(updatedHistoryArchivalURI, resp6.Namespace.Config.HistoryArchivalUri) 1009 m.Equal(updatedVisibilityArchivalState, resp6.Namespace.Config.VisibilityArchivalState) 1010 m.Equal(updatedVisibilityArchivalURI, resp6.Namespace.Config.VisibilityArchivalUri) 1011 m.ProtoEqual(testBinaries, resp6.Namespace.Config.BadBinaries) 1012 m.Equal(updateClusterActive, resp6.Namespace.ReplicationConfig.ActiveClusterName) 1013 m.Equal(len(updateClusters), len(resp6.Namespace.ReplicationConfig.Clusters)) 1014 for index := range clusters { 1015 m.Equal(updateClusters[index], resp4.Namespace.ReplicationConfig.Clusters[index]) 1016 } 1017 m.Equal(updateConfigVersion, resp6.Namespace.ConfigVersion) 1018 m.Equal(updateFailoverVersion, resp6.Namespace.FailoverVersion) 1019 m.Equal(updateFailoverNotificationVersion, resp6.Namespace.FailoverNotificationVersion) 1020 m.Equal(notificationVersion, resp6.NotificationVersion) 1021 m.EqualTimes(time.Unix(0, 0).UTC(), resp6.Namespace.FailoverEndTime.AsTime()) 1022 } 1023 1024 func (m *MetadataPersistenceSuiteV2) TestRenameNamespace() { 1025 id := uuid.New() 1026 name := "rename-namespace-test-name" 1027 newName := "rename-namespace-test-new-name" 1028 newNewName := "rename-namespace-test-new-new-name" 1029 state := enumspb.NAMESPACE_STATE_REGISTERED 1030 description := "rename-namespace-test-description" 1031 owner := "rename-namespace-test-owner" 1032 data := map[string]string{"k1": "v1"} 1033 retention := int32(10) 1034 historyArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 1035 historyArchivalURI := "test://history/uri" 1036 visibilityArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 1037 visibilityArchivalURI := "test://visibility/uri" 1038 1039 clusterActive := "some random active cluster name" 1040 clusterStandby := "some random standby cluster name" 1041 configVersion := int64(10) 1042 failoverVersion := int64(59) 1043 isGlobalNamespace := true 1044 clusters := []string{clusterActive, clusterStandby} 1045 1046 resp1, err1 := m.CreateNamespace( 1047 &persistencespb.NamespaceInfo{ 1048 Id: id, 1049 Name: name, 1050 State: state, 1051 Description: description, 1052 Owner: owner, 1053 Data: data, 1054 }, 1055 &persistencespb.NamespaceConfig{ 1056 Retention: timestamp.DurationFromDays(retention), 1057 HistoryArchivalState: historyArchivalState, 1058 HistoryArchivalUri: historyArchivalURI, 1059 VisibilityArchivalState: visibilityArchivalState, 1060 VisibilityArchivalUri: visibilityArchivalURI, 1061 }, 1062 &persistencespb.NamespaceReplicationConfig{ 1063 ActiveClusterName: clusterActive, 1064 Clusters: clusters, 1065 }, 1066 isGlobalNamespace, 1067 configVersion, 1068 failoverVersion, 1069 ) 1070 m.NoError(err1) 1071 m.EqualValues(id, resp1.ID) 1072 1073 _, err2 := m.GetNamespace(id, "") 1074 m.NoError(err2) 1075 1076 err3 := m.MetadataManager.RenameNamespace(m.ctx, &p.RenameNamespaceRequest{ 1077 PreviousName: name, 1078 NewName: newName, 1079 }) 1080 m.NoError(err3) 1081 1082 resp4, err4 := m.GetNamespace("", newName) 1083 m.NoError(err4) 1084 m.NotNil(resp4) 1085 m.EqualValues(id, resp4.Namespace.Info.Id) 1086 m.Equal(newName, resp4.Namespace.Info.Name) 1087 m.Equal(isGlobalNamespace, resp4.IsGlobalNamespace) 1088 1089 resp5, err5 := m.GetNamespace(id, "") 1090 m.NoError(err5) 1091 m.NotNil(resp5) 1092 m.EqualValues(id, resp5.Namespace.Info.Id) 1093 m.Equal(newName, resp5.Namespace.Info.Name) 1094 m.Equal(isGlobalNamespace, resp5.IsGlobalNamespace) 1095 1096 err6 := m.MetadataManager.RenameNamespace(m.ctx, &p.RenameNamespaceRequest{ 1097 PreviousName: newName, 1098 NewName: newNewName, 1099 }) 1100 m.NoError(err6) 1101 1102 resp6, err6 := m.GetNamespace(id, "") 1103 m.NoError(err6) 1104 m.NotNil(resp6) 1105 m.EqualValues(id, resp6.Namespace.Info.Id) 1106 m.Equal(newNewName, resp6.Namespace.Info.Name) 1107 m.Equal(isGlobalNamespace, resp6.IsGlobalNamespace) 1108 } 1109 1110 // TestDeleteNamespace test 1111 func (m *MetadataPersistenceSuiteV2) TestDeleteNamespace() { 1112 id := uuid.New() 1113 name := "delete-namespace-test-name" 1114 state := enumspb.NAMESPACE_STATE_REGISTERED 1115 description := "delete-namespace-test-description" 1116 owner := "delete-namespace-test-owner" 1117 data := map[string]string{"k1": "v1"} 1118 retention := timestamp.DurationFromDays(10) 1119 historyArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 1120 historyArchivalURI := "test://history/uri" 1121 visibilityArchivalState := enumspb.ARCHIVAL_STATE_ENABLED 1122 visibilityArchivalURI := "test://visibility/uri" 1123 1124 clusterActive := "some random active cluster name" 1125 clusterStandby := "some random standby cluster name" 1126 configVersion := int64(10) 1127 failoverVersion := int64(59) 1128 isGlobalNamespace := true 1129 clusters := []string{clusterActive, clusterStandby} 1130 1131 resp1, err1 := m.CreateNamespace( 1132 &persistencespb.NamespaceInfo{ 1133 Id: id, 1134 Name: name, 1135 State: state, 1136 Description: description, 1137 Owner: owner, 1138 Data: data, 1139 }, 1140 &persistencespb.NamespaceConfig{ 1141 Retention: retention, 1142 HistoryArchivalState: historyArchivalState, 1143 HistoryArchivalUri: historyArchivalURI, 1144 VisibilityArchivalState: visibilityArchivalState, 1145 VisibilityArchivalUri: visibilityArchivalURI, 1146 }, 1147 &persistencespb.NamespaceReplicationConfig{ 1148 ActiveClusterName: clusterActive, 1149 Clusters: clusters, 1150 }, 1151 isGlobalNamespace, 1152 configVersion, 1153 failoverVersion, 1154 ) 1155 m.NoError(err1) 1156 m.EqualValues(id, resp1.ID) 1157 1158 resp2, err2 := m.GetNamespace("", name) 1159 m.NoError(err2) 1160 m.NotNil(resp2) 1161 1162 err3 := m.DeleteNamespace("", name) 1163 m.NoError(err3) 1164 1165 // May need to loop here to avoid potential inconsistent read-after-write in cassandra 1166 var err4 error 1167 var resp4 *p.GetNamespaceResponse 1168 for i := 0; i < 3; i++ { 1169 resp4, err4 = m.GetNamespace("", name) 1170 if err4 != nil { 1171 break 1172 } 1173 time.Sleep(time.Second * time.Duration(i)) 1174 } 1175 m.Error(err4) 1176 m.IsType(&serviceerror.NamespaceNotFound{}, err4) 1177 m.Nil(resp4) 1178 1179 resp5, err5 := m.GetNamespace(id, "") 1180 m.Error(err5) 1181 m.IsType(&serviceerror.NamespaceNotFound{}, err5) 1182 m.Nil(resp5) 1183 1184 id = uuid.New() 1185 resp6, err6 := m.CreateNamespace( 1186 &persistencespb.NamespaceInfo{ 1187 Id: id, 1188 Name: name, 1189 State: state, 1190 Description: description, 1191 Owner: owner, 1192 Data: data, 1193 }, 1194 &persistencespb.NamespaceConfig{ 1195 Retention: retention, 1196 HistoryArchivalState: historyArchivalState, 1197 HistoryArchivalUri: historyArchivalURI, 1198 VisibilityArchivalState: visibilityArchivalState, 1199 VisibilityArchivalUri: visibilityArchivalURI, 1200 }, 1201 &persistencespb.NamespaceReplicationConfig{ 1202 ActiveClusterName: clusterActive, 1203 Clusters: clusters, 1204 }, 1205 isGlobalNamespace, 1206 configVersion, 1207 failoverVersion, 1208 ) 1209 m.NoError(err6) 1210 m.EqualValues(id, resp6.ID) 1211 1212 err7 := m.DeleteNamespace(id, "") 1213 m.NoError(err7) 1214 1215 resp8, err8 := m.GetNamespace("", name) 1216 m.Error(err8) 1217 m.IsType(&serviceerror.NamespaceNotFound{}, err8) 1218 m.Nil(resp8) 1219 1220 resp9, err9 := m.GetNamespace(id, "") 1221 m.Error(err9) 1222 m.IsType(&serviceerror.NamespaceNotFound{}, err9) 1223 m.Nil(resp9) 1224 } 1225 1226 // TestListNamespaces test 1227 func (m *MetadataPersistenceSuiteV2) TestListNamespaces() { 1228 clusterActive1 := "some random active cluster name" 1229 clusterStandby1 := "some random standby cluster name" 1230 clusters1 := []string{clusterActive1, clusterStandby1} 1231 1232 clusterActive2 := "other random active cluster name" 1233 clusterStandby2 := "other random standby cluster name" 1234 clusters2 := []string{clusterActive2, clusterStandby2} 1235 1236 testBinaries1 := &namespacepb.BadBinaries{ 1237 Binaries: map[string]*namespacepb.BadBinaryInfo{ 1238 "abc": { 1239 Reason: "test-reason1", 1240 Operator: "test-operator1", 1241 CreateTime: timestamppb.New(time.Date(2020, 8, 22, 0, 0, 0, 0, time.UTC)), 1242 }, 1243 }, 1244 } 1245 testBinaries2 := &namespacepb.BadBinaries{ 1246 Binaries: map[string]*namespacepb.BadBinaryInfo{ 1247 "efg": { 1248 Reason: "test-reason2", 1249 Operator: "test-operator2", 1250 CreateTime: timestamppb.New(time.Date(2020, 8, 22, 0, 0, 0, 0, time.UTC)), 1251 }, 1252 }, 1253 } 1254 1255 inputNamespaces := []*p.GetNamespaceResponse{ 1256 { 1257 Namespace: &persistencespb.NamespaceDetail{ 1258 Info: &persistencespb.NamespaceInfo{ 1259 Id: uuid.New(), 1260 Name: "list-namespace-test-name-1", 1261 State: enumspb.NAMESPACE_STATE_REGISTERED, 1262 Description: "list-namespace-test-description-1", 1263 Owner: "list-namespace-test-owner-1", 1264 Data: map[string]string{"k1": "v1"}, 1265 }, 1266 Config: &persistencespb.NamespaceConfig{ 1267 Retention: timestamp.DurationFromDays(109), 1268 HistoryArchivalState: enumspb.ARCHIVAL_STATE_ENABLED, 1269 HistoryArchivalUri: "test://history/uri", 1270 VisibilityArchivalState: enumspb.ARCHIVAL_STATE_ENABLED, 1271 VisibilityArchivalUri: "test://visibility/uri", 1272 BadBinaries: testBinaries1, 1273 }, 1274 ReplicationConfig: &persistencespb.NamespaceReplicationConfig{ 1275 ActiveClusterName: clusterActive1, 1276 Clusters: clusters1, 1277 }, 1278 1279 ConfigVersion: 133, 1280 FailoverVersion: 266, 1281 }, 1282 IsGlobalNamespace: true, 1283 }, 1284 { 1285 Namespace: &persistencespb.NamespaceDetail{ 1286 Info: &persistencespb.NamespaceInfo{ 1287 Id: uuid.New(), 1288 Name: "list-namespace-test-name-2", 1289 State: enumspb.NAMESPACE_STATE_REGISTERED, 1290 Description: "list-namespace-test-description-2", 1291 Owner: "list-namespace-test-owner-2", 1292 Data: map[string]string{"k1": "v2"}, 1293 }, 1294 Config: &persistencespb.NamespaceConfig{ 1295 Retention: timestamp.DurationFromDays(326), 1296 HistoryArchivalState: enumspb.ARCHIVAL_STATE_DISABLED, 1297 HistoryArchivalUri: "", 1298 VisibilityArchivalState: enumspb.ARCHIVAL_STATE_DISABLED, 1299 VisibilityArchivalUri: "", 1300 BadBinaries: testBinaries2, 1301 }, 1302 ReplicationConfig: &persistencespb.NamespaceReplicationConfig{ 1303 ActiveClusterName: clusterActive2, 1304 Clusters: clusters2, 1305 }, 1306 ConfigVersion: 400, 1307 FailoverVersion: 667, 1308 }, 1309 IsGlobalNamespace: false, 1310 }, 1311 } 1312 for _, namespace := range inputNamespaces { 1313 _, err := m.CreateNamespace( 1314 namespace.Namespace.Info, 1315 namespace.Namespace.Config, 1316 namespace.Namespace.ReplicationConfig, 1317 namespace.IsGlobalNamespace, 1318 namespace.Namespace.ConfigVersion, 1319 namespace.Namespace.FailoverVersion, 1320 ) 1321 m.NoError(err) 1322 } 1323 1324 var token []byte 1325 const pageSize = 1 1326 pageCount := 0 1327 outputNamespaces := make(map[string]*p.GetNamespaceResponse) 1328 for { 1329 resp, err := m.ListNamespaces(pageSize, token) 1330 m.NoError(err) 1331 token = resp.NextPageToken 1332 for _, namespace := range resp.Namespaces { 1333 outputNamespaces[namespace.Namespace.Info.Id] = namespace 1334 // global notification version is already tested, so here we make it 0 1335 // so we can test == easily 1336 namespace.NotificationVersion = 0 1337 } 1338 pageCount++ 1339 if len(token) == 0 { 1340 break 1341 } 1342 } 1343 1344 // 2 pages with data and 1 empty page which is unavoidable. 1345 m.Equal(pageCount, 3) 1346 m.Equal(len(inputNamespaces), len(outputNamespaces)) 1347 for _, namespace := range inputNamespaces { 1348 m.DeepEqual(namespace, outputNamespaces[namespace.Namespace.Info.Id]) 1349 } 1350 } 1351 1352 func (m *MetadataPersistenceSuiteV2) TestListNamespaces_DeletedNamespace() { 1353 inputNamespaces := []*p.GetNamespaceResponse{ 1354 { 1355 Namespace: &persistencespb.NamespaceDetail{ 1356 Info: &persistencespb.NamespaceInfo{ 1357 Id: uuid.New(), 1358 Name: "list-namespace-test-name-1", 1359 State: enumspb.NAMESPACE_STATE_REGISTERED, 1360 }, 1361 Config: &persistencespb.NamespaceConfig{}, 1362 ReplicationConfig: &persistencespb.NamespaceReplicationConfig{}, 1363 }, 1364 }, 1365 { 1366 Namespace: &persistencespb.NamespaceDetail{ 1367 Info: &persistencespb.NamespaceInfo{ 1368 Id: uuid.New(), 1369 Name: "list-namespace-test-name-2", 1370 State: enumspb.NAMESPACE_STATE_DELETED, 1371 }, 1372 Config: &persistencespb.NamespaceConfig{}, 1373 ReplicationConfig: &persistencespb.NamespaceReplicationConfig{}, 1374 }, 1375 }, 1376 { 1377 Namespace: &persistencespb.NamespaceDetail{ 1378 Info: &persistencespb.NamespaceInfo{ 1379 Id: uuid.New(), 1380 Name: "list-namespace-test-name-3", 1381 State: enumspb.NAMESPACE_STATE_REGISTERED, 1382 }, 1383 Config: &persistencespb.NamespaceConfig{}, 1384 ReplicationConfig: &persistencespb.NamespaceReplicationConfig{}, 1385 }, 1386 }, 1387 { 1388 Namespace: &persistencespb.NamespaceDetail{ 1389 Info: &persistencespb.NamespaceInfo{ 1390 Id: uuid.New(), 1391 Name: "list-namespace-test-name-4", 1392 State: enumspb.NAMESPACE_STATE_DELETED, 1393 }, 1394 Config: &persistencespb.NamespaceConfig{}, 1395 ReplicationConfig: &persistencespb.NamespaceReplicationConfig{}, 1396 }, 1397 }, 1398 } 1399 for _, namespace := range inputNamespaces { 1400 _, err := m.CreateNamespace( 1401 namespace.Namespace.Info, 1402 namespace.Namespace.Config, 1403 namespace.Namespace.ReplicationConfig, 1404 namespace.IsGlobalNamespace, 1405 namespace.Namespace.ConfigVersion, 1406 namespace.Namespace.FailoverVersion, 1407 ) 1408 m.NoError(err) 1409 } 1410 1411 var token []byte 1412 var listNamespacesPageSize2 []*p.GetNamespaceResponse 1413 pageCount := 0 1414 for { 1415 resp, err := m.ListNamespaces(2, token) 1416 m.NoError(err) 1417 token = resp.NextPageToken 1418 listNamespacesPageSize2 = append(listNamespacesPageSize2, resp.Namespaces...) 1419 pageCount++ 1420 if len(token) == 0 { 1421 break 1422 } 1423 } 1424 1425 // 1 page with data and 1 empty page which is unavoidable. 1426 m.Equal(2, pageCount) 1427 m.Len(listNamespacesPageSize2, 2) 1428 for _, namespace := range listNamespacesPageSize2 { 1429 m.NotEqual(namespace.Namespace.Info.State, enumspb.NAMESPACE_STATE_DELETED) 1430 } 1431 1432 pageCount = 0 1433 var listNamespacesPageSize1 []*p.GetNamespaceResponse 1434 for { 1435 resp, err := m.ListNamespaces(1, token) 1436 m.NoError(err) 1437 token = resp.NextPageToken 1438 listNamespacesPageSize1 = append(listNamespacesPageSize1, resp.Namespaces...) 1439 pageCount++ 1440 if len(token) == 0 { 1441 break 1442 } 1443 } 1444 1445 // 2 pages with data and 1 empty page which is unavoidable. 1446 m.Equal(3, pageCount) 1447 m.Len(listNamespacesPageSize1, 2) 1448 for _, namespace := range listNamespacesPageSize1 { 1449 m.NotEqual(namespace.Namespace.Info.State, enumspb.NAMESPACE_STATE_DELETED) 1450 } 1451 } 1452 1453 // CreateNamespace helper method 1454 func (m *MetadataPersistenceSuiteV2) CreateNamespace(info *persistencespb.NamespaceInfo, config *persistencespb.NamespaceConfig, 1455 replicationConfig *persistencespb.NamespaceReplicationConfig, isGlobalnamespace bool, configVersion int64, failoverVersion int64) (*p.CreateNamespaceResponse, error) { 1456 return m.MetadataManager.CreateNamespace(m.ctx, &p.CreateNamespaceRequest{ 1457 Namespace: &persistencespb.NamespaceDetail{ 1458 Info: info, 1459 Config: config, 1460 ReplicationConfig: replicationConfig, 1461 1462 ConfigVersion: configVersion, 1463 FailoverVersion: failoverVersion, 1464 }, IsGlobalNamespace: isGlobalnamespace, 1465 }) 1466 } 1467 1468 // GetNamespace helper method 1469 func (m *MetadataPersistenceSuiteV2) GetNamespace(id string, name string) (*p.GetNamespaceResponse, error) { 1470 return m.MetadataManager.GetNamespace(m.ctx, &p.GetNamespaceRequest{ 1471 ID: id, 1472 Name: name, 1473 }) 1474 } 1475 1476 // UpdateNamespace helper method 1477 func (m *MetadataPersistenceSuiteV2) UpdateNamespace( 1478 info *persistencespb.NamespaceInfo, 1479 config *persistencespb.NamespaceConfig, 1480 replicationConfig *persistencespb.NamespaceReplicationConfig, 1481 configVersion int64, 1482 failoverVersion int64, 1483 failoverNotificationVersion int64, 1484 failoverEndTime time.Time, 1485 notificationVersion int64, 1486 isGlobalNamespace bool, 1487 ) error { 1488 return m.MetadataManager.UpdateNamespace(m.ctx, &p.UpdateNamespaceRequest{ 1489 Namespace: &persistencespb.NamespaceDetail{ 1490 Info: info, 1491 Config: config, 1492 ReplicationConfig: replicationConfig, 1493 ConfigVersion: configVersion, 1494 FailoverVersion: failoverVersion, 1495 FailoverEndTime: timestamppb.New(failoverEndTime), 1496 FailoverNotificationVersion: failoverNotificationVersion, 1497 }, 1498 NotificationVersion: notificationVersion, 1499 IsGlobalNamespace: isGlobalNamespace, 1500 }) 1501 } 1502 1503 // DeleteNamespace helper method 1504 func (m *MetadataPersistenceSuiteV2) DeleteNamespace(id string, name string) error { 1505 if len(id) > 0 { 1506 return m.MetadataManager.DeleteNamespace(m.ctx, &p.DeleteNamespaceRequest{ID: id}) 1507 } 1508 return m.MetadataManager.DeleteNamespaceByName(m.ctx, &p.DeleteNamespaceByNameRequest{Name: name}) 1509 } 1510 1511 // ListNamespaces helper method 1512 func (m *MetadataPersistenceSuiteV2) ListNamespaces(pageSize int, pageToken []byte) (*p.ListNamespacesResponse, error) { 1513 return m.MetadataManager.ListNamespaces(m.ctx, &p.ListNamespacesRequest{ 1514 PageSize: pageSize, 1515 NextPageToken: pageToken, 1516 }) 1517 }