diff --git a/common/persistence/execution_manager_test.go b/common/persistence/execution_manager_test.go index edf2c5d90c7..0595652a4cf 100644 --- a/common/persistence/execution_manager_test.go +++ b/common/persistence/execution_manager_test.go @@ -38,6 +38,23 @@ import ( "github.com/uber/cadence/common/types" ) +var ( + testIndex = "test-index" + testDomain = "test-domain" + testDomainID = "bfd5c907-f899-4baf-a7b2-2ab85e623ebd" + testPageSize = 10 + testEarliestTime = int64(1547596872371000000) + testLatestTime = int64(2547596872371000000) + testWorkflowType = "test-wf-type" + testWorkflowID = "test-wid" + testCloseStatus = int32(1) + testTableName = "test-table-name" + testRunID = "test-run-id" + testSearchAttributes1 = map[string]interface{}{"TestAttr1": "val1", "TestAttr2": 2, "TestAttr3": false} + testSearchAttributes2 = map[string]interface{}{"TestAttr1": "val2", "TestAttr2": 2, "TestAttr3": false} + testSearchAttributes3 = map[string]interface{}{"TestAttr2": 2, "TestAttr3": false} +) + func TestExecutionManager_ProxyStoreMethods(t *testing.T) { for _, tc := range []struct { method string diff --git a/common/persistence/pinotResponseComparator.go b/common/persistence/pinotResponseComparator.go deleted file mode 100644 index 506fcc63436..00000000000 --- a/common/persistence/pinotResponseComparator.go +++ /dev/null @@ -1,523 +0,0 @@ -// The MIT License (MIT) - -// Copyright (c) 2017-2020 Uber Technologies Inc. - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package persistence - -import ( - "bytes" - "context" - "fmt" - "reflect" - "strings" - - "github.com/uber/cadence/common/log" - "github.com/uber/cadence/common/log/tag" - "github.com/uber/cadence/common/types" -) - -func interfaceToMap(in interface{}) (map[string][]byte, error) { - if in == nil || in == "" { - return map[string][]byte{}, nil - } - - v, ok := in.(map[string][]byte) - if !ok { - return map[string][]byte{}, fmt.Errorf(fmt.Sprintf("interface to map error in ES/Pinot comparator: %#v", in)) - } - - return v, nil -} - -func compareSearchAttributes(esSearchAttribute interface{}, pinotSearchAttribute interface{}) error { - esAttr, ok := esSearchAttribute.(*types.SearchAttributes) - if !ok { - return fmt.Errorf("interface is not an ES SearchAttributes! ") - } - - pinotAttr, ok := pinotSearchAttribute.(*types.SearchAttributes) - if !ok { - return fmt.Errorf("interface is not a pinot SearchAttributes! ") - } - - esSearchAttributeList, err := interfaceToMap(esAttr.GetIndexedFields()) - if err != nil { - return err - } - pinotSearchAttributeList, err := interfaceToMap(pinotAttr.GetIndexedFields()) - if err != nil { - return err - } - - for key, esValue := range esSearchAttributeList { // length(esAttribute) <= length(pinotAttribute) - pinotValue := pinotSearchAttributeList[key] - if !bytes.Equal(esValue, pinotValue) { - return fmt.Errorf(fmt.Sprintf("Comparison Failed: response.%s are not equal. ES value = %s, Pinot value = %s", key, esValue, pinotValue)) - } - } - - return nil -} - -func compareExecutions(esInput interface{}, pinotInput interface{}) error { - esExecution, ok := esInput.(*types.WorkflowExecution) - if !ok { - return fmt.Errorf("interface is not an ES WorkflowExecution! ") - } - - pinotExecution, ok := pinotInput.(*types.WorkflowExecution) - if !ok { - return fmt.Errorf("interface is not a pinot WorkflowExecution! ") - } - - if esExecution.GetWorkflowID() != pinotExecution.GetWorkflowID() { - return fmt.Errorf(fmt.Sprintf("Comparison Failed: Execution.WorkflowID are not equal. ES value = %s, Pinot value = %s", esExecution.GetWorkflowID(), pinotExecution.GetWorkflowID())) - } - - if esExecution.GetRunID() != pinotExecution.GetRunID() { - return fmt.Errorf(fmt.Sprintf("Comparison Failed: Execution.RunID are not equal. ES value = %s, Pinot value = %s", esExecution.GetRunID(), pinotExecution.GetRunID())) - } - - return nil -} - -func compareType(esInput interface{}, pinotInput interface{}) error { - esType, ok := esInput.(*types.WorkflowType) - if !ok { - return fmt.Errorf("interface is not an ES WorkflowType! ") - } - - pinotType, ok := pinotInput.(*types.WorkflowType) - if !ok { - return fmt.Errorf("interface is not a pinot WorkflowType! ") - } - - if esType.GetName() != pinotType.GetName() { - return fmt.Errorf(fmt.Sprintf("Comparison Failed: WorkflowTypes are not equal. ES value = %s, Pinot value = %s", esType.GetName(), pinotType.GetName())) - } - - return nil -} - -func compareCloseStatus(esInput interface{}, pinotInput interface{}) error { - esStatus, ok := esInput.(*types.WorkflowExecutionCloseStatus) - if !ok { - return fmt.Errorf("interface is not an ES WorkflowExecutionCloseStatus! ") - } - - pinotStatus, ok := pinotInput.(*types.WorkflowExecutionCloseStatus) - if !ok { - return fmt.Errorf("interface is not a pinot WorkflowExecutionCloseStatus! ") - } - - if esStatus != pinotStatus { - return fmt.Errorf(fmt.Sprintf("Comparison Failed: WorkflowExecutionCloseStatus are not equal. ES value = %s, Pinot value = %s", esStatus, pinotStatus)) - } - - return nil -} - -func compareListWorkflowExecutionInfo( - esExecutionInfo *types.WorkflowExecutionInfo, - pinotExecutionInfo *types.WorkflowExecutionInfo, -) error { - vOfES := reflect.ValueOf(*esExecutionInfo) - typeOfesExecutionInfo := vOfES.Type() - vOfPinot := reflect.ValueOf(*pinotExecutionInfo) - - for i := 0; i < vOfES.NumField(); i++ { - esFieldName := typeOfesExecutionInfo.Field(i).Name - esValue := vOfES.Field(i).Interface() - pinotValue := vOfPinot.Field(i).Interface() - - // if the value in ES is nil, then we don't need to compare - if esValue == nil { - continue - } - - // if the value in ES is not nil but in pinot is nil, then there's an error - if pinotValue == nil { - return fmt.Errorf("Pinot result is nil while ES result is not. ") - } - - switch strings.ToLower(esFieldName) { - case "memo", "autoresetpoints", "partitionconfig": - - case "searchattributes": - err := compareSearchAttributes(esValue, pinotValue) - if err != nil { - return err - } - case "execution", "parentexecution": - err := compareExecutions(esValue, pinotValue) - if err != nil { - return err - } - case "type": - err := compareType(esValue, pinotValue) - if err != nil { - return err - } - case "closestatus": - err := compareCloseStatus(esValue, pinotValue) - if err != nil { - return err - } - default: - if esValue != pinotValue { - return fmt.Errorf(fmt.Sprintf("Comparison Failed: response.%s are not equal. ES value = %s, Pinot value = %s", esFieldName, esValue, pinotValue)) - } - } - } - - return nil -} - -func compareListWorkflowExecutions( - esExecutionInfos []*types.WorkflowExecutionInfo, - pinotExecutionInfos []*types.WorkflowExecutionInfo, -) error { - if esExecutionInfos == nil && pinotExecutionInfos == nil { - return nil - } - if esExecutionInfos == nil || pinotExecutionInfos == nil { - return fmt.Errorf(fmt.Sprintf("Comparison failed. One of the response is nil. ")) - } - if len(esExecutionInfos) != len(pinotExecutionInfos) { - return fmt.Errorf(fmt.Sprintf("Comparison failed. result length doesn't equal. ")) - } - - for i := 0; i < len(esExecutionInfos); i++ { - err := compareListWorkflowExecutionInfo(esExecutionInfos[i], pinotExecutionInfos[i]) - if err != nil { - return err - } - } - - return nil -} - -func comparePinotESListOpenResponse( - ctx context.Context, - ESManager VisibilityManager, - PinotManager VisibilityManager, - request *ListWorkflowExecutionsRequest, - logger log.Logger, -) (*ListWorkflowExecutionsResponse, error) { - esResponse, err1 := ESManager.ListOpenWorkflowExecutions(ctx, request) - pinotResponse, err2 := PinotManager.ListOpenWorkflowExecutions(ctx, request) - - if err1 != nil && err2 != nil { - return nil, fmt.Errorf("ListOpenWorkflowExecutions in comparator error, no available results") - } else if err1 != nil { - logger.Error(fmt.Sprintf("ListOpenWorkflowExecutions in comparator error, ES: %s", err1)) - return pinotResponse, nil - } else if err2 != nil { - logger.Error(fmt.Sprintf("ListOpenWorkflowExecutions in comparator error, Pinot: %s", err2)) - return esResponse, nil - } - - err := compareListWorkflowExecutions(esResponse.Executions, pinotResponse.Executions) - if err != nil { - logger.Error("ES/Pinot Response comparison Error! ", tag.Error(err)) - return esResponse, nil - } - return esResponse, nil -} - -func comparePinotESListClosedResponse( - ctx context.Context, - ESManager VisibilityManager, - PinotManager VisibilityManager, - request *ListWorkflowExecutionsRequest, - logger log.Logger, -) (*ListWorkflowExecutionsResponse, error) { - esResponse, err1 := ESManager.ListClosedWorkflowExecutions(ctx, request) - pinotResponse, err2 := PinotManager.ListClosedWorkflowExecutions(ctx, request) - - if err1 != nil && err2 != nil { - return nil, fmt.Errorf("ListClosedWorkflowExecutions in comparator error, no available results") - } else if err1 != nil { - logger.Error(fmt.Sprintf("ListClosedWorkflowExecutions in comparator error, ES: %s", err1)) - return pinotResponse, nil - } else if err2 != nil { - logger.Error(fmt.Sprintf("ListClosedWorkflowExecutions in comparator error, Pinot: %s", err2)) - return esResponse, nil - } - - err := compareListWorkflowExecutions(esResponse.Executions, pinotResponse.Executions) - if err != nil { - logger.Error("ES/Pinot Response comparison Error! ", tag.Error(err)) - return esResponse, nil - } - return esResponse, nil -} - -func comparePinotESListOpenByTypeResponse( - ctx context.Context, - ESManager VisibilityManager, - PinotManager VisibilityManager, - request *ListWorkflowExecutionsByTypeRequest, - logger log.Logger, -) (*ListWorkflowExecutionsResponse, error) { - esResponse, err1 := ESManager.ListOpenWorkflowExecutionsByType(ctx, request) - pinotResponse, err2 := PinotManager.ListOpenWorkflowExecutionsByType(ctx, request) - - if err1 != nil && err2 != nil { - return nil, fmt.Errorf("ListOpenWorkflowExecutionsByType in comparator error, no available results") - } else if err1 != nil { - logger.Error(fmt.Sprintf("ListOpenWorkflowExecutionsByType in comparator error, ES: %s", err1)) - return pinotResponse, nil - } else if err2 != nil { - logger.Error(fmt.Sprintf("ListOpenWorkflowExecutionsByType in comparator error, Pinot: %s", err2)) - return esResponse, nil - } - - err := compareListWorkflowExecutions(esResponse.Executions, pinotResponse.Executions) - if err != nil { - logger.Error("ES/Pinot Response comparison Error! ", tag.Error(err)) - return esResponse, nil - } - return esResponse, nil -} - -func comparePinotESListClosedByTypeResponse( - ctx context.Context, - ESManager VisibilityManager, - PinotManager VisibilityManager, - request *ListWorkflowExecutionsByTypeRequest, - logger log.Logger, -) (*ListWorkflowExecutionsResponse, error) { - esResponse, err1 := ESManager.ListClosedWorkflowExecutionsByType(ctx, request) - pinotResponse, err2 := PinotManager.ListClosedWorkflowExecutionsByType(ctx, request) - - if err1 != nil && err2 != nil { - return nil, fmt.Errorf("ListClosedWorkflowExecutionsByType in comparator error, no available results") - } else if err1 != nil { - logger.Error(fmt.Sprintf("ListClosedWorkflowExecutionsByType in comparator error, ES: %s", err1)) - return pinotResponse, nil - } else if err2 != nil { - logger.Error(fmt.Sprintf("ListClosedWorkflowExecutionsByType in comparator error, Pinot: %s", err2)) - return esResponse, nil - } - - err := compareListWorkflowExecutions(esResponse.Executions, pinotResponse.Executions) - if err != nil { - logger.Error("ES/Pinot Response comparison Error! ", tag.Error(err)) - return esResponse, nil - } - return esResponse, nil -} - -func comparePinotESListOpenByWorkflowIDResponse( - ctx context.Context, - ESManager VisibilityManager, - PinotManager VisibilityManager, - request *ListWorkflowExecutionsByWorkflowIDRequest, - logger log.Logger, -) (*ListWorkflowExecutionsResponse, error) { - esResponse, err1 := ESManager.ListOpenWorkflowExecutionsByWorkflowID(ctx, request) - pinotResponse, err2 := PinotManager.ListOpenWorkflowExecutionsByWorkflowID(ctx, request) - - if err1 != nil && err2 != nil { - return nil, fmt.Errorf("ListOpenWorkflowExecutionsByWorkflowID in comparator error, no available results") - } else if err1 != nil { - logger.Error(fmt.Sprintf("ListOpenWorkflowExecutionsByWorkflowID in comparator error, ES: %s", err1)) - return pinotResponse, nil - } else if err2 != nil { - logger.Error(fmt.Sprintf("ListOpenWorkflowExecutionsByWorkflowID in comparator error, Pinot: %s", err2)) - return esResponse, nil - } - - err := compareListWorkflowExecutions(esResponse.Executions, pinotResponse.Executions) - if err != nil { - logger.Error("ES/Pinot Response comparison Error! ", tag.Error(err)) - return esResponse, nil - } - return esResponse, nil -} - -func comparePinotESListClosedByWorkflowIDResponse( - ctx context.Context, - ESManager VisibilityManager, - PinotManager VisibilityManager, - request *ListWorkflowExecutionsByWorkflowIDRequest, - logger log.Logger, -) (*ListWorkflowExecutionsResponse, error) { - esResponse, err1 := ESManager.ListClosedWorkflowExecutionsByWorkflowID(ctx, request) - pinotResponse, err2 := PinotManager.ListClosedWorkflowExecutionsByWorkflowID(ctx, request) - - if err1 != nil && err2 != nil { - return nil, fmt.Errorf("ListClosedWorkflowExecutionsByWorkflowID in comparator error, no available results") - } else if err1 != nil { - logger.Error(fmt.Sprintf("ListClosedWorkflowExecutionsByWorkflowID in comparator error, ES: %s", err1)) - return pinotResponse, nil - } else if err2 != nil { - logger.Error(fmt.Sprintf("ListClosedWorkflowExecutionsByWorkflowID in comparator error, Pinot: %s", err2)) - return esResponse, nil - } - err := compareListWorkflowExecutions(esResponse.Executions, pinotResponse.Executions) - if err != nil { - logger.Error("ES/Pinot Response comparison Error! ", tag.Error(err)) - } - return esResponse, nil -} - -func comparePinotESListClosedByStatusResponse( - ctx context.Context, - ESManager VisibilityManager, - PinotManager VisibilityManager, - request *ListClosedWorkflowExecutionsByStatusRequest, - logger log.Logger, -) (*ListWorkflowExecutionsResponse, error) { - esResponse, err1 := ESManager.ListClosedWorkflowExecutionsByStatus(ctx, request) - pinotResponse, err2 := PinotManager.ListClosedWorkflowExecutionsByStatus(ctx, request) - - if err1 != nil && err2 != nil { - return nil, fmt.Errorf("ListClosedWorkflowExecutionsByStatus in comparator error, no available results") - } else if err1 != nil { - logger.Error(fmt.Sprintf("ListClosedWorkflowExecutionsByStatus in comparator error, ES: %s", err1)) - return pinotResponse, nil - } else if err2 != nil { - logger.Error(fmt.Sprintf("ListClosedWorkflowExecutionsByStatus in comparator error, Pinot: %s", err2)) - return esResponse, nil - } - - err := compareListWorkflowExecutions(esResponse.Executions, pinotResponse.Executions) - if err != nil { - logger.Error("ES/Pinot Response comparison Error! ", tag.Error(err)) - return esResponse, nil - } - return esResponse, nil -} - -func comparePinotESGetClosedByStatusResponse( - ctx context.Context, - ESManager VisibilityManager, - PinotManager VisibilityManager, - request *GetClosedWorkflowExecutionRequest, - logger log.Logger, -) (*GetClosedWorkflowExecutionResponse, error) { - esResponse, err1 := ESManager.GetClosedWorkflowExecution(ctx, request) - pinotResponse, err2 := PinotManager.GetClosedWorkflowExecution(ctx, request) - - if err1 != nil && err2 != nil { - return nil, fmt.Errorf("GetClosedWorkflowExecutions in comparator error, no available results") - } else if err1 != nil { - logger.Error(fmt.Sprintf("GetClosedWorkflowExecutions in comparator error, ES: %s", err1)) - return pinotResponse, nil - } else if err2 != nil { - logger.Error(fmt.Sprintf("GetClosedWorkflowExecutions in comparator error, Pinot: %s", err2)) - return esResponse, nil - } - - err := compareListWorkflowExecutionInfo(esResponse.Execution, pinotResponse.Execution) - if err != nil { - logger.Error("ES/Pinot Response comparison Error! ", tag.Error(err)) - return esResponse, nil - } - return esResponse, nil -} - -func comparePinotESListByQueryResponse( - ctx context.Context, - ESManager VisibilityManager, - PinotManager VisibilityManager, - request *ListWorkflowExecutionsByQueryRequest, - logger log.Logger, -) (*ListWorkflowExecutionsResponse, error) { - esResponse, err1 := ESManager.ListWorkflowExecutions(ctx, request) - pinotResponse, err2 := PinotManager.ListWorkflowExecutions(ctx, request) - - if err1 != nil && err2 != nil { - return nil, fmt.Errorf("ListOpenWorkflowExecutionsByQuery in comparator error, no available results") - } else if err1 != nil { - logger.Error(fmt.Sprintf("ListOpenWorkflowExecutionsByQuery in comparator error, ES: %s", err1)) - return pinotResponse, nil - } else if err2 != nil { - logger.Error(fmt.Sprintf("ListOpenWorkflowExecutionsByQuery in comparator error, Pinot: %s", err2)) - return esResponse, nil - } - - err := compareListWorkflowExecutions(esResponse.Executions, pinotResponse.Executions) - if err != nil { - logger.Error("ES/Pinot Response comparison Error! ", tag.Error(err)) - return esResponse, nil - } - return esResponse, nil -} - -func comparePinotESScanResponse( - ctx context.Context, - ESManager VisibilityManager, - PinotManager VisibilityManager, - request *ListWorkflowExecutionsByQueryRequest, - logger log.Logger, -) (*ListWorkflowExecutionsResponse, error) { - esResponse, err1 := ESManager.ScanWorkflowExecutions(ctx, request) - pinotResponse, err2 := PinotManager.ScanWorkflowExecutions(ctx, request) - - if err1 != nil && err2 != nil { - return nil, fmt.Errorf("ScanWorkflowExecutions in comparator error, no available results") - } else if err1 != nil { - logger.Error(fmt.Sprintf("ScanWorkflowExecutions in comparator error, ES: %s", err1)) - return pinotResponse, nil - } else if err2 != nil { - logger.Error(fmt.Sprintf("ScanWorkflowExecutions in comparator error, Pinot: %s", err2)) - return esResponse, nil - } - - err := compareListWorkflowExecutions(esResponse.Executions, pinotResponse.Executions) - if err != nil { - logger.Error("ES/Pinot Response comparison Error! ", tag.Error(err)) - return esResponse, nil - } - return esResponse, nil -} - -func comparePinotESCountResponse( - ctx context.Context, - ESManager VisibilityManager, - PinotManager VisibilityManager, - request *CountWorkflowExecutionsRequest, - logger log.Logger, -) (*CountWorkflowExecutionsResponse, error) { - esResponse, err1 := ESManager.CountWorkflowExecutions(ctx, request) - pinotResponse, err2 := PinotManager.CountWorkflowExecutions(ctx, request) - - if err1 != nil && err2 != nil { - return nil, fmt.Errorf("CountOpenWorkflowExecutions in comparator error, no available results") - } else if err1 != nil { - logger.Error(fmt.Sprintf("CountOpenWorkflowExecutions in comparator error, ES: %s", err1)) - return pinotResponse, nil - } else if err2 != nil { - logger.Error(fmt.Sprintf("CountOpenWorkflowExecutions in comparator error, Pinot: %s", err2)) - return esResponse, nil - } - - if esResponse.Count != pinotResponse.Count { - err := fmt.Errorf(fmt.Sprintf("Comparison Failed: counts are not equal. ES value = %v, Pinot value = %v", esResponse.Count, pinotResponse.Count)) - logger.Error("ES/Pinot Response comparison Error! ", tag.Error(err)) - return esResponse, nil - } - - return esResponse, nil -} diff --git a/common/persistence/pinotResponseComparator_test.go b/common/persistence/pinotResponseComparator_test.go deleted file mode 100644 index a7e5e5df021..00000000000 --- a/common/persistence/pinotResponseComparator_test.go +++ /dev/null @@ -1,541 +0,0 @@ -// The MIT License (MIT) - -// Copyright (c) 2017-2020 Uber Technologies Inc. - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package persistence - -import ( - "encoding/json" - "fmt" - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/uber/cadence/common/types" -) - -var ( - testIndex = "test-index" - testDomain = "test-domain" - testDomainID = "bfd5c907-f899-4baf-a7b2-2ab85e623ebd" - testPageSize = 10 - testEarliestTime = int64(1547596872371000000) - testLatestTime = int64(2547596872371000000) - testWorkflowType = "test-wf-type" - testWorkflowID = "test-wid" - testCloseStatus = int32(1) - testTableName = "test-table-name" - testRunID = "test-run-id" - testSearchAttributes1 = map[string]interface{}{"TestAttr1": "val1", "TestAttr2": 2, "TestAttr3": false} - testSearchAttributes2 = map[string]interface{}{"TestAttr1": "val2", "TestAttr2": 2, "TestAttr3": false} - testSearchAttributes3 = map[string]interface{}{"TestAttr2": 2, "TestAttr3": false} -) - -func TestInterfaceToMap(t *testing.T) { - tests := map[string]struct { - input interface{} - expectedResult map[string][]byte - expectedError error - }{ - "Case1: nil input case": { - input: nil, - expectedResult: map[string][]byte{}, - expectedError: nil, - }, - "Case2: empty input case": { - input: "", - expectedResult: map[string][]byte{}, - expectedError: nil, - }, - "Case3: normal input case": { - input: transferMap(testSearchAttributes1), - expectedResult: transferMap(testSearchAttributes1), - expectedError: nil, - }, - "Case4: error input case": { - input: 0, - expectedResult: map[string][]byte{}, - expectedError: fmt.Errorf("interface to map error in ES/Pinot comparator: 0"), - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - assert.NotPanics(t, func() { - actualResult, actualError := interfaceToMap(test.input) - assert.Equal(t, test.expectedResult, actualResult) - assert.Equal(t, test.expectedError, actualError) - }) - }) - } -} - -func TestCompareSearchAttributes(t *testing.T) { - tests := map[string]struct { - pinotInput interface{} - esInput interface{} - expectedResult error - }{ - "Case1: pass case": { - pinotInput: &types.SearchAttributes{IndexedFields: transferMap(testSearchAttributes1)}, - esInput: &types.SearchAttributes{IndexedFields: transferMap(testSearchAttributes1)}, - expectedResult: nil, - }, - "Case2: error case": { - pinotInput: &types.SearchAttributes{IndexedFields: transferMap(testSearchAttributes1)}, - esInput: &types.SearchAttributes{IndexedFields: transferMap(testSearchAttributes2)}, - expectedResult: fmt.Errorf(fmt.Sprintf("Comparison Failed: response.%s are not equal. ES value = \"%s\", Pinot value = \"%s\"", "TestAttr1", "val2", "val1")), - }, - "Case3: pass case with different response": { - pinotInput: &types.SearchAttributes{IndexedFields: transferMap(testSearchAttributes1)}, - esInput: &types.SearchAttributes{IndexedFields: transferMap(testSearchAttributes3)}, - expectedResult: nil, - }, - "Case4: error case with different response": { - pinotInput: &types.SearchAttributes{IndexedFields: transferMap(testSearchAttributes3)}, - esInput: &types.SearchAttributes{IndexedFields: transferMap(testSearchAttributes2)}, - expectedResult: fmt.Errorf(fmt.Sprintf("Comparison Failed: response.%s are not equal. ES value = \"%s\", Pinot value = %s", "TestAttr1", "val2", "")), - }, - "Case5: error input case1": { - pinotInput: 0, - esInput: &types.SearchAttributes{IndexedFields: transferMap(testSearchAttributes2)}, - expectedResult: fmt.Errorf(fmt.Sprintf("interface is not a pinot SearchAttributes! ")), - }, - "Case6: error input case2": { - pinotInput: &types.SearchAttributes{IndexedFields: transferMap(testSearchAttributes2)}, - esInput: 0, - expectedResult: fmt.Errorf(fmt.Sprintf("interface is not an ES SearchAttributes! ")), - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - assert.NotPanics(t, func() { - actualResult := compareSearchAttributes(test.esInput, test.pinotInput) - assert.Equal(t, test.expectedResult, actualResult) - }) - }) - } -} - -func TestCompareExecutions(t *testing.T) { - tests := map[string]struct { - pinotInput interface{} - esInput interface{} - expectedResult error - }{ - "Case1: pass case": { - pinotInput: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - esInput: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, expectedResult: nil, - }, - "Case2: error case": { - pinotInput: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: "testRunID", - }, - esInput: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, expectedResult: fmt.Errorf(fmt.Sprintf("Comparison Failed: Execution.RunID are not equal. ES value = test-run-id, Pinot value = testRunID")), - }, - "Case3: error input case1": { - pinotInput: 0, - esInput: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: "testRunID", - }, - expectedResult: fmt.Errorf(fmt.Sprintf("interface is not a pinot WorkflowExecution! ")), - }, - "Case4: error input case2": { - pinotInput: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: "testRunID", - }, - esInput: 0, - expectedResult: fmt.Errorf(fmt.Sprintf("interface is not an ES WorkflowExecution! ")), - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - assert.NotPanics(t, func() { - actualResult := compareExecutions(test.esInput, test.pinotInput) - assert.Equal(t, test.expectedResult, actualResult) - }) - }) - } -} - -func TestCompareType(t *testing.T) { - tests := map[string]struct { - pinotInput interface{} - esInput interface{} - expectedResult error - }{ - "Case1: pass case": { - pinotInput: &types.WorkflowType{Name: testWorkflowType}, - esInput: &types.WorkflowType{Name: testWorkflowType}, - expectedResult: nil, - }, - "Case2: error case": { - pinotInput: &types.WorkflowType{Name: "testWorkflowType"}, - esInput: &types.WorkflowType{Name: testWorkflowType}, - expectedResult: fmt.Errorf("Comparison Failed: WorkflowTypes are not equal. ES value = test-wf-type, Pinot value = testWorkflowType"), - }, - "Case3: error input case1": { - pinotInput: 0, - esInput: &types.WorkflowType{Name: testWorkflowType}, - expectedResult: fmt.Errorf(fmt.Sprintf("interface is not a pinot WorkflowType! ")), - }, - "Case4: error input case2": { - pinotInput: &types.WorkflowType{Name: testWorkflowType}, - esInput: 0, - expectedResult: fmt.Errorf(fmt.Sprintf("interface is not an ES WorkflowType! ")), - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - assert.NotPanics(t, func() { - actualResult := compareType(test.esInput, test.pinotInput) - assert.Equal(t, test.expectedResult, actualResult) - }) - }) - } -} - -func TestCompareCloseStatus(t *testing.T) { - testVal1 := types.WorkflowExecutionCloseStatus(0) - testVal2 := types.WorkflowExecutionCloseStatus(1) - - tests := map[string]struct { - pinotInput interface{} - esInput interface{} - expectedResult error - }{ - "Case1: pass case": { - pinotInput: &testVal1, - esInput: &testVal1, - expectedResult: nil, - }, - "Case2: error case": { - pinotInput: &testVal1, - esInput: &testVal2, - expectedResult: fmt.Errorf("Comparison Failed: WorkflowExecutionCloseStatus are not equal. ES value = FAILED, Pinot value = COMPLETED"), - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - assert.NotPanics(t, func() { - actualResult := compareCloseStatus(test.esInput, test.pinotInput) - assert.Equal(t, test.expectedResult, actualResult) - }) - }) - } -} - -func TestCompareListWorkflowExecutionInfo(t *testing.T) { - testSearchAttributeMap1 := transferMap(testSearchAttributes1) - testSearchAttributeMap2 := transferMap(testSearchAttributes2) - - tests := map[string]struct { - esInfo *types.WorkflowExecutionInfo - pinotInfo *types.WorkflowExecutionInfo - expectedResult error - }{ - "Case1: pass case": { - esInfo: &types.WorkflowExecutionInfo{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: nil, - }, - pinotInfo: &types.WorkflowExecutionInfo{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: nil, - }, - expectedResult: nil, - }, - "Case2: pass case with search attributes": { - esInfo: &types.WorkflowExecutionInfo{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap1}, - }, - pinotInfo: &types.WorkflowExecutionInfo{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap1}, - }, - expectedResult: nil, - }, - "Case3: error case with wrong type": { - esInfo: &types.WorkflowExecutionInfo{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: "testWorkflowType"}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap1}, - }, - pinotInfo: &types.WorkflowExecutionInfo{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap1}, - }, - expectedResult: fmt.Errorf("Comparison Failed: WorkflowTypes are not equal. ES value = testWorkflowType, Pinot value = test-wf-type"), - }, - "Case4: error case with wrong workflowID": { - esInfo: &types.WorkflowExecutionInfo{ - Execution: &types.WorkflowExecution{ - WorkflowID: "testWorkflowID", - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap1}, - }, - pinotInfo: &types.WorkflowExecutionInfo{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap1}, - }, - expectedResult: fmt.Errorf("Comparison Failed: Execution.WorkflowID are not equal. ES value = testWorkflowID, Pinot value = test-wid"), - }, - "Case5: error case with wrong runID": { - esInfo: &types.WorkflowExecutionInfo{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: "testRunID", - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap1}, - }, - pinotInfo: &types.WorkflowExecutionInfo{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap1}, - }, - expectedResult: fmt.Errorf("Comparison Failed: Execution.RunID are not equal. ES value = testRunID, Pinot value = test-run-id"), - }, - "Case6: error case with wrong SearchAttributes": { - esInfo: &types.WorkflowExecutionInfo{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap1}, - }, - pinotInfo: &types.WorkflowExecutionInfo{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap2}, - }, - expectedResult: fmt.Errorf("Comparison Failed: response.TestAttr1 are not equal. ES value = \"val1\", Pinot value = \"val2\""), - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - assert.NotPanics(t, func() { - actualResult := compareListWorkflowExecutionInfo(test.esInfo, test.pinotInfo) - assert.Equal(t, test.expectedResult, actualResult) - }) - }) - } -} - -func TestCompareListWorkflowExecutions(t *testing.T) { - testSearchAttributeMap1 := transferMap(testSearchAttributes1) - - tests := map[string]struct { - esInfo []*types.WorkflowExecutionInfo - pinotInfo []*types.WorkflowExecutionInfo - expectedResult error - }{ - "Case1: pass case": { - esInfo: []*types.WorkflowExecutionInfo{{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - }, - { - Execution: &types.WorkflowExecution{ - WorkflowID: "testWorkflowID", - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap1}, - }}, - pinotInfo: []*types.WorkflowExecutionInfo{{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - }, - { - Execution: &types.WorkflowExecution{ - WorkflowID: "testWorkflowID", - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap1}, - }}, - expectedResult: nil, - }, - "Case2: nil case": { - esInfo: nil, - pinotInfo: nil, - expectedResult: nil, - }, - "Case3: one nil case": { - esInfo: []*types.WorkflowExecutionInfo{{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap1}, - }}, - pinotInfo: nil, - expectedResult: fmt.Errorf("Comparison failed. One of the response is nil. "), - }, - "Case4: length not equal case": { - esInfo: []*types.WorkflowExecutionInfo{{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap1}, - }, - { - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap1}, - }}, - pinotInfo: []*types.WorkflowExecutionInfo{{ - Execution: &types.WorkflowExecution{ - WorkflowID: testWorkflowID, - RunID: testRunID, - }, - Type: &types.WorkflowType{Name: testWorkflowType}, - StartTime: &testEarliestTime, - CloseTime: &testLatestTime, - SearchAttributes: &types.SearchAttributes{IndexedFields: testSearchAttributeMap1}, - }}, - expectedResult: fmt.Errorf("Comparison failed. result length doesn't equal. "), - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - assert.NotPanics(t, func() { - actualResult := compareListWorkflowExecutions(test.esInfo, test.pinotInfo) - assert.Equal(t, test.expectedResult, actualResult) - }) - }) - } -} - -func transferMap(input map[string]interface{}) map[string][]byte { - res := make(map[string][]byte) - for key := range input { - marshalVal, _ := json.Marshal(input[key]) - res[key] = marshalVal - } - return res -} diff --git a/common/persistence/pinot_visibility_triple_manager_test.go b/common/persistence/pinot_visibility_triple_manager_test.go index b7b6b2e3c28..3b13c5ae5af 100644 --- a/common/persistence/pinot_visibility_triple_manager_test.go +++ b/common/persistence/pinot_visibility_triple_manager_test.go @@ -889,3 +889,801 @@ func TestFilterAttrPrefix(t *testing.T) { }) } } + +func TestPinotTripleListOpenWorkflowExecutions(t *testing.T) { + request := &ListWorkflowExecutionsRequest{ + Domain: "test-domain", + } + + // put this outside because need to use it as an input of the table tests + ctrl := gomock.NewController(t) + + tests := map[string]struct { + request *ListWorkflowExecutionsRequest + mockDBVisibilityManager VisibilityManager + mockESVisibilityManager VisibilityManager + mockPinotVisibilityManager VisibilityManager + mockDBVisibilityManagerAccordance func(mockDBVisibilityManager *MockVisibilityManager) + mockPinotVisibilityManagerAccordance func(mockPinotVisibilityManager *MockVisibilityManager) + mockESVisibilityManagerAccordance func(mockESVisibilityManager *MockVisibilityManager) + readModeIsFromES dynamicconfig.BoolPropertyFnWithDomainFilter + readModeIsFromPinot dynamicconfig.BoolPropertyFnWithDomainFilter + expectedError error + }{ + "Case1-1: success case with DB visibility is not nil": { + request: request, + mockDBVisibilityManager: NewMockVisibilityManager(ctrl), + mockDBVisibilityManagerAccordance: func(mockDBVisibilityManager *MockVisibilityManager) { + mockDBVisibilityManager.EXPECT().ListOpenWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + "Case1-2: success case with Pinot visibility is not nil": { + request: request, + mockPinotVisibilityManager: NewMockVisibilityManager(ctrl), + mockPinotVisibilityManagerAccordance: func(mockPinotVisibilityManager *MockVisibilityManager) { + mockPinotVisibilityManager.EXPECT().ListOpenWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + readModeIsFromPinot: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + if test.mockDBVisibilityManager != nil { + test.mockDBVisibilityManagerAccordance(test.mockDBVisibilityManager.(*MockVisibilityManager)) + } + if test.mockPinotVisibilityManager != nil { + test.mockPinotVisibilityManagerAccordance(test.mockPinotVisibilityManager.(*MockVisibilityManager)) + } + if test.mockESVisibilityManager != nil { + test.mockESVisibilityManagerAccordance(test.mockESVisibilityManager.(*MockVisibilityManager)) + } + + visibilityManager := NewPinotVisibilityTripleManager(test.mockDBVisibilityManager, test.mockPinotVisibilityManager, + test.mockESVisibilityManager, test.readModeIsFromPinot, test.readModeIsFromES, + nil, dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), log.NewNoop()) + + _, err := visibilityManager.ListOpenWorkflowExecutions(context.Background(), test.request) + if test.expectedError != nil { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestPinotTripleListClosedWorkflowExecutions(t *testing.T) { + request := &ListWorkflowExecutionsRequest{ + Domain: "test-domain", + } + + // put this outside because need to use it as an input of the table tests + ctrl := gomock.NewController(t) + + tests := map[string]struct { + context context.Context + request *ListWorkflowExecutionsRequest + mockDBVisibilityManager VisibilityManager + mockESVisibilityManager VisibilityManager + mockPinotVisibilityManager VisibilityManager + mockDBVisibilityManagerAccordance func(mockDBVisibilityManager *MockVisibilityManager) + mockPinotVisibilityManagerAccordance func(mockPinotVisibilityManager *MockVisibilityManager) + mockESVisibilityManagerAccordance func(mockESVisibilityManager *MockVisibilityManager) + readModeIsFromES dynamicconfig.BoolPropertyFnWithDomainFilter + readModeIsFromPinot dynamicconfig.BoolPropertyFnWithDomainFilter + expectedError error + }{ + "Case1-1: success case with DB visibility is not nil": { + context: context.Background(), + request: request, + mockDBVisibilityManager: NewMockVisibilityManager(ctrl), + mockDBVisibilityManagerAccordance: func(mockDBVisibilityManager *MockVisibilityManager) { + mockDBVisibilityManager.EXPECT().ListClosedWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + "Case1-2: success case with Pinot visibility is not nil": { + context: context.Background(), + request: request, + mockPinotVisibilityManager: NewMockVisibilityManager(ctrl), + mockPinotVisibilityManagerAccordance: func(mockPinotVisibilityManager *MockVisibilityManager) { + mockPinotVisibilityManager.EXPECT().ListClosedWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + readModeIsFromPinot: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + "Case1-3: success case with ES visibility is not nil": { + context: context.Background(), + request: request, + mockESVisibilityManager: NewMockVisibilityManager(ctrl), + mockESVisibilityManagerAccordance: func(mockESVisibilityManager *MockVisibilityManager) { + mockESVisibilityManager.EXPECT().ListClosedWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + readModeIsFromPinot: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + expectedError: nil, + }, + "Case2-1: success case with DB visibility is not nil and read Pinot is true": { + context: context.Background(), + request: request, + mockDBVisibilityManager: NewMockVisibilityManager(ctrl), + mockDBVisibilityManagerAccordance: func(mockDBVisibilityManager *MockVisibilityManager) { + mockDBVisibilityManager.EXPECT().ListClosedWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + readModeIsFromPinot: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + "Case2-2: success case with Pinot visibility is not nil and read mod is false": { + context: context.Background(), + request: request, + mockPinotVisibilityManager: NewMockVisibilityManager(ctrl), + mockPinotVisibilityManagerAccordance: func(mockPinotVisibilityManager *MockVisibilityManager) { + mockPinotVisibilityManager.EXPECT().ListClosedWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + readModeIsFromPinot: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + expectedError: nil, + }, + "Case2-3: success case with DB visibility is not nil and read modes are false": { + context: context.Background(), + request: request, + mockDBVisibilityManager: NewMockVisibilityManager(ctrl), + mockDBVisibilityManagerAccordance: func(mockDBVisibilityManager *MockVisibilityManager) { + mockDBVisibilityManager.EXPECT().ListClosedWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + readModeIsFromPinot: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + expectedError: nil, + }, + "Case3-1: read from ES with context key": { + context: context.WithValue(context.Background(), ContextKey, VisibilityOverridePrimary), + request: request, + mockESVisibilityManager: NewMockVisibilityManager(ctrl), + mockESVisibilityManagerAccordance: func(mockESVisibilityManager *MockVisibilityManager) { + mockESVisibilityManager.EXPECT().ListClosedWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + }, + "Case3-2: read from Pinot with context key": { + context: context.WithValue(context.Background(), ContextKey, VisibilityOverrideSecondary), + request: request, + mockPinotVisibilityManager: NewMockVisibilityManager(ctrl), + mockPinotVisibilityManagerAccordance: func(mockPinotVisibilityManager *MockVisibilityManager) { + mockPinotVisibilityManager.EXPECT().ListClosedWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + if test.mockDBVisibilityManager != nil { + test.mockDBVisibilityManagerAccordance(test.mockDBVisibilityManager.(*MockVisibilityManager)) + } + if test.mockPinotVisibilityManager != nil { + test.mockPinotVisibilityManagerAccordance(test.mockPinotVisibilityManager.(*MockVisibilityManager)) + } + if test.mockESVisibilityManager != nil { + test.mockESVisibilityManagerAccordance(test.mockESVisibilityManager.(*MockVisibilityManager)) + } + + visibilityManager := NewPinotVisibilityTripleManager(test.mockDBVisibilityManager, test.mockPinotVisibilityManager, + test.mockESVisibilityManager, test.readModeIsFromPinot, test.readModeIsFromES, + nil, dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), log.NewNoop()) + + _, err := visibilityManager.ListClosedWorkflowExecutions(test.context, test.request) + if test.expectedError != nil { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestPinotTripleListOpenWorkflowExecutionsByType(t *testing.T) { + request := &ListWorkflowExecutionsByTypeRequest{ + ListWorkflowExecutionsRequest: ListWorkflowExecutionsRequest{ + Domain: "test-domain", + }, + } + + // put this outside because need to use it as an input of the table tests + ctrl := gomock.NewController(t) + + tests := map[string]struct { + request *ListWorkflowExecutionsByTypeRequest + mockDBVisibilityManager VisibilityManager + mockESVisibilityManager VisibilityManager + mockPinotVisibilityManager VisibilityManager + mockDBVisibilityManagerAccordance func(mockDBVisibilityManager *MockVisibilityManager) + mockPinotVisibilityManagerAccordance func(mockPinotVisibilityManager *MockVisibilityManager) + mockESVisibilityManagerAccordance func(mockESVisibilityManager *MockVisibilityManager) + readModeIsFromES dynamicconfig.BoolPropertyFnWithDomainFilter + readModeIsFromPinot dynamicconfig.BoolPropertyFnWithDomainFilter + expectedError error + }{ + "Case1-1: success case with DB visibility is not nil": { + request: request, + mockDBVisibilityManager: NewMockVisibilityManager(ctrl), + mockDBVisibilityManagerAccordance: func(mockDBVisibilityManager *MockVisibilityManager) { + mockDBVisibilityManager.EXPECT().ListOpenWorkflowExecutionsByType(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + "Case1-2: success case with Pinot visibility is not nil": { + request: request, + mockPinotVisibilityManager: NewMockVisibilityManager(ctrl), + mockPinotVisibilityManagerAccordance: func(mockPinotVisibilityManager *MockVisibilityManager) { + mockPinotVisibilityManager.EXPECT().ListOpenWorkflowExecutionsByType(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + readModeIsFromPinot: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + if test.mockDBVisibilityManager != nil { + test.mockDBVisibilityManagerAccordance(test.mockDBVisibilityManager.(*MockVisibilityManager)) + } + if test.mockPinotVisibilityManager != nil { + test.mockPinotVisibilityManagerAccordance(test.mockPinotVisibilityManager.(*MockVisibilityManager)) + } + if test.mockESVisibilityManager != nil { + test.mockESVisibilityManagerAccordance(test.mockESVisibilityManager.(*MockVisibilityManager)) + } + + visibilityManager := NewPinotVisibilityTripleManager(test.mockDBVisibilityManager, test.mockPinotVisibilityManager, + test.mockESVisibilityManager, test.readModeIsFromPinot, test.readModeIsFromES, + nil, dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), log.NewNoop()) + + _, err := visibilityManager.ListOpenWorkflowExecutionsByType(context.Background(), test.request) + if test.expectedError != nil { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestPinotTripleListClosedWorkflowExecutionsByType(t *testing.T) { + request := &ListWorkflowExecutionsByTypeRequest{ + ListWorkflowExecutionsRequest: ListWorkflowExecutionsRequest{ + Domain: "test-domain", + }, + } + + // put this outside because need to use it as an input of the table tests + ctrl := gomock.NewController(t) + + tests := map[string]struct { + request *ListWorkflowExecutionsByTypeRequest + mockDBVisibilityManager VisibilityManager + mockESVisibilityManager VisibilityManager + mockPinotVisibilityManager VisibilityManager + mockDBVisibilityManagerAccordance func(mockDBVisibilityManager *MockVisibilityManager) + mockPinotVisibilityManagerAccordance func(mockPinotVisibilityManager *MockVisibilityManager) + mockESVisibilityManagerAccordance func(mockESVisibilityManager *MockVisibilityManager) + readModeIsFromES dynamicconfig.BoolPropertyFnWithDomainFilter + readModeIsFromPinot dynamicconfig.BoolPropertyFnWithDomainFilter + expectedError error + }{ + "Case1-1: success case with DB visibility is not nil": { + request: request, + mockDBVisibilityManager: NewMockVisibilityManager(ctrl), + mockDBVisibilityManagerAccordance: func(mockDBVisibilityManager *MockVisibilityManager) { + mockDBVisibilityManager.EXPECT().ListClosedWorkflowExecutionsByType(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + "Case1-2: success case with Pinot visibility is not nil": { + request: request, + mockPinotVisibilityManager: NewMockVisibilityManager(ctrl), + mockPinotVisibilityManagerAccordance: func(mockPinotVisibilityManager *MockVisibilityManager) { + mockPinotVisibilityManager.EXPECT().ListClosedWorkflowExecutionsByType(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + readModeIsFromPinot: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + if test.mockDBVisibilityManager != nil { + test.mockDBVisibilityManagerAccordance(test.mockDBVisibilityManager.(*MockVisibilityManager)) + } + if test.mockPinotVisibilityManager != nil { + test.mockPinotVisibilityManagerAccordance(test.mockPinotVisibilityManager.(*MockVisibilityManager)) + } + if test.mockESVisibilityManager != nil { + test.mockESVisibilityManagerAccordance(test.mockESVisibilityManager.(*MockVisibilityManager)) + } + + visibilityManager := NewPinotVisibilityTripleManager(test.mockDBVisibilityManager, test.mockPinotVisibilityManager, + test.mockESVisibilityManager, test.readModeIsFromPinot, test.readModeIsFromES, + nil, dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), log.NewNoop()) + + _, err := visibilityManager.ListClosedWorkflowExecutionsByType(context.Background(), test.request) + if test.expectedError != nil { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestPinotTripleListOpenWorkflowExecutionsByWorkflowID(t *testing.T) { + request := &ListWorkflowExecutionsByWorkflowIDRequest{ + ListWorkflowExecutionsRequest: ListWorkflowExecutionsRequest{ + Domain: "test-domain", + }, + } + + // put this outside because need to use it as an input of the table tests + ctrl := gomock.NewController(t) + + tests := map[string]struct { + request *ListWorkflowExecutionsByWorkflowIDRequest + mockDBVisibilityManager VisibilityManager + mockESVisibilityManager VisibilityManager + mockPinotVisibilityManager VisibilityManager + mockDBVisibilityManagerAccordance func(mockDBVisibilityManager *MockVisibilityManager) + mockPinotVisibilityManagerAccordance func(mockPinotVisibilityManager *MockVisibilityManager) + mockESVisibilityManagerAccordance func(mockESVisibilityManager *MockVisibilityManager) + readModeIsFromES dynamicconfig.BoolPropertyFnWithDomainFilter + readModeIsFromPinot dynamicconfig.BoolPropertyFnWithDomainFilter + expectedError error + }{ + "Case1-1: success case with DB visibility is not nil": { + request: request, + mockDBVisibilityManager: NewMockVisibilityManager(ctrl), + mockDBVisibilityManagerAccordance: func(mockDBVisibilityManager *MockVisibilityManager) { + mockDBVisibilityManager.EXPECT().ListOpenWorkflowExecutionsByWorkflowID(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + "Case1-2: success case with Pinot visibility is not nil": { + request: request, + mockPinotVisibilityManager: NewMockVisibilityManager(ctrl), + mockPinotVisibilityManagerAccordance: func(mockPinotVisibilityManager *MockVisibilityManager) { + mockPinotVisibilityManager.EXPECT().ListOpenWorkflowExecutionsByWorkflowID(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + readModeIsFromPinot: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + if test.mockDBVisibilityManager != nil { + test.mockDBVisibilityManagerAccordance(test.mockDBVisibilityManager.(*MockVisibilityManager)) + } + if test.mockPinotVisibilityManager != nil { + test.mockPinotVisibilityManagerAccordance(test.mockPinotVisibilityManager.(*MockVisibilityManager)) + } + if test.mockESVisibilityManager != nil { + test.mockESVisibilityManagerAccordance(test.mockESVisibilityManager.(*MockVisibilityManager)) + } + + visibilityManager := NewPinotVisibilityTripleManager(test.mockDBVisibilityManager, test.mockPinotVisibilityManager, + test.mockESVisibilityManager, test.readModeIsFromPinot, test.readModeIsFromES, + nil, dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), log.NewNoop()) + + _, err := visibilityManager.ListOpenWorkflowExecutionsByWorkflowID(context.Background(), test.request) + if test.expectedError != nil { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestPinotTripleListClosedWorkflowExecutionsByWorkflowID(t *testing.T) { + request := &ListWorkflowExecutionsByWorkflowIDRequest{ + ListWorkflowExecutionsRequest: ListWorkflowExecutionsRequest{ + Domain: "test-domain", + }, + } + + // put this outside because need to use it as an input of the table tests + ctrl := gomock.NewController(t) + + tests := map[string]struct { + request *ListWorkflowExecutionsByWorkflowIDRequest + mockDBVisibilityManager VisibilityManager + mockESVisibilityManager VisibilityManager + mockPinotVisibilityManager VisibilityManager + mockDBVisibilityManagerAccordance func(mockDBVisibilityManager *MockVisibilityManager) + mockPinotVisibilityManagerAccordance func(mockPinotVisibilityManager *MockVisibilityManager) + mockESVisibilityManagerAccordance func(mockESVisibilityManager *MockVisibilityManager) + readModeIsFromES dynamicconfig.BoolPropertyFnWithDomainFilter + readModeIsFromPinot dynamicconfig.BoolPropertyFnWithDomainFilter + expectedError error + }{ + "Case1-1: success case with DB visibility is not nil": { + request: request, + mockDBVisibilityManager: NewMockVisibilityManager(ctrl), + mockDBVisibilityManagerAccordance: func(mockDBVisibilityManager *MockVisibilityManager) { + mockDBVisibilityManager.EXPECT().ListClosedWorkflowExecutionsByWorkflowID(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + "Case1-2: success case with Pinot visibility is not nil": { + request: request, + mockPinotVisibilityManager: NewMockVisibilityManager(ctrl), + mockPinotVisibilityManagerAccordance: func(mockPinotVisibilityManager *MockVisibilityManager) { + mockPinotVisibilityManager.EXPECT().ListClosedWorkflowExecutionsByWorkflowID(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + readModeIsFromPinot: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + if test.mockDBVisibilityManager != nil { + test.mockDBVisibilityManagerAccordance(test.mockDBVisibilityManager.(*MockVisibilityManager)) + } + if test.mockPinotVisibilityManager != nil { + test.mockPinotVisibilityManagerAccordance(test.mockPinotVisibilityManager.(*MockVisibilityManager)) + } + if test.mockESVisibilityManager != nil { + test.mockESVisibilityManagerAccordance(test.mockESVisibilityManager.(*MockVisibilityManager)) + } + + visibilityManager := NewPinotVisibilityTripleManager(test.mockDBVisibilityManager, test.mockPinotVisibilityManager, + test.mockESVisibilityManager, test.readModeIsFromPinot, test.readModeIsFromES, + nil, dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), log.NewNoop()) + + _, err := visibilityManager.ListClosedWorkflowExecutionsByWorkflowID(context.Background(), test.request) + if test.expectedError != nil { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestPinotTripleListClosedWorkflowExecutionsByStatus(t *testing.T) { + request := &ListClosedWorkflowExecutionsByStatusRequest{ + ListWorkflowExecutionsRequest: ListWorkflowExecutionsRequest{ + Domain: "test-domain", + }, + } + + // put this outside because need to use it as an input of the table tests + ctrl := gomock.NewController(t) + + tests := map[string]struct { + request *ListClosedWorkflowExecutionsByStatusRequest + mockDBVisibilityManager VisibilityManager + mockESVisibilityManager VisibilityManager + mockPinotVisibilityManager VisibilityManager + mockDBVisibilityManagerAccordance func(mockDBVisibilityManager *MockVisibilityManager) + mockPinotVisibilityManagerAccordance func(mockPinotVisibilityManager *MockVisibilityManager) + mockESVisibilityManagerAccordance func(mockESVisibilityManager *MockVisibilityManager) + readModeIsFromES dynamicconfig.BoolPropertyFnWithDomainFilter + readModeIsFromPinot dynamicconfig.BoolPropertyFnWithDomainFilter + expectedError error + }{ + "Case1-1: success case with DB visibility is not nil": { + request: request, + mockDBVisibilityManager: NewMockVisibilityManager(ctrl), + mockDBVisibilityManagerAccordance: func(mockDBVisibilityManager *MockVisibilityManager) { + mockDBVisibilityManager.EXPECT().ListClosedWorkflowExecutionsByStatus(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + "Case1-2: success case with Pinot visibility is not nil": { + request: request, + mockPinotVisibilityManager: NewMockVisibilityManager(ctrl), + mockPinotVisibilityManagerAccordance: func(mockPinotVisibilityManager *MockVisibilityManager) { + mockPinotVisibilityManager.EXPECT().ListClosedWorkflowExecutionsByStatus(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + readModeIsFromPinot: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + if test.mockDBVisibilityManager != nil { + test.mockDBVisibilityManagerAccordance(test.mockDBVisibilityManager.(*MockVisibilityManager)) + } + if test.mockPinotVisibilityManager != nil { + test.mockPinotVisibilityManagerAccordance(test.mockPinotVisibilityManager.(*MockVisibilityManager)) + } + if test.mockESVisibilityManager != nil { + test.mockESVisibilityManagerAccordance(test.mockESVisibilityManager.(*MockVisibilityManager)) + } + + visibilityManager := NewPinotVisibilityTripleManager(test.mockDBVisibilityManager, test.mockPinotVisibilityManager, + test.mockESVisibilityManager, test.readModeIsFromPinot, test.readModeIsFromES, + nil, dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), log.NewNoop()) + + _, err := visibilityManager.ListClosedWorkflowExecutionsByStatus(context.Background(), test.request) + if test.expectedError != nil { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestPinotTripleGetClosedWorkflowExecution(t *testing.T) { + request := &GetClosedWorkflowExecutionRequest{ + Domain: "test-domain", + } + + // put this outside because need to use it as an input of the table tests + ctrl := gomock.NewController(t) + + tests := map[string]struct { + request *GetClosedWorkflowExecutionRequest + mockDBVisibilityManager VisibilityManager + mockESVisibilityManager VisibilityManager + mockPinotVisibilityManager VisibilityManager + mockDBVisibilityManagerAccordance func(mockDBVisibilityManager *MockVisibilityManager) + mockPinotVisibilityManagerAccordance func(mockPinotVisibilityManager *MockVisibilityManager) + mockESVisibilityManagerAccordance func(mockESVisibilityManager *MockVisibilityManager) + readModeIsFromES dynamicconfig.BoolPropertyFnWithDomainFilter + readModeIsFromPinot dynamicconfig.BoolPropertyFnWithDomainFilter + expectedError error + }{ + "Case1-1: success case with DB visibility is not nil": { + request: request, + mockDBVisibilityManager: NewMockVisibilityManager(ctrl), + mockDBVisibilityManagerAccordance: func(mockDBVisibilityManager *MockVisibilityManager) { + mockDBVisibilityManager.EXPECT().GetClosedWorkflowExecution(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + "Case1-2: success case with Pinot visibility is not nil": { + request: request, + mockPinotVisibilityManager: NewMockVisibilityManager(ctrl), + mockPinotVisibilityManagerAccordance: func(mockPinotVisibilityManager *MockVisibilityManager) { + mockPinotVisibilityManager.EXPECT().GetClosedWorkflowExecution(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + readModeIsFromPinot: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + if test.mockDBVisibilityManager != nil { + test.mockDBVisibilityManagerAccordance(test.mockDBVisibilityManager.(*MockVisibilityManager)) + } + if test.mockPinotVisibilityManager != nil { + test.mockPinotVisibilityManagerAccordance(test.mockPinotVisibilityManager.(*MockVisibilityManager)) + } + if test.mockESVisibilityManager != nil { + test.mockESVisibilityManagerAccordance(test.mockESVisibilityManager.(*MockVisibilityManager)) + } + + visibilityManager := NewPinotVisibilityTripleManager(test.mockDBVisibilityManager, test.mockPinotVisibilityManager, + test.mockESVisibilityManager, test.readModeIsFromPinot, test.readModeIsFromES, + nil, dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), log.NewNoop()) + + _, err := visibilityManager.GetClosedWorkflowExecution(context.Background(), test.request) + if test.expectedError != nil { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestPinotTripleListWorkflowExecutions(t *testing.T) { + request := &ListWorkflowExecutionsByQueryRequest{ + Domain: "test-domain", + } + + // put this outside because need to use it as an input of the table tests + ctrl := gomock.NewController(t) + + tests := map[string]struct { + request *ListWorkflowExecutionsByQueryRequest + mockDBVisibilityManager VisibilityManager + mockESVisibilityManager VisibilityManager + mockPinotVisibilityManager VisibilityManager + mockDBVisibilityManagerAccordance func(mockDBVisibilityManager *MockVisibilityManager) + mockPinotVisibilityManagerAccordance func(mockPinotVisibilityManager *MockVisibilityManager) + mockESVisibilityManagerAccordance func(mockESVisibilityManager *MockVisibilityManager) + readModeIsFromES dynamicconfig.BoolPropertyFnWithDomainFilter + readModeIsFromPinot dynamicconfig.BoolPropertyFnWithDomainFilter + expectedError error + }{ + "Case1-1: success case with DB visibility is not nil": { + request: request, + mockDBVisibilityManager: NewMockVisibilityManager(ctrl), + mockDBVisibilityManagerAccordance: func(mockDBVisibilityManager *MockVisibilityManager) { + mockDBVisibilityManager.EXPECT().ListWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + "Case1-2: success case with Pinot visibility is not nil": { + request: request, + mockPinotVisibilityManager: NewMockVisibilityManager(ctrl), + mockPinotVisibilityManagerAccordance: func(mockPinotVisibilityManager *MockVisibilityManager) { + mockPinotVisibilityManager.EXPECT().ListWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + readModeIsFromPinot: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + if test.mockDBVisibilityManager != nil { + test.mockDBVisibilityManagerAccordance(test.mockDBVisibilityManager.(*MockVisibilityManager)) + } + if test.mockPinotVisibilityManager != nil { + test.mockPinotVisibilityManagerAccordance(test.mockPinotVisibilityManager.(*MockVisibilityManager)) + } + if test.mockESVisibilityManager != nil { + test.mockESVisibilityManagerAccordance(test.mockESVisibilityManager.(*MockVisibilityManager)) + } + + visibilityManager := NewPinotVisibilityTripleManager(test.mockDBVisibilityManager, test.mockPinotVisibilityManager, + test.mockESVisibilityManager, test.readModeIsFromPinot, test.readModeIsFromES, + nil, dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), log.NewNoop()) + + _, err := visibilityManager.ListWorkflowExecutions(context.Background(), test.request) + if test.expectedError != nil { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestPinotTripleScanWorkflowExecutions(t *testing.T) { + request := &ListWorkflowExecutionsByQueryRequest{ + Domain: "test-domain", + } + + // put this outside because need to use it as an input of the table tests + ctrl := gomock.NewController(t) + + tests := map[string]struct { + request *ListWorkflowExecutionsByQueryRequest + mockDBVisibilityManager VisibilityManager + mockESVisibilityManager VisibilityManager + mockPinotVisibilityManager VisibilityManager + mockDBVisibilityManagerAccordance func(mockDBVisibilityManager *MockVisibilityManager) + mockPinotVisibilityManagerAccordance func(mockPinotVisibilityManager *MockVisibilityManager) + mockESVisibilityManagerAccordance func(mockESVisibilityManager *MockVisibilityManager) + readModeIsFromES dynamicconfig.BoolPropertyFnWithDomainFilter + readModeIsFromPinot dynamicconfig.BoolPropertyFnWithDomainFilter + expectedError error + }{ + "Case1-1: success case with DB visibility is not nil": { + request: request, + mockDBVisibilityManager: NewMockVisibilityManager(ctrl), + mockDBVisibilityManagerAccordance: func(mockDBVisibilityManager *MockVisibilityManager) { + mockDBVisibilityManager.EXPECT().ScanWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + "Case1-2: success case with Pinot visibility is not nil": { + request: request, + mockPinotVisibilityManager: NewMockVisibilityManager(ctrl), + mockPinotVisibilityManagerAccordance: func(mockPinotVisibilityManager *MockVisibilityManager) { + mockPinotVisibilityManager.EXPECT().ScanWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + readModeIsFromPinot: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + if test.mockDBVisibilityManager != nil { + test.mockDBVisibilityManagerAccordance(test.mockDBVisibilityManager.(*MockVisibilityManager)) + } + if test.mockPinotVisibilityManager != nil { + test.mockPinotVisibilityManagerAccordance(test.mockPinotVisibilityManager.(*MockVisibilityManager)) + } + if test.mockESVisibilityManager != nil { + test.mockESVisibilityManagerAccordance(test.mockESVisibilityManager.(*MockVisibilityManager)) + } + + visibilityManager := NewPinotVisibilityTripleManager(test.mockDBVisibilityManager, test.mockPinotVisibilityManager, + test.mockESVisibilityManager, test.readModeIsFromPinot, test.readModeIsFromES, + nil, dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), log.NewNoop()) + + _, err := visibilityManager.ScanWorkflowExecutions(context.Background(), test.request) + if test.expectedError != nil { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestPinotTripleCountWorkflowExecutions(t *testing.T) { + request := &CountWorkflowExecutionsRequest{ + Domain: "test-domain", + } + + ctrl := gomock.NewController(t) + + tests := map[string]struct { + request *CountWorkflowExecutionsRequest + mockDBVisibilityManager VisibilityManager + mockESVisibilityManager VisibilityManager + mockPinotVisibilityManager VisibilityManager + mockDBVisibilityManagerAccordance func(mockDBVisibilityManager *MockVisibilityManager) + mockPinotVisibilityManagerAccordance func(mockPinotVisibilityManager *MockVisibilityManager) + mockESVisibilityManagerAccordance func(mockESVisibilityManager *MockVisibilityManager) + readModeIsFromES dynamicconfig.BoolPropertyFnWithDomainFilter + readModeIsFromPinot dynamicconfig.BoolPropertyFnWithDomainFilter + expectedError error + }{ + "Case1-1: success case with DB visibility is not nil": { + request: request, + mockDBVisibilityManager: NewMockVisibilityManager(ctrl), + mockDBVisibilityManagerAccordance: func(mockDBVisibilityManager *MockVisibilityManager) { + mockDBVisibilityManager.EXPECT().CountWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + "Case1-2: success case with Pinot visibility is not nil": { + request: request, + mockPinotVisibilityManager: NewMockVisibilityManager(ctrl), + mockPinotVisibilityManagerAccordance: func(mockPinotVisibilityManager *MockVisibilityManager) { + mockPinotVisibilityManager.EXPECT().CountWorkflowExecutions(gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + }, + readModeIsFromES: dynamicconfig.GetBoolPropertyFnFilteredByDomain(false), + readModeIsFromPinot: dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), + expectedError: nil, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + if test.mockDBVisibilityManager != nil { + test.mockDBVisibilityManagerAccordance(test.mockDBVisibilityManager.(*MockVisibilityManager)) + } + if test.mockPinotVisibilityManager != nil { + test.mockPinotVisibilityManagerAccordance(test.mockPinotVisibilityManager.(*MockVisibilityManager)) + } + if test.mockESVisibilityManager != nil { + test.mockESVisibilityManagerAccordance(test.mockESVisibilityManager.(*MockVisibilityManager)) + } + + visibilityManager := NewPinotVisibilityTripleManager(test.mockDBVisibilityManager, test.mockPinotVisibilityManager, + test.mockESVisibilityManager, test.readModeIsFromPinot, test.readModeIsFromES, + nil, dynamicconfig.GetBoolPropertyFnFilteredByDomain(true), log.NewNoop()) + + _, err := visibilityManager.CountWorkflowExecutions(context.Background(), test.request) + if test.expectedError != nil { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +}