go.uber.org/cadence@v1.2.9/internal/registry_test.go (about) 1 // Copyright (c) 2017-2020 Uber Technologies Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package internal 22 23 import ( 24 "testing" 25 26 "github.com/stretchr/testify/require" 27 ) 28 29 func TestWorkflowRegistration(t *testing.T) { 30 w := &testWorkflowStruct{} 31 tests := []struct { 32 msg string 33 register func(r *registry) 34 registerPanic bool 35 workflowType string 36 altWorkflowType string 37 resolveByFunction interface{} 38 resolveByAlias string 39 }{ 40 { 41 msg: "register workflow function", 42 register: func(r *registry) { r.RegisterWorkflow(testWorkflowFunction) }, 43 workflowType: "go.uber.org/cadence/internal.testWorkflowFunction", 44 resolveByFunction: testWorkflowFunction, 45 }, 46 { 47 msg: "register workflow function with short name", 48 register: func(r *registry) { 49 r.RegisterWorkflowWithOptions(testWorkflowFunction, RegisterWorkflowOptions{EnableShortName: true}) 50 }, 51 workflowType: "testWorkflowFunction", 52 resolveByFunction: testWorkflowFunction, 53 }, 54 { 55 msg: "register workflow function with alias", 56 register: func(r *registry) { 57 r.RegisterWorkflowWithOptions(testWorkflowFunction, RegisterWorkflowOptions{Name: "workflow.alias"}) 58 }, 59 workflowType: "workflow.alias", 60 resolveByFunction: testWorkflowFunction, 61 resolveByAlias: "workflow.alias", 62 }, 63 { 64 msg: "register workflow struct function (backwards compatible)", 65 register: func(r *registry) { r.RegisterWorkflow(w.Method) }, 66 workflowType: "go.uber.org/cadence/internal.(*testWorkflowStruct).Method", 67 altWorkflowType: "go.uber.org/cadence/internal.(*testWorkflowStruct).Method-fm", 68 resolveByFunction: w.Method, 69 }, 70 { 71 msg: "register duplicated workflow in one registry (should panic)", 72 register: func(r *registry) { 73 r.RegisterWorkflow(testWorkflowFunction) 74 r.RegisterWorkflow(testWorkflowFunction) 75 }, 76 registerPanic: true, 77 }, 78 { 79 msg: "register duplicated workflow with already registered check disabled", 80 register: func(r *registry) { 81 r.RegisterWorkflow(testWorkflowFunction) 82 r.RegisterWorkflowWithOptions(testWorkflowFunction, RegisterWorkflowOptions{DisableAlreadyRegisteredCheck: true}) 83 }, 84 workflowType: "go.uber.org/cadence/internal.testWorkflowFunction", 85 resolveByFunction: testWorkflowFunction, 86 }, 87 { 88 msg: "register duplicated workflow in chained registry (should panic)", 89 register: func(r *registry) { 90 r.next.RegisterWorkflow(testWorkflowFunction) 91 r.RegisterWorkflow(testWorkflowFunction) 92 }, 93 registerPanic: true, 94 }, 95 } 96 97 for _, tt := range tests { 98 t.Run(tt.msg, func(t *testing.T) { 99 r := newRegistry() 100 if tt.registerPanic { 101 require.Panics(t, func() { tt.register(r) }, "register should panic") 102 return 103 } 104 105 tt.register(r) 106 107 // Verify registered workflow type 108 workflowType := r.GetRegisteredWorkflowTypes()[0] 109 require.Equal(t, tt.workflowType, workflowType) 110 111 // Verify workflow is resolved from workflow type 112 _, ok := r.getWorkflowFn(tt.workflowType) 113 require.True(t, ok) 114 115 // Verify workflow is resolved from alternative (backwards compatible) workflow type 116 if len(tt.altWorkflowType) > 0 { 117 _, ok = r.getWorkflowFn(tt.altWorkflowType) 118 require.True(t, ok) 119 } 120 121 // Verify resolving by function reference 122 workflowType = getWorkflowFunctionName(r, tt.resolveByFunction) 123 require.Equal(t, tt.workflowType, workflowType) 124 125 // Verify resolving by alias 126 if tt.resolveByAlias != "" { 127 workflowType = getWorkflowFunctionName(r, tt.resolveByAlias) 128 require.Equal(t, tt.workflowType, workflowType) 129 } 130 }) 131 } 132 } 133 134 func TestActivityRegistration(t *testing.T) { 135 tests := []struct { 136 msg string 137 register func(r *registry) 138 registerPanic bool 139 activityType string 140 altActivityType string 141 resolveByFunction interface{} 142 resolveByAlias string 143 }{ 144 { 145 msg: "register activity function", 146 register: func(r *registry) { r.RegisterActivity(testActivityFunction) }, 147 activityType: "go.uber.org/cadence/internal.testActivityFunction", 148 resolveByFunction: testActivityFunction, 149 }, 150 { 151 msg: "register activity function with short name", 152 register: func(r *registry) { 153 r.RegisterActivityWithOptions(testActivityFunction, RegisterActivityOptions{EnableShortName: true}) 154 }, 155 activityType: "testActivityFunction", 156 resolveByFunction: testActivityFunction, 157 }, 158 { 159 msg: "register activity function with an alias", 160 register: func(r *registry) { 161 r.RegisterActivityWithOptions(testActivityFunction, RegisterActivityOptions{Name: "activity.alias"}) 162 }, 163 activityType: "activity.alias", 164 resolveByFunction: testActivityFunction, 165 resolveByAlias: "activity.alias", 166 }, 167 { 168 msg: "register activity struct", 169 register: func(r *registry) { r.RegisterActivity(&testActivityStruct{}) }, 170 activityType: "go.uber.org/cadence/internal.(*testActivityStruct).Method", 171 altActivityType: "go.uber.org/cadence/internal.(*testActivityStruct).Method-fm", 172 resolveByFunction: (&testActivityStruct{}).Method, 173 }, 174 { 175 msg: "register activity struct with short name", 176 register: func(r *registry) { 177 r.RegisterActivityWithOptions(&testActivityStruct{}, RegisterActivityOptions{EnableShortName: true}) 178 }, 179 activityType: "Method", 180 resolveByFunction: (&testActivityStruct{}).Method, 181 }, 182 { 183 msg: "register activity struct with a prefix", 184 register: func(r *registry) { 185 r.RegisterActivityWithOptions(&testActivityStruct{}, RegisterActivityOptions{Name: "prefix."}) 186 }, 187 activityType: "prefix.Method", 188 resolveByFunction: (&testActivityStruct{}).Method, 189 resolveByAlias: "prefix.Method", 190 }, 191 { 192 msg: "register duplicated activity function in one registry (should panic)", 193 register: func(r *registry) { 194 duplicatedActivityAlias := "activity.alias" 195 r.RegisterActivityWithOptions(testActivityFunction, RegisterActivityOptions{Name: duplicatedActivityAlias}) 196 r.RegisterActivityWithOptions(testActivityFunction, RegisterActivityOptions{Name: duplicatedActivityAlias}) 197 }, 198 registerPanic: true, 199 }, 200 { 201 msg: "register duplicated activity struct with already registered check disabled", 202 register: func(r *registry) { 203 r.RegisterActivity(&testActivityStruct{}) 204 r.RegisterActivityWithOptions(&testActivityStruct{}, RegisterActivityOptions{DisableAlreadyRegisteredCheck: true}) 205 }, 206 activityType: "go.uber.org/cadence/internal.(*testActivityStruct).Method", 207 resolveByFunction: (&testActivityStruct{}).Method, 208 }, 209 { 210 msg: "register duplicated activity function in chained registry (should panic)", 211 register: func(r *registry) { 212 r.next.RegisterActivity(testActivityFunction) 213 r.RegisterActivity(testActivityFunction) 214 }, 215 registerPanic: true, 216 }, 217 } 218 for _, tt := range tests { 219 t.Run(tt.msg, func(t *testing.T) { 220 r := newRegistry() 221 if tt.registerPanic { 222 require.Panics(t, func() { tt.register(r) }, "register should panic") 223 return 224 } 225 226 tt.register(r) 227 228 // Verify registered activity type 229 activityType := r.getRegisteredActivities()[0].ActivityType().Name 230 require.Equal(t, tt.activityType, activityType, "activity type") 231 232 // Verify activity is resolved from activity type 233 _, ok := r.GetActivity(tt.activityType) 234 require.True(t, ok) 235 236 // Verify activity is resolved from alternative (backwards compatible) activity type 237 if len(tt.altActivityType) > 0 { 238 _, ok = r.GetActivity(tt.altActivityType) 239 require.True(t, ok) 240 } 241 242 // Verify resolving by function reference 243 activityType = getActivityFunctionName(r, tt.resolveByFunction) 244 require.Equal(t, tt.activityType, activityType, "resolve by function reference") 245 246 // Verify resolving by alias 247 if tt.resolveByAlias != "" { 248 activityType = getActivityFunctionName(r, tt.resolveByAlias) 249 require.Equal(t, tt.activityType, activityType, "resolve by alias") 250 } 251 }) 252 } 253 } 254 255 type testWorkflowStruct struct{} 256 type testActivityStruct struct{} 257 258 func (ts *testWorkflowStruct) Method(ctx Context) error { return nil } 259 func (ts *testActivityStruct) Method() error { return nil } 260 261 func testActivityFunction() error { return nil } 262 func testWorkflowFunction(ctx Context) error { return nil }