@@ -29,6 +29,8 @@ import (
2929 mqmock "github.com/uber/submitqueue/platform/extension/messagequeue/mock"
3030 "github.com/uber/submitqueue/platform/metrics"
3131 stovepipemq "github.com/uber/submitqueue/stovepipe/core/messagequeue"
32+ "github.com/uber/submitqueue/stovepipe/core/requestlog"
33+ requestlogmock "github.com/uber/submitqueue/stovepipe/core/requestlog/mock"
3234 "github.com/uber/submitqueue/stovepipe/entity"
3335 "github.com/uber/submitqueue/stovepipe/extension/buildrunner"
3436 buildrunnermock "github.com/uber/submitqueue/stovepipe/extension/buildrunner/mock"
@@ -55,6 +57,8 @@ func queueContext() context.Context {
5557type buildMocks struct {
5658 reqStore * storagemock.MockRequestStore
5759 buildStore * storagemock.MockBuildStore
60+ store * storagemock.MockStorage
61+ materializer * requestlogmock.MockMaterializer
5862 runnerFactory * buildrunnermock.MockFactory
5963 runner * buildrunnermock.MockBuildRunner
6064 publisher * mqmock.MockPublisher
@@ -74,15 +78,16 @@ func newController(t *testing.T, ctrl *gomock.Controller) (*Controller, buildMoc
7478 m := buildMocks {
7579 reqStore : storagemock .NewMockRequestStore (ctrl ),
7680 buildStore : storagemock .NewMockBuildStore (ctrl ),
81+ store : storagemock .NewMockStorage (ctrl ),
82+ materializer : requestlogmock .NewMockMaterializer (ctrl ),
7783 runnerFactory : buildrunnermock .NewMockFactory (ctrl ),
7884 runner : buildrunnermock .NewMockBuildRunner (ctrl ),
7985 publisher : mqmock .NewMockPublisher (ctrl ),
8086 metricsScope : scope ,
8187 }
8288
83- store := storagemock .NewMockStorage (ctrl )
84- store .EXPECT ().GetRequestStore ().Return (m .reqStore ).AnyTimes ()
85- store .EXPECT ().GetBuildStore ().Return (m .buildStore ).AnyTimes ()
89+ m .store .EXPECT ().GetRequestStore ().Return (m .reqStore ).AnyTimes ()
90+ m .store .EXPECT ().GetBuildStore ().Return (m .buildStore ).AnyTimes ()
8691
8792 queue := mqmock .NewMockQueue (ctrl )
8893 queue .EXPECT ().Publisher ().Return (m .publisher ).AnyTimes ()
@@ -92,10 +97,24 @@ func newController(t *testing.T, ctrl *gomock.Controller) (*Controller, buildMoc
9297 })
9398 require .NoError (t , err )
9499
95- c := NewController (zap .NewNop ().Sugar (), scope , staticStorageFactory {store : store }, m .runnerFactory , registry , stovepipemq .TopicKeyBuild , "stovepipe-build" )
100+ c := NewController (zap .NewNop ().Sugar (), scope , staticStorageFactory {store : m . store }, m . materializer , m .runnerFactory , registry , stovepipemq .TopicKeyBuild , "stovepipe-build" )
96101 return c , m
97102}
98103
104+ func expectBuildTriggered (m buildMocks ) * gomock.Call {
105+ request := entity.Request {ID : testID , Queue : testQueue }
106+ return m .materializer .EXPECT ().PersistLog (
107+ gomock .Any (),
108+ m .store ,
109+ requestlog .NewRequestEventLog (
110+ request ,
111+ entity .RequestEventBuildTriggered ,
112+ testBuildID ,
113+ map [string ]string {requestlog .MetadataKeyBuildID : testBuildID },
114+ ),
115+ ).Return (nil )
116+ }
117+
99118func TestProcessTagsMetricsWithQueue (t * testing.T ) {
100119 ctrl := gomock .NewController (t )
101120 c , m := newController (t , ctrl )
@@ -185,8 +204,9 @@ func TestProcess(t *testing.T) {
185204 Status : entity .BuildStatusAccepted ,
186205 Version : 1 ,
187206 }
188- m .buildStore .EXPECT ().Create (gomock .Any (), build ).Return (nil )
189- m .publisher .EXPECT ().Publish (gomock .Any (), "buildsignal" , gomock .Any ()).Return (nil )
207+ createCall := m .buildStore .EXPECT ().Create (gomock .Any (), build ).Return (nil )
208+ logCall := expectBuildTriggered (m ).After (createCall )
209+ m .publisher .EXPECT ().Publish (gomock .Any (), "buildsignal" , gomock .Any ()).Return (nil ).After (logCall )
190210 },
191211 },
192212 {
@@ -202,8 +222,9 @@ func TestProcess(t *testing.T) {
202222 Status : entity .BuildStatusAccepted ,
203223 Version : 1 ,
204224 }
205- m .buildStore .EXPECT ().Create (gomock .Any (), build ).Return (nil )
206- m .publisher .EXPECT ().Publish (gomock .Any (), "buildsignal" , gomock .Any ()).Return (nil )
225+ createCall := m .buildStore .EXPECT ().Create (gomock .Any (), build ).Return (nil )
226+ logCall := expectBuildTriggered (m ).After (createCall )
227+ m .publisher .EXPECT ().Publish (gomock .Any (), "buildsignal" , gomock .Any ()).Return (nil ).After (logCall )
207228 },
208229 },
209230 {
@@ -286,14 +307,14 @@ func TestProcess(t *testing.T) {
286307 },
287308 },
288309 {
289- name : "already exists on create is swallowed and publish still happens" ,
310+ name : "duplicate runner build id is rejected" ,
311+ wantErr : true ,
290312 setup : func (m buildMocks ) {
291313 req := processingRequest (entity .BuildStrategyFull , "" )
292314 m .reqStore .EXPECT ().Get (gomock .Any (), testID ).Return (req , nil )
293315 m .runnerFactory .EXPECT ().For (buildrunner.Config {QueueName : testQueue }).Return (m .runner , nil )
294316 m .runner .EXPECT ().Trigger (gomock .Any (), "" , testHeadURI , entity .BuildMetadata (nil )).Return (entity.BuildID {ID : testBuildID }, nil )
295317 m .buildStore .EXPECT ().Create (gomock .Any (), gomock .Any ()).Return (storage .ErrAlreadyExists )
296- m .publisher .EXPECT ().Publish (gomock .Any (), "buildsignal" , gomock .Any ()).Return (nil )
297318 },
298319 },
299320 {
@@ -308,6 +329,28 @@ func TestProcess(t *testing.T) {
308329 m .buildStore .EXPECT ().Create (gomock .Any (), gomock .Any ()).Return (errors .New ("db down" ))
309330 },
310331 },
332+ {
333+ name : "event persistence failure stops before buildsignal" ,
334+ wantErr : true ,
335+ setup : func (m buildMocks ) {
336+ req := processingRequest (entity .BuildStrategyFull , "" )
337+ m .reqStore .EXPECT ().Get (gomock .Any (), testID ).Return (req , nil )
338+ m .runnerFactory .EXPECT ().For (buildrunner.Config {QueueName : testQueue }).Return (m .runner , nil )
339+ m .runner .EXPECT ().Trigger (gomock .Any (), "" , testHeadURI , entity .BuildMetadata (nil )).Return (entity.BuildID {ID : testBuildID }, nil )
340+ createCall := m .buildStore .EXPECT ().Create (gomock .Any (), gomock .Any ()).Return (nil )
341+ request := entity.Request {ID : testID , Queue : testQueue }
342+ m .materializer .EXPECT ().PersistLog (
343+ gomock .Any (),
344+ m .store ,
345+ requestlog .NewRequestEventLog (
346+ request ,
347+ entity .RequestEventBuildTriggered ,
348+ testBuildID ,
349+ map [string ]string {requestlog .MetadataKeyBuildID : testBuildID },
350+ ),
351+ ).Return (errors .New ("db down" )).After (createCall )
352+ },
353+ },
311354 {
312355 name : "publish failure is not retryable" ,
313356 wantErr : true ,
@@ -317,8 +360,9 @@ func TestProcess(t *testing.T) {
317360 m .reqStore .EXPECT ().Get (gomock .Any (), testID ).Return (req , nil )
318361 m .runnerFactory .EXPECT ().For (buildrunner.Config {QueueName : testQueue }).Return (m .runner , nil )
319362 m .runner .EXPECT ().Trigger (gomock .Any (), "" , testHeadURI , entity .BuildMetadata (nil )).Return (entity.BuildID {ID : testBuildID }, nil )
320- m .buildStore .EXPECT ().Create (gomock .Any (), gomock .Any ()).Return (nil )
321- m .publisher .EXPECT ().Publish (gomock .Any (), "buildsignal" , gomock .Any ()).Return (errors .New ("queue down" ))
363+ createCall := m .buildStore .EXPECT ().Create (gomock .Any (), gomock .Any ()).Return (nil )
364+ logCall := expectBuildTriggered (m ).After (createCall )
365+ m .publisher .EXPECT ().Publish (gomock .Any (), "buildsignal" , gomock .Any ()).Return (errors .New ("queue down" )).After (logCall )
322366 },
323367 },
324368 {
0 commit comments