github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/store/storetest/job_store.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package storetest 5 6 import ( 7 "testing" 8 9 "time" 10 11 "github.com/mattermost/mattermost-server/v5/model" 12 "github.com/mattermost/mattermost-server/v5/store" 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 ) 16 17 func TestJobStore(t *testing.T, ss store.Store) { 18 t.Run("JobSaveGet", func(t *testing.T) { testJobSaveGet(t, ss) }) 19 t.Run("JobGetAllByType", func(t *testing.T) { testJobGetAllByType(t, ss) }) 20 t.Run("JobGetAllByTypePage", func(t *testing.T) { testJobGetAllByTypePage(t, ss) }) 21 t.Run("JobGetAllPage", func(t *testing.T) { testJobGetAllPage(t, ss) }) 22 t.Run("JobGetAllByStatus", func(t *testing.T) { testJobGetAllByStatus(t, ss) }) 23 t.Run("GetNewestJobByStatusAndType", func(t *testing.T) { testJobStoreGetNewestJobByStatusAndType(t, ss) }) 24 t.Run("GetCountByStatusAndType", func(t *testing.T) { testJobStoreGetCountByStatusAndType(t, ss) }) 25 t.Run("JobUpdateOptimistically", func(t *testing.T) { testJobUpdateOptimistically(t, ss) }) 26 t.Run("JobUpdateStatusUpdateStatusOptimistically", func(t *testing.T) { testJobUpdateStatusUpdateStatusOptimistically(t, ss) }) 27 t.Run("JobDelete", func(t *testing.T) { testJobDelete(t, ss) }) 28 } 29 30 func testJobSaveGet(t *testing.T, ss store.Store) { 31 job := &model.Job{ 32 Id: model.NewId(), 33 Type: model.NewId(), 34 Status: model.NewId(), 35 Data: map[string]string{ 36 "Processed": "0", 37 "Total": "12345", 38 "LastProcessed": "abcd", 39 }, 40 } 41 42 _, err := ss.Job().Save(job) 43 require.Nil(t, err) 44 45 defer ss.Job().Delete(job.Id) 46 47 received, err := ss.Job().Get(job.Id) 48 require.Nil(t, err) 49 require.Equal(t, job.Id, received.Id, "received incorrect job after save") 50 require.Equal(t, "12345", received.Data["Total"]) 51 } 52 53 func testJobGetAllByType(t *testing.T, ss store.Store) { 54 jobType := model.NewId() 55 56 jobs := []*model.Job{ 57 { 58 Id: model.NewId(), 59 Type: jobType, 60 }, 61 { 62 Id: model.NewId(), 63 Type: jobType, 64 }, 65 { 66 Id: model.NewId(), 67 Type: model.NewId(), 68 }, 69 } 70 71 for _, job := range jobs { 72 _, err := ss.Job().Save(job) 73 require.Nil(t, err) 74 defer ss.Job().Delete(job.Id) 75 } 76 77 received, err := ss.Job().GetAllByType(jobType) 78 require.Nil(t, err) 79 require.Len(t, received, 2) 80 require.ElementsMatch(t, []string{jobs[0].Id, jobs[1].Id}, []string{received[0].Id, received[1].Id}) 81 } 82 83 func testJobGetAllByTypePage(t *testing.T, ss store.Store) { 84 jobType := model.NewId() 85 86 jobs := []*model.Job{ 87 { 88 Id: model.NewId(), 89 Type: jobType, 90 CreateAt: 1000, 91 }, 92 { 93 Id: model.NewId(), 94 Type: jobType, 95 CreateAt: 999, 96 }, 97 { 98 Id: model.NewId(), 99 Type: jobType, 100 CreateAt: 1001, 101 }, 102 { 103 Id: model.NewId(), 104 Type: model.NewId(), 105 CreateAt: 1002, 106 }, 107 } 108 109 for _, job := range jobs { 110 _, err := ss.Job().Save(job) 111 require.Nil(t, err) 112 defer ss.Job().Delete(job.Id) 113 } 114 115 received, err := ss.Job().GetAllByTypePage(jobType, 0, 2) 116 require.Nil(t, err) 117 require.Len(t, received, 2) 118 require.Equal(t, received[0].Id, jobs[2].Id, "should've received newest job first") 119 require.Equal(t, received[1].Id, jobs[0].Id, "should've received second newest job second") 120 121 received, err = ss.Job().GetAllByTypePage(jobType, 2, 2) 122 require.Nil(t, err) 123 require.Len(t, received, 1) 124 require.Equal(t, received[0].Id, jobs[1].Id, "should've received oldest job last") 125 } 126 127 func testJobGetAllPage(t *testing.T, ss store.Store) { 128 jobType := model.NewId() 129 createAtTime := model.GetMillis() 130 131 jobs := []*model.Job{ 132 { 133 Id: model.NewId(), 134 Type: jobType, 135 CreateAt: createAtTime + 1, 136 }, 137 { 138 Id: model.NewId(), 139 Type: jobType, 140 CreateAt: createAtTime, 141 }, 142 { 143 Id: model.NewId(), 144 Type: jobType, 145 CreateAt: createAtTime + 2, 146 }, 147 } 148 149 for _, job := range jobs { 150 _, err := ss.Job().Save(job) 151 require.Nil(t, err) 152 defer ss.Job().Delete(job.Id) 153 } 154 155 received, err := ss.Job().GetAllPage(0, 2) 156 require.Nil(t, err) 157 require.Len(t, received, 2) 158 require.Equal(t, received[0].Id, jobs[2].Id, "should've received newest job first") 159 require.Equal(t, received[1].Id, jobs[0].Id, "should've received second newest job second") 160 161 received, err = ss.Job().GetAllPage(2, 2) 162 require.Nil(t, err) 163 require.NotEmpty(t, received) 164 require.Equal(t, received[0].Id, jobs[1].Id, "should've received oldest job last") 165 } 166 167 func testJobGetAllByStatus(t *testing.T, ss store.Store) { 168 jobType := model.NewId() 169 status := model.NewId() 170 171 jobs := []*model.Job{ 172 { 173 Id: model.NewId(), 174 Type: jobType, 175 CreateAt: 1000, 176 Status: status, 177 Data: map[string]string{ 178 "test": "data", 179 }, 180 }, 181 { 182 Id: model.NewId(), 183 Type: jobType, 184 CreateAt: 999, 185 Status: status, 186 }, 187 { 188 Id: model.NewId(), 189 Type: jobType, 190 CreateAt: 1001, 191 Status: status, 192 }, 193 { 194 Id: model.NewId(), 195 Type: jobType, 196 CreateAt: 1002, 197 Status: model.NewId(), 198 }, 199 } 200 201 for _, job := range jobs { 202 _, err := ss.Job().Save(job) 203 require.Nil(t, err) 204 defer ss.Job().Delete(job.Id) 205 } 206 207 received, err := ss.Job().GetAllByStatus(status) 208 require.Nil(t, err) 209 require.Len(t, received, 3) 210 require.Equal(t, received[0].Id, jobs[1].Id) 211 require.Equal(t, received[1].Id, jobs[0].Id) 212 require.Equal(t, received[2].Id, jobs[2].Id) 213 require.Equal(t, "data", received[1].Data["test"], "should've received job data field back as saved") 214 } 215 216 func testJobStoreGetNewestJobByStatusAndType(t *testing.T, ss store.Store) { 217 jobType1 := model.NewId() 218 jobType2 := model.NewId() 219 status1 := model.NewId() 220 status2 := model.NewId() 221 222 jobs := []*model.Job{ 223 { 224 Id: model.NewId(), 225 Type: jobType1, 226 CreateAt: 1001, 227 Status: status1, 228 }, 229 { 230 Id: model.NewId(), 231 Type: jobType1, 232 CreateAt: 1000, 233 Status: status1, 234 }, 235 { 236 Id: model.NewId(), 237 Type: jobType2, 238 CreateAt: 1003, 239 Status: status1, 240 }, 241 { 242 Id: model.NewId(), 243 Type: jobType1, 244 CreateAt: 1004, 245 Status: status2, 246 }, 247 } 248 249 for _, job := range jobs { 250 _, err := ss.Job().Save(job) 251 require.Nil(t, err) 252 defer ss.Job().Delete(job.Id) 253 } 254 255 received, err := ss.Job().GetNewestJobByStatusAndType(status1, jobType1) 256 assert.Nil(t, err) 257 assert.EqualValues(t, jobs[0].Id, received.Id) 258 259 received, err = ss.Job().GetNewestJobByStatusAndType(model.NewId(), model.NewId()) 260 assert.Nil(t, err) 261 assert.Nil(t, received) 262 } 263 264 func testJobStoreGetCountByStatusAndType(t *testing.T, ss store.Store) { 265 jobType1 := model.NewId() 266 jobType2 := model.NewId() 267 status1 := model.NewId() 268 status2 := model.NewId() 269 270 jobs := []*model.Job{ 271 { 272 Id: model.NewId(), 273 Type: jobType1, 274 CreateAt: 1000, 275 Status: status1, 276 }, 277 { 278 Id: model.NewId(), 279 Type: jobType1, 280 CreateAt: 999, 281 Status: status1, 282 }, 283 { 284 Id: model.NewId(), 285 Type: jobType2, 286 CreateAt: 1001, 287 Status: status1, 288 }, 289 { 290 Id: model.NewId(), 291 Type: jobType1, 292 CreateAt: 1002, 293 Status: status2, 294 }, 295 } 296 297 for _, job := range jobs { 298 _, err := ss.Job().Save(job) 299 require.Nil(t, err) 300 defer ss.Job().Delete(job.Id) 301 } 302 303 count, err := ss.Job().GetCountByStatusAndType(status1, jobType1) 304 assert.Nil(t, err) 305 assert.EqualValues(t, 2, count) 306 307 count, err = ss.Job().GetCountByStatusAndType(status2, jobType2) 308 assert.Nil(t, err) 309 assert.EqualValues(t, 0, count) 310 311 count, err = ss.Job().GetCountByStatusAndType(status1, jobType2) 312 assert.Nil(t, err) 313 assert.EqualValues(t, 1, count) 314 315 count, err = ss.Job().GetCountByStatusAndType(status2, jobType1) 316 assert.Nil(t, err) 317 assert.EqualValues(t, 1, count) 318 } 319 320 func testJobUpdateOptimistically(t *testing.T, ss store.Store) { 321 job := &model.Job{ 322 Id: model.NewId(), 323 Type: model.JOB_TYPE_DATA_RETENTION, 324 CreateAt: model.GetMillis(), 325 Status: model.JOB_STATUS_PENDING, 326 } 327 328 _, err := ss.Job().Save(job) 329 require.Nil(t, err) 330 defer ss.Job().Delete(job.Id) 331 332 job.LastActivityAt = model.GetMillis() 333 job.Status = model.JOB_STATUS_IN_PROGRESS 334 job.Progress = 50 335 job.Data = map[string]string{ 336 "Foo": "Bar", 337 } 338 339 updated, err := ss.Job().UpdateOptimistically(job, model.JOB_STATUS_SUCCESS) 340 require.False(t, err != nil && updated) 341 342 time.Sleep(2 * time.Millisecond) 343 344 updated, err = ss.Job().UpdateOptimistically(job, model.JOB_STATUS_PENDING) 345 require.Nil(t, err) 346 require.True(t, updated) 347 348 updatedJob, err := ss.Job().Get(job.Id) 349 require.Nil(t, err) 350 351 require.Equal(t, updatedJob.Type, job.Type) 352 require.Equal(t, updatedJob.CreateAt, job.CreateAt) 353 require.Equal(t, updatedJob.Status, job.Status) 354 require.Greater(t, updatedJob.LastActivityAt, job.LastActivityAt) 355 require.Equal(t, updatedJob.Progress, job.Progress) 356 require.Equal(t, updatedJob.Data["Foo"], job.Data["Foo"]) 357 } 358 359 func testJobUpdateStatusUpdateStatusOptimistically(t *testing.T, ss store.Store) { 360 job := &model.Job{ 361 Id: model.NewId(), 362 Type: model.JOB_TYPE_DATA_RETENTION, 363 CreateAt: model.GetMillis(), 364 Status: model.JOB_STATUS_SUCCESS, 365 } 366 367 var lastUpdateAt int64 368 received, err := ss.Job().Save(job) 369 require.Nil(t, err) 370 lastUpdateAt = received.LastActivityAt 371 372 defer ss.Job().Delete(job.Id) 373 374 time.Sleep(2 * time.Millisecond) 375 376 received, err = ss.Job().UpdateStatus(job.Id, model.JOB_STATUS_PENDING) 377 require.Nil(t, err) 378 379 require.Equal(t, model.JOB_STATUS_PENDING, received.Status) 380 require.Greater(t, received.LastActivityAt, lastUpdateAt) 381 lastUpdateAt = received.LastActivityAt 382 383 time.Sleep(2 * time.Millisecond) 384 385 updated, err := ss.Job().UpdateStatusOptimistically(job.Id, model.JOB_STATUS_IN_PROGRESS, model.JOB_STATUS_SUCCESS) 386 require.Nil(t, err) 387 require.False(t, updated) 388 389 received, err = ss.Job().Get(job.Id) 390 require.Nil(t, err) 391 392 require.Equal(t, model.JOB_STATUS_PENDING, received.Status) 393 require.Equal(t, received.LastActivityAt, lastUpdateAt) 394 395 time.Sleep(2 * time.Millisecond) 396 397 updated, err = ss.Job().UpdateStatusOptimistically(job.Id, model.JOB_STATUS_PENDING, model.JOB_STATUS_IN_PROGRESS) 398 require.Nil(t, err) 399 require.True(t, updated, "should have succeeded") 400 401 var startAtSet int64 402 received, err = ss.Job().Get(job.Id) 403 require.Nil(t, err) 404 require.Equal(t, model.JOB_STATUS_IN_PROGRESS, received.Status) 405 require.NotEqual(t, 0, received.StartAt) 406 require.Greater(t, received.LastActivityAt, lastUpdateAt) 407 lastUpdateAt = received.LastActivityAt 408 startAtSet = received.StartAt 409 410 time.Sleep(2 * time.Millisecond) 411 412 updated, err = ss.Job().UpdateStatusOptimistically(job.Id, model.JOB_STATUS_IN_PROGRESS, model.JOB_STATUS_SUCCESS) 413 require.Nil(t, err) 414 require.True(t, updated, "should have succeeded") 415 416 received, err = ss.Job().Get(job.Id) 417 require.Nil(t, err) 418 require.Equal(t, model.JOB_STATUS_SUCCESS, received.Status) 419 require.Equal(t, startAtSet, received.StartAt) 420 require.Greater(t, received.LastActivityAt, lastUpdateAt) 421 } 422 423 func testJobDelete(t *testing.T, ss store.Store) { 424 job, err := ss.Job().Save(&model.Job{Id: model.NewId()}) 425 require.Nil(t, err) 426 427 _, err = ss.Job().Delete(job.Id) 428 assert.Nil(t, err) 429 }