github.com/prebid/prebid-server/v2@v2.18.0/stored_requests/events/database/database_test.go (about) 1 package database 2 3 import ( 4 "encoding/json" 5 "errors" 6 "regexp" 7 "testing" 8 "time" 9 10 "github.com/prebid/prebid-server/v2/config" 11 "github.com/prebid/prebid-server/v2/metrics" 12 "github.com/prebid/prebid-server/v2/stored_requests/backends/db_provider" 13 "github.com/prebid/prebid-server/v2/stored_requests/events" 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/mock" 16 17 sqlmock "github.com/DATA-DOG/go-sqlmock" 18 ) 19 20 // FakeTime implements the Time interface 21 type FakeTime struct { 22 time time.Time 23 } 24 25 func (mc *FakeTime) Now() time.Time { 26 return mc.time 27 } 28 29 const fakeQuery = "SELECT id, requestData, type FROM stored_data" 30 31 func fakeQueryRegex() string { 32 return "^" + regexp.QuoteMeta(fakeQuery) + "$" 33 } 34 35 func TestFetchAllSuccess(t *testing.T) { 36 tests := []struct { 37 description string 38 giveFakeTime time.Time 39 giveMockRows *sqlmock.Rows 40 wantLastUpdate time.Time 41 wantSavedReqs map[string]json.RawMessage 42 wantSavedImps map[string]json.RawMessage 43 wantSavedResps map[string]json.RawMessage 44 wantInvalidatedReqs []string 45 wantInvalidatedImps []string 46 wantInvalidatedResps []string 47 }{ 48 { 49 description: "saved reqs = 0, saved imps = 0, invalidated reqs = 0, invalidated imps = 0", 50 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 51 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}), 52 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 53 }, 54 { 55 description: "saved reqs > 0, saved imps = 0, saved resps = 0, invalidated reqs = 0, invalidated imps = 0, invalidated resps = 0", 56 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 57 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}).AddRow("req-1", "true", "request"), 58 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 59 wantSavedReqs: map[string]json.RawMessage{"req-1": json.RawMessage(`true`)}, 60 wantSavedImps: map[string]json.RawMessage{}, 61 wantSavedResps: map[string]json.RawMessage{}, 62 }, 63 { 64 description: "saved reqs = 0, saved imps > 0, saved resps = 0, invalidated reqs = 0, invalidated imps = 0, invalidated resps = 0", 65 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 66 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}).AddRow("imp-1", "true", "imp"), 67 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 68 wantSavedReqs: map[string]json.RawMessage{}, 69 wantSavedImps: map[string]json.RawMessage{"imp-1": json.RawMessage(`true`)}, 70 wantSavedResps: map[string]json.RawMessage{}, 71 }, 72 { 73 description: "saved reqs = 0, saved imps = 0, saved responses > 0, invalidated reqs = 0, invalidated imps = 0, invalidated responses = 0", 74 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 75 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}).AddRow("resp-1", "true", "response"), 76 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 77 wantSavedReqs: map[string]json.RawMessage{}, 78 wantSavedImps: map[string]json.RawMessage{}, 79 wantSavedResps: map[string]json.RawMessage{"resp-1": json.RawMessage(`true`)}, 80 }, 81 { 82 description: "saved reqs = 0, saved imps = 0, saved responses = 0, invalidated reqs > 0, invalidated imps = 0, invalidated responses = 0", 83 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 84 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}).AddRow("req-1", "", "request"), 85 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 86 }, 87 { 88 description: "saved reqs = 0, saved imps = 0, saved responses = 0, invalidated reqs = 0, invalidated imps > 0, invalidated responses = 0", 89 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 90 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}).AddRow("imp-1", "", "imp"), 91 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 92 }, 93 { 94 description: "saved reqs = 0, saved imps = 0, saved responses = 0, invalidated reqs = 0, invalidated imps = 0, invalidated responses > 0", 95 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 96 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}).AddRow("resp-1", "", "response"), 97 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 98 }, 99 { 100 description: "saved reqs > 0, saved imps > 0, saved responses > 0, invalidated reqs > 0, invalidated imps > 0, invalidated responses > 0", 101 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 102 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}). 103 AddRow("req-1", "true", "request"). 104 AddRow("imp-1", "true", "imp"). 105 AddRow("req-2", "", "request"). 106 AddRow("imp-2", "", "imp"). 107 AddRow("resp-1", "true", "response"). 108 AddRow("resp-2", "", "response"), 109 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 110 wantSavedReqs: map[string]json.RawMessage{"req-1": json.RawMessage(`true`)}, 111 wantSavedImps: map[string]json.RawMessage{"imp-1": json.RawMessage(`true`)}, 112 wantSavedResps: map[string]json.RawMessage{"resp-1": json.RawMessage(`true`)}, 113 }, 114 } 115 116 for _, tt := range tests { 117 provider, dbMock, _ := db_provider.NewDbProviderMock() 118 dbMock.ExpectQuery(fakeQueryRegex()).WillReturnRows(tt.giveMockRows) 119 120 metricsMock := &metrics.MetricsEngineMock{} 121 metricsMock.Mock.On("RecordStoredDataFetchTime", metrics.StoredDataLabels{ 122 DataType: metrics.RequestDataType, 123 DataFetchType: metrics.FetchAll, 124 }, mock.Anything).Return() 125 126 eventProducer := NewDatabaseEventProducer(DatabaseEventProducerConfig{ 127 Provider: provider, 128 RequestType: config.RequestDataType, 129 CacheInitTimeout: 100 * time.Millisecond, 130 CacheInitQuery: fakeQuery, 131 MetricsEngine: metricsMock, 132 }) 133 eventProducer.time = &FakeTime{time: tt.giveFakeTime} 134 err := eventProducer.Run() 135 136 assert.Nil(t, err, tt.description) 137 assert.Equal(t, tt.wantLastUpdate, eventProducer.lastUpdate, tt.description) 138 139 var saves events.Save 140 // Read data from saves channel with timeout to avoid test suite deadlock 141 select { 142 case saves = <-eventProducer.Saves(): 143 case <-time.After(20 * time.Millisecond): 144 } 145 var invalidations events.Invalidation 146 // Read data from invalidations channel with timeout to avoid test suite deadlock 147 select { 148 case invalidations = <-eventProducer.Invalidations(): 149 case <-time.After(20 * time.Millisecond): 150 } 151 152 assert.Equal(t, tt.wantSavedReqs, saves.Requests, tt.description) 153 assert.Equal(t, tt.wantSavedImps, saves.Imps, tt.description) 154 assert.Equal(t, tt.wantSavedResps, saves.Responses, tt.description) 155 assert.Equal(t, tt.wantInvalidatedReqs, invalidations.Requests, tt.description) 156 assert.Equal(t, tt.wantInvalidatedImps, invalidations.Imps, tt.description) 157 assert.Equal(t, tt.wantInvalidatedResps, invalidations.Responses, tt.description) 158 159 metricsMock.AssertExpectations(t) 160 } 161 } 162 163 func TestFetchAllErrors(t *testing.T) { 164 tests := []struct { 165 description string 166 giveFakeTime time.Time 167 giveTimeoutMS int 168 giveMockRows *sqlmock.Rows 169 wantRecordedError metrics.StoredDataError 170 wantLastUpdate time.Time 171 }{ 172 { 173 description: "fetch all timeout", 174 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 175 giveMockRows: nil, 176 wantRecordedError: metrics.StoredDataErrorNetwork, 177 wantLastUpdate: time.Time{}, 178 }, 179 { 180 description: "fetch all query error", 181 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 182 giveTimeoutMS: 100, 183 giveMockRows: nil, 184 wantRecordedError: metrics.StoredDataErrorUndefined, 185 wantLastUpdate: time.Time{}, 186 }, 187 { 188 description: "fetch all row error", 189 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 190 giveTimeoutMS: 100, 191 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}). 192 AddRow("stored-req-id", "true", "request"). 193 RowError(0, errors.New("Some row error.")), 194 wantRecordedError: metrics.StoredDataErrorUndefined, 195 wantLastUpdate: time.Time{}, 196 }, 197 } 198 199 for _, tt := range tests { 200 provider, dbMock, _ := db_provider.NewDbProviderMock() 201 if tt.giveMockRows == nil { 202 dbMock.ExpectQuery(fakeQueryRegex()).WillReturnError(errors.New("Query failed.")) 203 } else { 204 dbMock.ExpectQuery(fakeQueryRegex()).WillReturnRows(tt.giveMockRows) 205 } 206 207 metricsMock := &metrics.MetricsEngineMock{} 208 metricsMock.Mock.On("RecordStoredDataFetchTime", metrics.StoredDataLabels{ 209 DataType: metrics.RequestDataType, 210 DataFetchType: metrics.FetchAll, 211 }, mock.Anything).Return() 212 metricsMock.Mock.On("RecordStoredDataError", metrics.StoredDataLabels{ 213 DataType: metrics.RequestDataType, 214 Error: tt.wantRecordedError, 215 }).Return() 216 217 eventProducer := NewDatabaseEventProducer(DatabaseEventProducerConfig{ 218 Provider: provider, 219 RequestType: config.RequestDataType, 220 CacheInitTimeout: time.Duration(tt.giveTimeoutMS) * time.Millisecond, 221 CacheInitQuery: fakeQuery, 222 MetricsEngine: metricsMock, 223 }) 224 eventProducer.time = &FakeTime{time: tt.giveFakeTime} 225 err := eventProducer.Run() 226 227 assert.NotNil(t, err, tt.description) 228 assert.Equal(t, tt.wantLastUpdate, eventProducer.lastUpdate, tt.description) 229 230 var saves events.Save 231 // Read data from saves channel with timeout to avoid test suite deadlock 232 select { 233 case saves = <-eventProducer.Saves(): 234 case <-time.After(10 * time.Millisecond): 235 } 236 var invalidations events.Invalidation 237 // Read data from invalidations channel with timeout to avoid test suite deadlock 238 select { 239 case invalidations = <-eventProducer.Invalidations(): 240 case <-time.After(10 * time.Millisecond): 241 } 242 243 assert.Nil(t, saves.Requests, tt.description) 244 assert.Nil(t, saves.Imps, tt.description) 245 assert.Nil(t, saves.Responses, tt.description) 246 assert.Nil(t, invalidations.Requests, tt.description) 247 assert.Nil(t, invalidations.Imps, tt.description) 248 assert.Nil(t, invalidations.Responses, tt.description) 249 250 metricsMock.AssertExpectations(t) 251 } 252 } 253 254 func TestFetchDeltaSuccess(t *testing.T) { 255 tests := []struct { 256 description string 257 giveFakeTime time.Time 258 giveMockRows *sqlmock.Rows 259 wantLastUpdate time.Time 260 wantSavedReqs map[string]json.RawMessage 261 wantSavedImps map[string]json.RawMessage 262 wantSavedResps map[string]json.RawMessage 263 wantInvalidatedReqs []string 264 wantInvalidatedImps []string 265 wantInvalidatedResps []string 266 }{ 267 { 268 description: "saved reqs = 0, saved imps = 0, saved resps = 0, invalidated reqs = 0, invalidated imps = 0, invalidated resps = 0", 269 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 270 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}), 271 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 272 }, 273 { 274 description: "saved reqs > 0, saved imps = 0, saved resps = 0, invalidated reqs = 0, invalidated imps = 0, invalidated resps = 0", 275 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 276 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}).AddRow("req-1", "true", "request"), 277 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 278 wantSavedReqs: map[string]json.RawMessage{"req-1": json.RawMessage(`true`)}, 279 wantSavedImps: map[string]json.RawMessage{}, 280 wantSavedResps: map[string]json.RawMessage{}, 281 }, 282 { 283 description: "saved reqs = 0, saved imps > 0, saved resps = 0, invalidated reqs = 0, invalidated imps = 0, invalidated resps = 0", 284 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 285 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}).AddRow("imp-1", "true", "imp"), 286 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 287 wantSavedReqs: map[string]json.RawMessage{}, 288 wantSavedImps: map[string]json.RawMessage{"imp-1": json.RawMessage(`true`)}, 289 wantSavedResps: map[string]json.RawMessage{}, 290 }, 291 { 292 description: "saved reqs = 0, saved imps = 0, saved resps > 0, invalidated reqs = 0, invalidated imps = 0, invalidated resps = 0", 293 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 294 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}).AddRow("resp-1", "true", "response"), 295 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 296 wantSavedReqs: map[string]json.RawMessage{}, 297 wantSavedImps: map[string]json.RawMessage{}, 298 wantSavedResps: map[string]json.RawMessage{"resp-1": json.RawMessage(`true`)}, 299 }, 300 { 301 description: "saved reqs = 0, saved imps = 0, saved resps = 0, invalidated reqs > 0, invalidated imps = 0, invalidated resps = 0, empty data", 302 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 303 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}).AddRow("req-1", "", "request"), 304 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 305 wantInvalidatedReqs: []string{"req-1"}, 306 wantInvalidatedImps: nil, 307 wantInvalidatedResps: nil, 308 }, 309 { 310 description: "saved reqs = 0, saved imps = 0, saved resps = 0, invalidated reqs = 0, invalidated imps = 0, invalidated resps > 0, null data", 311 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 312 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}).AddRow("resp-1", "null", "response"), 313 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 314 wantInvalidatedReqs: nil, 315 wantInvalidatedImps: nil, 316 wantInvalidatedResps: []string{"resp-1"}, 317 }, 318 { 319 description: "saved reqs = 0, saved imps = 0, saved resps = 0, invalidated reqs = 0, invalidated imps > 0, invalidated resps = 0, empty data", 320 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 321 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}).AddRow("imp-1", "", "imp"), 322 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 323 wantInvalidatedImps: []string{"imp-1"}, 324 }, 325 { 326 description: "saved reqs = 0, saved imps = 0, saved resps = 0, invalidated reqs = 0, invalidated imps > 0, invalidated resps = 0, null data", 327 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 328 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}).AddRow("imp-1", "null", "imp"), 329 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 330 wantInvalidatedImps: []string{"imp-1"}, 331 }, 332 { 333 description: "saved reqs > 0, saved imps > 0, saved resps > 0, invalidated reqs > 0, invalidated imps > 0, invalidated resps > 0", 334 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 335 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}). 336 AddRow("req-1", "true", "request"). 337 AddRow("imp-1", "true", "imp"). 338 AddRow("resps-1", "true", "response"). 339 AddRow("req-2", "", "request"). 340 AddRow("imp-2", "", "imp"). 341 AddRow("resps-2", "", "response"), 342 wantLastUpdate: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 343 wantSavedReqs: map[string]json.RawMessage{"req-1": json.RawMessage(`true`)}, 344 wantSavedImps: map[string]json.RawMessage{"imp-1": json.RawMessage(`true`)}, 345 wantSavedResps: map[string]json.RawMessage{"resps-1": json.RawMessage(`true`)}, 346 wantInvalidatedReqs: []string{"req-2"}, 347 wantInvalidatedImps: []string{"imp-2"}, 348 wantInvalidatedResps: []string{"resps-2"}, 349 }, 350 } 351 352 for _, tt := range tests { 353 provider, dbMock, _ := db_provider.NewDbProviderMock() 354 dbMock.ExpectQuery(fakeQueryRegex()).WillReturnRows(tt.giveMockRows) 355 356 metricsMock := &metrics.MetricsEngineMock{} 357 metricsMock.Mock.On("RecordStoredDataFetchTime", metrics.StoredDataLabels{ 358 DataType: metrics.RequestDataType, 359 DataFetchType: metrics.FetchDelta, 360 }, mock.Anything).Return() 361 362 eventProducer := NewDatabaseEventProducer(DatabaseEventProducerConfig{ 363 Provider: provider, 364 RequestType: config.RequestDataType, 365 CacheUpdateTimeout: 100 * time.Millisecond, 366 CacheUpdateQuery: fakeQuery, 367 MetricsEngine: metricsMock, 368 }) 369 eventProducer.lastUpdate = time.Date(2020, time.June, 30, 6, 0, 0, 0, time.UTC) 370 eventProducer.time = &FakeTime{time: tt.giveFakeTime} 371 err := eventProducer.Run() 372 373 assert.Nil(t, err, tt.description) 374 assert.Equal(t, tt.wantLastUpdate, eventProducer.lastUpdate, tt.description) 375 376 var saves events.Save 377 // Read data from saves channel with timeout to avoid test suite deadlock 378 select { 379 case saves = <-eventProducer.Saves(): 380 case <-time.After(20 * time.Millisecond): 381 } 382 var invalidations events.Invalidation 383 // Read data from invalidations channel with timeout to avoid test suite deadlock 384 select { 385 case invalidations = <-eventProducer.Invalidations(): 386 case <-time.After(20 * time.Millisecond): 387 } 388 389 assert.Equal(t, tt.wantSavedReqs, saves.Requests, tt.description) 390 assert.Equal(t, tt.wantSavedImps, saves.Imps, tt.description) 391 assert.Equal(t, tt.wantSavedResps, saves.Responses, tt.description) 392 assert.Equal(t, tt.wantInvalidatedReqs, invalidations.Requests, tt.description) 393 assert.Equal(t, tt.wantInvalidatedImps, invalidations.Imps, tt.description) 394 assert.Equal(t, tt.wantInvalidatedResps, invalidations.Responses, tt.description) 395 396 metricsMock.AssertExpectations(t) 397 } 398 } 399 400 func TestFetchDeltaErrors(t *testing.T) { 401 tests := []struct { 402 description string 403 giveFakeTime time.Time 404 giveTimeoutMS int 405 giveLastUpdate time.Time 406 giveMockRows *sqlmock.Rows 407 wantRecordedError metrics.StoredDataError 408 wantLastUpdate time.Time 409 }{ 410 { 411 description: "fetch delta timeout", 412 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 413 giveLastUpdate: time.Date(2020, time.June, 30, 6, 0, 0, 0, time.UTC), 414 giveMockRows: nil, 415 wantRecordedError: metrics.StoredDataErrorNetwork, 416 wantLastUpdate: time.Date(2020, time.June, 30, 6, 0, 0, 0, time.UTC), 417 }, 418 { 419 description: "fetch delta query error", 420 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 421 giveTimeoutMS: 100, 422 giveLastUpdate: time.Date(2020, time.June, 30, 6, 0, 0, 0, time.UTC), 423 giveMockRows: nil, 424 wantRecordedError: metrics.StoredDataErrorUndefined, 425 wantLastUpdate: time.Date(2020, time.June, 30, 6, 0, 0, 0, time.UTC), 426 }, 427 { 428 description: "fetch delta row error", 429 giveFakeTime: time.Date(2020, time.July, 1, 12, 30, 0, 0, time.UTC), 430 giveTimeoutMS: 100, 431 giveLastUpdate: time.Date(2020, time.June, 30, 6, 0, 0, 0, time.UTC), 432 giveMockRows: sqlmock.NewRows([]string{"id", "data", "dataType"}). 433 AddRow("stored-req-id", "true", "request"). 434 RowError(0, errors.New("Some row error.")), 435 wantRecordedError: metrics.StoredDataErrorUndefined, 436 wantLastUpdate: time.Date(2020, time.June, 30, 6, 0, 0, 0, time.UTC), 437 }, 438 } 439 440 for _, tt := range tests { 441 provider, dbMock, _ := db_provider.NewDbProviderMock() 442 if tt.giveMockRows == nil { 443 dbMock.ExpectQuery(fakeQueryRegex()).WillReturnError(errors.New("Query failed.")) 444 } else { 445 dbMock.ExpectQuery(fakeQueryRegex()).WillReturnRows(tt.giveMockRows) 446 } 447 448 metricsMock := &metrics.MetricsEngineMock{} 449 metricsMock.Mock.On("RecordStoredDataFetchTime", metrics.StoredDataLabels{ 450 DataType: metrics.RequestDataType, 451 DataFetchType: metrics.FetchDelta, 452 }, mock.Anything).Return() 453 metricsMock.Mock.On("RecordStoredDataError", metrics.StoredDataLabels{ 454 DataType: metrics.RequestDataType, 455 Error: tt.wantRecordedError, 456 }).Return() 457 458 eventProducer := NewDatabaseEventProducer(DatabaseEventProducerConfig{ 459 Provider: provider, 460 RequestType: config.RequestDataType, 461 CacheUpdateTimeout: time.Duration(tt.giveTimeoutMS) * time.Millisecond, 462 CacheUpdateQuery: fakeQuery, 463 MetricsEngine: metricsMock, 464 }) 465 eventProducer.lastUpdate = tt.giveLastUpdate 466 eventProducer.time = &FakeTime{time: tt.giveFakeTime} 467 err := eventProducer.Run() 468 469 assert.NotNil(t, err, tt.description) 470 assert.Equal(t, tt.wantLastUpdate, eventProducer.lastUpdate, tt.description) 471 472 var saves events.Save 473 // Read data from saves channel with timeout to avoid test suite deadlock 474 select { 475 case saves = <-eventProducer.Saves(): 476 case <-time.After(10 * time.Millisecond): 477 } 478 var invalidations events.Invalidation 479 // Read data from invalidations channel with timeout to avoid test suite deadlock 480 select { 481 case invalidations = <-eventProducer.Invalidations(): 482 case <-time.After(10 * time.Millisecond): 483 } 484 485 assert.Nil(t, saves.Requests, tt.description) 486 assert.Nil(t, saves.Imps, tt.description) 487 assert.Nil(t, saves.Responses, tt.description) 488 assert.Nil(t, invalidations.Requests, tt.description) 489 assert.Nil(t, invalidations.Imps, tt.description) 490 assert.Nil(t, invalidations.Responses, tt.description) 491 492 metricsMock.AssertExpectations(t) 493 } 494 }