go.temporal.io/server@v1.23.0/common/persistence/visibility/visibility_manager_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 visibility 26 27 import ( 28 "context" 29 "testing" 30 "time" 31 32 "github.com/golang/mock/gomock" 33 "github.com/stretchr/testify/require" 34 "github.com/stretchr/testify/suite" 35 commonpb "go.temporal.io/api/common/v1" 36 enumspb "go.temporal.io/api/enums/v1" 37 38 "go.temporal.io/server/common/dynamicconfig" 39 "go.temporal.io/server/common/namespace" 40 41 "go.temporal.io/server/common/log" 42 "go.temporal.io/server/common/metrics" 43 "go.temporal.io/server/common/persistence" 44 "go.temporal.io/server/common/persistence/sql/sqlplugin/mysql" 45 "go.temporal.io/server/common/persistence/visibility/manager" 46 "go.temporal.io/server/common/persistence/visibility/store" 47 ) 48 49 type VisibilityManagerSuite struct { 50 *require.Assertions // override suite.Suite.Assertions with require.Assertions; this means that s.NotNil(nil) will stop the test, not merely log an error 51 suite.Suite 52 controller *gomock.Controller 53 54 visibilityManager manager.VisibilityManager 55 visibilityStore *store.MockVisibilityStore 56 metricsHandler *metrics.MockHandler 57 } 58 59 var ( 60 testNamespaceUUID = namespace.ID("fb15e4b5-356f-466d-8c6d-a29223e5c536") 61 testNamespace = namespace.Name("test-namespace") 62 testWorkflowExecution = commonpb.WorkflowExecution{ 63 WorkflowId: "visibility-workflow-test", 64 RunId: "843f6fc7-102a-4c63-a2d4-7c653b01bf52", 65 } 66 testWorkflowTypeName = "visibility-workflow" 67 ) 68 69 func TestVisibilityManagerSuite(t *testing.T) { 70 suite.Run(t, new(VisibilityManagerSuite)) 71 } 72 73 func (s *VisibilityManagerSuite) SetupTest() { 74 s.Assertions = require.New(s.T()) // Have to define our overridden assertions in the test setup. If we did it earlier, s.T() will return nil 75 76 s.controller = gomock.NewController(s.T()) 77 s.visibilityStore = store.NewMockVisibilityStore(s.controller) 78 s.visibilityStore.EXPECT().GetName().Return(mysql.PluginNameV8).AnyTimes() 79 s.visibilityStore.EXPECT().GetIndexName().Return("test-index-name").AnyTimes() 80 s.metricsHandler = metrics.NewMockHandler(s.controller) 81 s.visibilityManager = newVisibilityManager( 82 s.visibilityStore, 83 dynamicconfig.GetIntPropertyFn(1), 84 dynamicconfig.GetIntPropertyFn(1), 85 dynamicconfig.GetFloatPropertyFn(0.2), 86 s.metricsHandler, 87 metrics.VisibilityPluginNameTag(s.visibilityStore.GetName()), 88 log.NewNoopLogger()) 89 } 90 91 func (s *VisibilityManagerSuite) TearDownTest() { 92 s.controller.Finish() 93 } 94 95 func (s *VisibilityManagerSuite) TestRecordWorkflowExecutionStarted() { 96 request := &manager.RecordWorkflowExecutionStartedRequest{ 97 VisibilityRequestBase: &manager.VisibilityRequestBase{ 98 NamespaceID: testNamespaceUUID, 99 Namespace: testNamespace, 100 Execution: &testWorkflowExecution, 101 WorkflowTypeName: testWorkflowTypeName, 102 StartTime: time.Now().UTC(), 103 }, 104 } 105 s.visibilityStore.EXPECT().RecordWorkflowExecutionStarted(gomock.Any(), gomock.Any()).Return(nil) 106 s.metricsHandler.EXPECT(). 107 WithTags( 108 metrics.OperationTag(metrics.VisibilityPersistenceRecordWorkflowExecutionStartedScope), 109 metrics.VisibilityPluginNameTag(s.visibilityStore.GetName()), 110 ). 111 Return(metrics.NoopMetricsHandler).Times(2) 112 s.NoError(s.visibilityManager.RecordWorkflowExecutionStarted(context.Background(), request)) 113 114 // no remaining tokens 115 err := s.visibilityManager.RecordWorkflowExecutionStarted(context.Background(), request) 116 s.Error(err) 117 s.ErrorIs(err, persistence.ErrPersistenceLimitExceeded) 118 } 119 120 func (s *VisibilityManagerSuite) TestRecordWorkflowExecutionClosed() { 121 request := &manager.RecordWorkflowExecutionClosedRequest{ 122 VisibilityRequestBase: &manager.VisibilityRequestBase{ 123 NamespaceID: testNamespaceUUID, 124 Namespace: testNamespace, 125 Execution: &testWorkflowExecution, 126 WorkflowTypeName: testWorkflowTypeName, 127 Status: enumspb.WORKFLOW_EXECUTION_STATUS_COMPLETED, 128 }, 129 } 130 131 s.visibilityStore.EXPECT().RecordWorkflowExecutionClosed(gomock.Any(), gomock.Any()).Return(nil) 132 s.metricsHandler.EXPECT(). 133 WithTags(metrics.OperationTag( 134 metrics.VisibilityPersistenceRecordWorkflowExecutionClosedScope), 135 metrics.VisibilityPluginNameTag(s.visibilityStore.GetName()), 136 ). 137 Return(metrics.NoopMetricsHandler).Times(2) 138 s.NoError(s.visibilityManager.RecordWorkflowExecutionClosed(context.Background(), request)) 139 140 err := s.visibilityManager.RecordWorkflowExecutionClosed(context.Background(), request) 141 s.Error(err) 142 s.ErrorIs(err, persistence.ErrPersistenceLimitExceeded) 143 } 144 145 func (s *VisibilityManagerSuite) TestListOpenWorkflowExecutions() { 146 request := &manager.ListWorkflowExecutionsRequest{ 147 NamespaceID: testNamespaceUUID, 148 Namespace: testNamespace, 149 } 150 s.visibilityStore.EXPECT().ListOpenWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil) 151 s.metricsHandler.EXPECT(). 152 WithTags(metrics.OperationTag( 153 metrics.VisibilityPersistenceListOpenWorkflowExecutionsScope), 154 metrics.VisibilityPluginNameTag(s.visibilityStore.GetName()), 155 ). 156 Return(metrics.NoopMetricsHandler).Times(2) 157 _, err := s.visibilityManager.ListOpenWorkflowExecutions(context.Background(), request) 158 s.NoError(err) 159 160 // no remaining tokens 161 _, err = s.visibilityManager.ListOpenWorkflowExecutions(context.Background(), request) 162 s.Error(err) 163 s.Equal(persistence.ErrPersistenceLimitExceeded, err) 164 } 165 166 func (s *VisibilityManagerSuite) TestListClosedWorkflowExecutions() { 167 request := &manager.ListWorkflowExecutionsRequest{ 168 NamespaceID: testNamespaceUUID, 169 Namespace: testNamespace, 170 } 171 s.visibilityStore.EXPECT().ListClosedWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil) 172 s.metricsHandler.EXPECT(). 173 WithTags(metrics.OperationTag( 174 metrics.VisibilityPersistenceListClosedWorkflowExecutionsScope), 175 metrics.VisibilityPluginNameTag(s.visibilityStore.GetName()), 176 ). 177 Return(metrics.NoopMetricsHandler).Times(2) 178 _, err := s.visibilityManager.ListClosedWorkflowExecutions(context.Background(), request) 179 s.NoError(err) 180 181 // no remaining tokens 182 _, err = s.visibilityManager.ListClosedWorkflowExecutions(context.Background(), request) 183 s.Equal(persistence.ErrPersistenceLimitExceeded, err) 184 } 185 186 func (s *VisibilityManagerSuite) TestListOpenWorkflowExecutionsByType() { 187 req := &manager.ListWorkflowExecutionsRequest{ 188 NamespaceID: testNamespaceUUID, 189 Namespace: testNamespace, 190 } 191 request := &manager.ListWorkflowExecutionsByTypeRequest{ 192 ListWorkflowExecutionsRequest: req, 193 WorkflowTypeName: testWorkflowTypeName, 194 } 195 s.visibilityStore.EXPECT().ListOpenWorkflowExecutionsByType(gomock.Any(), gomock.Any()).Return(nil, nil) 196 s.metricsHandler.EXPECT(). 197 WithTags(metrics.OperationTag( 198 metrics.VisibilityPersistenceListOpenWorkflowExecutionsByTypeScope), 199 metrics.VisibilityPluginNameTag(s.visibilityStore.GetName()), 200 ). 201 Return(metrics.NoopMetricsHandler).Times(2) 202 _, err := s.visibilityManager.ListOpenWorkflowExecutionsByType(context.Background(), request) 203 s.NoError(err) 204 205 // no remaining tokens 206 _, err = s.visibilityManager.ListOpenWorkflowExecutionsByType(context.Background(), request) 207 s.Equal(persistence.ErrPersistenceLimitExceeded, err) 208 } 209 210 func (s *VisibilityManagerSuite) TestListClosedWorkflowExecutionsByType() { 211 req := &manager.ListWorkflowExecutionsRequest{ 212 NamespaceID: testNamespaceUUID, 213 Namespace: testNamespace, 214 } 215 request := &manager.ListWorkflowExecutionsByTypeRequest{ 216 ListWorkflowExecutionsRequest: req, 217 WorkflowTypeName: testWorkflowTypeName, 218 } 219 s.visibilityStore.EXPECT().ListClosedWorkflowExecutionsByType(gomock.Any(), gomock.Any()).Return(nil, nil) 220 s.metricsHandler.EXPECT(). 221 WithTags(metrics.OperationTag( 222 metrics.VisibilityPersistenceListClosedWorkflowExecutionsByTypeScope), 223 metrics.VisibilityPluginNameTag(s.visibilityStore.GetName()), 224 ). 225 Return(metrics.NoopMetricsHandler).Times(2) 226 _, err := s.visibilityManager.ListClosedWorkflowExecutionsByType(context.Background(), request) 227 s.NoError(err) 228 229 // no remaining tokens 230 _, err = s.visibilityManager.ListClosedWorkflowExecutionsByType(context.Background(), request) 231 s.Equal(persistence.ErrPersistenceLimitExceeded, err) 232 } 233 234 func (s *VisibilityManagerSuite) TestListOpenWorkflowExecutionsByWorkflowID() { 235 req := &manager.ListWorkflowExecutionsRequest{ 236 NamespaceID: testNamespaceUUID, 237 Namespace: testNamespace, 238 } 239 request := &manager.ListWorkflowExecutionsByWorkflowIDRequest{ 240 ListWorkflowExecutionsRequest: req, 241 WorkflowID: testWorkflowExecution.GetWorkflowId(), 242 } 243 s.visibilityStore.EXPECT().ListOpenWorkflowExecutionsByWorkflowID(gomock.Any(), gomock.Any()).Return(nil, nil) 244 s.metricsHandler.EXPECT(). 245 WithTags(metrics.OperationTag( 246 metrics.VisibilityPersistenceListOpenWorkflowExecutionsByWorkflowIDScope), 247 metrics.VisibilityPluginNameTag(s.visibilityStore.GetName()), 248 ). 249 Return(metrics.NoopMetricsHandler).Times(2) 250 _, err := s.visibilityManager.ListOpenWorkflowExecutionsByWorkflowID(context.Background(), request) 251 s.NoError(err) 252 253 // no remaining tokens 254 _, err = s.visibilityManager.ListOpenWorkflowExecutionsByWorkflowID(context.Background(), request) 255 s.Equal(persistence.ErrPersistenceLimitExceeded, err) 256 } 257 258 func (s *VisibilityManagerSuite) TestListClosedWorkflowExecutionsByWorkflowID() { 259 req := &manager.ListWorkflowExecutionsRequest{ 260 NamespaceID: testNamespaceUUID, 261 Namespace: testNamespace, 262 } 263 request := &manager.ListWorkflowExecutionsByWorkflowIDRequest{ 264 ListWorkflowExecutionsRequest: req, 265 WorkflowID: testWorkflowExecution.GetWorkflowId(), 266 } 267 s.visibilityStore.EXPECT().ListClosedWorkflowExecutionsByWorkflowID(gomock.Any(), gomock.Any()).Return(nil, nil) 268 s.metricsHandler.EXPECT(). 269 WithTags(metrics.OperationTag( 270 metrics.VisibilityPersistenceListClosedWorkflowExecutionsByWorkflowIDScope), 271 metrics.VisibilityPluginNameTag(s.visibilityStore.GetName()), 272 ). 273 Return(metrics.NoopMetricsHandler).Times(2) 274 _, err := s.visibilityManager.ListClosedWorkflowExecutionsByWorkflowID(context.Background(), request) 275 s.NoError(err) 276 277 // no remaining tokens 278 _, err = s.visibilityManager.ListClosedWorkflowExecutionsByWorkflowID(context.Background(), request) 279 s.Equal(persistence.ErrPersistenceLimitExceeded, err) 280 } 281 282 func (s *VisibilityManagerSuite) TestListClosedWorkflowExecutionsByStatus() { 283 req := &manager.ListWorkflowExecutionsRequest{ 284 NamespaceID: testNamespaceUUID, 285 Namespace: testNamespace, 286 } 287 request := &manager.ListClosedWorkflowExecutionsByStatusRequest{ 288 ListWorkflowExecutionsRequest: req, 289 Status: enumspb.WORKFLOW_EXECUTION_STATUS_FAILED, 290 } 291 s.visibilityStore.EXPECT().ListClosedWorkflowExecutionsByStatus(gomock.Any(), gomock.Any()).Return(nil, nil) 292 s.metricsHandler.EXPECT(). 293 WithTags( 294 metrics.OperationTag(metrics.VisibilityPersistenceListClosedWorkflowExecutionsByStatusScope), 295 metrics.VisibilityPluginNameTag(s.visibilityStore.GetName()), 296 ). 297 Return(metrics.NoopMetricsHandler).Times(2) 298 _, err := s.visibilityManager.ListClosedWorkflowExecutionsByStatus(context.Background(), request) 299 s.NoError(err) 300 301 // no remaining tokens 302 _, err = s.visibilityManager.ListClosedWorkflowExecutionsByStatus(context.Background(), request) 303 s.Equal(persistence.ErrPersistenceLimitExceeded, err) 304 } 305 306 func (s *VisibilityManagerSuite) TestGetWorkflowExecution() { 307 request := &manager.GetWorkflowExecutionRequest{ 308 NamespaceID: testNamespaceUUID, 309 Namespace: testNamespace, 310 RunID: testWorkflowExecution.RunId, 311 WorkflowID: testWorkflowExecution.WorkflowId, 312 CloseTime: time.Now(), 313 } 314 s.visibilityStore.EXPECT().GetWorkflowExecution(gomock.Any(), gomock.Any()).Return( 315 &store.InternalGetWorkflowExecutionResponse{}, 316 nil, 317 ) 318 s.metricsHandler.EXPECT(). 319 WithTags( 320 metrics.OperationTag(metrics.VisibilityPersistenceGetWorkflowExecutionScope), 321 metrics.VisibilityPluginNameTag(s.visibilityStore.GetName()), 322 ). 323 Return(metrics.NoopMetricsHandler).Times(2) 324 _, err := s.visibilityManager.GetWorkflowExecution(context.Background(), request) 325 s.NoError(err) 326 327 // no remaining tokens 328 _, err = s.visibilityManager.GetWorkflowExecution(context.Background(), request) 329 s.Equal(persistence.ErrPersistenceLimitExceeded, err) 330 }