@@ -50,7 +50,7 @@ func newTestLogger() *zap.SugaredLogger {
5050 return l .Sugar ()
5151}
5252
53- func TestConstruct_SingleStage_NoDLQ (t * testing.T ) {
53+ func TestConstruct_SingleStage (t * testing.T ) {
5454 ctrl := gomock .NewController (t )
5555 q := mqmock .NewMockQueue (ctrl )
5656 q .EXPECT ().Subscriber ().Return (mqmock .NewMockSubscriber (ctrl )).AnyTimes ()
@@ -61,10 +61,13 @@ func TestConstruct_SingleStage_NoDLQ(t *testing.T) {
6161 {
6262 Key : "start" ,
6363 Name : "start" ,
64- ConsumerGroup : "orchestrator-start " ,
64+ ConsumerGroup : "orchestrator" ,
6565 New : func (d testDeps , sc StageContext ) (consumer.Controller , error ) {
6666 return & fakeController {key : sc .TopicKey , group : sc .ConsumerGroup }, nil
6767 },
68+ DLQ : func (d testDeps , sc StageContext ) (consumer.Controller , error ) {
69+ return & fakeController {key : sc .TopicKey , group : sc .ConsumerGroup }, nil
70+ },
6871 },
6972 }
7073
@@ -84,7 +87,7 @@ func TestConstruct_WithDLQ(t *testing.T) {
8487 {
8588 Key : "start" ,
8689 Name : "start" ,
87- ConsumerGroup : "orchestrator-start " ,
90+ ConsumerGroup : "orchestrator" ,
8891 New : func (d testDeps , sc StageContext ) (consumer.Controller , error ) {
8992 return & fakeController {key : sc .TopicKey , group : sc .ConsumerGroup }, nil
9093 },
@@ -99,6 +102,30 @@ func TestConstruct_WithDLQ(t *testing.T) {
99102 assert .NotNil (t , comp )
100103}
101104
105+ func TestConstruct_NilDLQ_Error (t * testing.T ) {
106+ ctrl := gomock .NewController (t )
107+ q := mqmock .NewMockQueue (ctrl )
108+ q .EXPECT ().Subscriber ().Return (mqmock .NewMockSubscriber (ctrl )).AnyTimes ()
109+ q .EXPECT ().Publisher ().Return (mqmock .NewMockPublisher (ctrl )).AnyTimes ()
110+
111+ deps := testDeps {logger : newTestLogger ()}
112+ stages := []Stage [testDeps ]{
113+ {
114+ Key : "start" ,
115+ Name : "start" ,
116+ ConsumerGroup : "orchestrator" ,
117+ New : func (d testDeps , sc StageContext ) (consumer.Controller , error ) {
118+ return & fakeController {key : sc .TopicKey , group : sc .ConsumerGroup }, nil
119+ },
120+ // DLQ intentionally omitted.
121+ },
122+ }
123+
124+ _ , err := Construct (deps .logger , tally .NoopScope , q , "test-sub" , deps , stages )
125+ require .Error (t , err )
126+ assert .Contains (t , err .Error (), "DLQ handler is required" )
127+ }
128+
102129func TestConstruct_MultipleStages (t * testing.T ) {
103130 ctrl := gomock .NewController (t )
104131 q := mqmock .NewMockQueue (ctrl )
@@ -110,15 +137,18 @@ func TestConstruct_MultipleStages(t *testing.T) {
110137 {
111138 Key : "start" ,
112139 Name : "start" ,
113- ConsumerGroup : "orchestrator-start " ,
140+ ConsumerGroup : "orchestrator" ,
114141 New : func (d testDeps , sc StageContext ) (consumer.Controller , error ) {
115142 return & fakeController {key : sc .TopicKey , group : sc .ConsumerGroup }, nil
116143 },
144+ DLQ : func (d testDeps , sc StageContext ) (consumer.Controller , error ) {
145+ return & fakeController {key : sc .TopicKey , group : sc .ConsumerGroup }, nil
146+ },
117147 },
118148 {
119149 Key : "validate" ,
120150 Name : "validate" ,
121- ConsumerGroup : "orchestrator-validate " ,
151+ ConsumerGroup : "orchestrator" ,
122152 New : func (d testDeps , sc StageContext ) (consumer.Controller , error ) {
123153 return & fakeController {key : sc .TopicKey , group : sc .ConsumerGroup }, nil
124154 },
@@ -154,10 +184,13 @@ func TestConstruct_ControllerCreationFailure(t *testing.T) {
154184 {
155185 Key : "start" ,
156186 Name : "start" ,
157- ConsumerGroup : "orchestrator-start " ,
187+ ConsumerGroup : "orchestrator" ,
158188 New : func (d testDeps , sc StageContext ) (consumer.Controller , error ) {
159189 return nil , fmt .Errorf ("missing dependency" )
160190 },
191+ DLQ : func (d testDeps , sc StageContext ) (consumer.Controller , error ) {
192+ return & fakeController {key : sc .TopicKey , group : sc .ConsumerGroup }, nil
193+ },
161194 },
162195 }
163196
@@ -178,7 +211,7 @@ func TestConstruct_DLQControllerCreationFailure(t *testing.T) {
178211 {
179212 Key : "start" ,
180213 Name : "start" ,
181- ConsumerGroup : "orchestrator-start " ,
214+ ConsumerGroup : "orchestrator" ,
182215 New : func (d testDeps , sc StageContext ) (consumer.Controller , error ) {
183216 return & fakeController {key : sc .TopicKey , group : sc .ConsumerGroup }, nil
184217 },
@@ -205,10 +238,13 @@ func TestConstruct_WithPublishOnly(t *testing.T) {
205238 {
206239 Key : "start" ,
207240 Name : "start" ,
208- ConsumerGroup : "orchestrator-start " ,
241+ ConsumerGroup : "orchestrator" ,
209242 New : func (d testDeps , sc StageContext ) (consumer.Controller , error ) {
210243 return & fakeController {key : sc .TopicKey , group : sc .ConsumerGroup }, nil
211244 },
245+ DLQ : func (d testDeps , sc StageContext ) (consumer.Controller , error ) {
246+ return & fakeController {key : sc .TopicKey , group : sc .ConsumerGroup }, nil
247+ },
212248 },
213249 }
214250
@@ -233,10 +269,13 @@ func TestConstruct_WithTopicNameOverrides(t *testing.T) {
233269 {
234270 Key : "start" ,
235271 Name : "start" ,
236- ConsumerGroup : "orchestrator-start " ,
272+ ConsumerGroup : "orchestrator" ,
237273 New : func (d testDeps , sc StageContext ) (consumer.Controller , error ) {
238274 return & fakeController {key : sc .TopicKey , group : sc .ConsumerGroup }, nil
239275 },
276+ DLQ : func (d testDeps , sc StageContext ) (consumer.Controller , error ) {
277+ return & fakeController {key : sc .TopicKey , group : sc .ConsumerGroup }, nil
278+ },
240279 },
241280 }
242281
@@ -262,7 +301,7 @@ func TestConstruct_StageContext_Populated(t *testing.T) {
262301 {
263302 Key : "start" ,
264303 Name : "start" ,
265- ConsumerGroup : "orchestrator-start " ,
304+ ConsumerGroup : "orchestrator" ,
266305 New : func (d testDeps , sc StageContext ) (consumer.Controller , error ) {
267306 primarySC = sc
268307 return & fakeController {key : sc .TopicKey , group : sc .ConsumerGroup }, nil
@@ -279,11 +318,11 @@ func TestConstruct_StageContext_Populated(t *testing.T) {
279318
280319 // Primary StageContext should have the stage's own key and group.
281320 assert .Equal (t , consumer .TopicKey ("start" ), primarySC .TopicKey )
282- assert .Equal (t , "orchestrator-start " , primarySC .ConsumerGroup )
321+ assert .Equal (t , "orchestrator" , primarySC .ConsumerGroup )
283322
284323 // DLQ StageContext should have the derived DLQ key and group.
285324 assert .Equal (t , consumer .TopicKey ("start_dlq" ), dlqSC .TopicKey )
286- assert .Equal (t , "orchestrator-start- dlq" , dlqSC .ConsumerGroup )
325+ assert .Equal (t , "orchestrator-dlq" , dlqSC .ConsumerGroup )
287326
288327 // Both should share the same registry.
289328 assert .Equal (t , primarySC .Registry , dlqSC .Registry )
@@ -347,16 +386,16 @@ func TestBuildTopicConfigs(t *testing.T) {
347386 {
348387 Key : "start" ,
349388 Name : "start" ,
350- ConsumerGroup : "orchestrator-start " ,
389+ ConsumerGroup : "orchestrator" ,
351390 New : func (d testDeps , sc StageContext ) (consumer.Controller , error ) { return nil , nil },
352391 DLQ : func (d testDeps , sc StageContext ) (consumer.Controller , error ) { return nil , nil },
353392 },
354393 {
355394 Key : "validate" ,
356395 Name : "validate" ,
357- ConsumerGroup : "orchestrator-validate " ,
396+ ConsumerGroup : "orchestrator" ,
358397 New : func (d testDeps , sc StageContext ) (consumer.Controller , error ) { return nil , nil },
359- // No DLQ for this stage.
398+ DLQ : func ( d testDeps , sc StageContext ) (consumer. Controller , error ) { return nil , nil },
360399 },
361400 }
362401
@@ -369,29 +408,30 @@ func TestBuildTopicConfigs(t *testing.T) {
369408 configs , err := buildTopicConfigs (q , "test-sub" , stages , o )
370409 require .NoError (t , err )
371410
372- // Expected: start (primary + DLQ) + validate (primary only ) + log (publish-only) = 4
373- assert .Len (t , configs , 4 )
411+ // Expected: start (primary + DLQ) + validate (primary + DLQ ) + log (publish-only) = 5
412+ assert .Len (t , configs , 5 )
374413
375414 // Verify primary stage config.
376415 assert .Equal (t , consumer .TopicKey ("start" ), configs [0 ].Key )
377416 assert .Equal (t , "start" , configs [0 ].Name )
378- assert .Equal (t , "orchestrator-start " , configs [0 ].Subscription .ConsumerGroup )
417+ assert .Equal (t , "orchestrator" , configs [0 ].Subscription .ConsumerGroup )
379418
380419 // Verify DLQ config derived from primary.
381420 assert .Equal (t , consumer .TopicKey ("start_dlq" ), configs [1 ].Key )
382421 assert .Equal (t , "start_dlq" , configs [1 ].Name )
383- assert .Equal (t , "orchestrator-start- dlq" , configs [1 ].Subscription .ConsumerGroup )
422+ assert .Equal (t , "orchestrator-dlq" , configs [1 ].Subscription .ConsumerGroup )
384423
385424 // Verify DLQ subscription has DLQ disabled (no cascade).
386- expected := extqueue .DLQSubscriptionConfig ("test-sub" , "orchestrator-start- dlq" )
425+ expected := extqueue .DLQSubscriptionConfig ("test-sub" , "orchestrator-dlq" )
387426 assert .Equal (t , expected .DLQ .Enabled , configs [1 ].Subscription .DLQ .Enabled )
388427 assert .Equal (t , expected .Retry .MaxAttempts , configs [1 ].Subscription .Retry .MaxAttempts )
389428
390- // Verify validate stage (no DLQ).
429+ // Verify validate stage (primary + DLQ).
391430 assert .Equal (t , consumer .TopicKey ("validate" ), configs [2 ].Key )
431+ assert .Equal (t , consumer .TopicKey ("validate_dlq" ), configs [3 ].Key )
392432
393433 // Verify publish-only topic.
394- assert .Equal (t , consumer .TopicKey ("log" ), configs [3 ].Key )
395- assert .Equal (t , "log" , configs [3 ].Name )
396- assert .Equal (t , "" , configs [3 ].Subscription .ConsumerGroup )
434+ assert .Equal (t , consumer .TopicKey ("log" ), configs [4 ].Key )
435+ assert .Equal (t , "log" , configs [4 ].Name )
436+ assert .Equal (t , "" , configs [4 ].Subscription .ConsumerGroup )
397437}
0 commit comments