github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/api4/job_test.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package api4 5 6 import ( 7 "os" 8 "path/filepath" 9 "strings" 10 "testing" 11 12 "github.com/stretchr/testify/require" 13 14 "github.com/masterhung0112/hk_server/v5/model" 15 ) 16 17 func TestCreateJob(t *testing.T) { 18 th := Setup(t) 19 defer th.TearDown() 20 21 job := &model.Job{ 22 Type: model.JOB_TYPE_MESSAGE_EXPORT, 23 Data: map[string]string{ 24 "thing": "stuff", 25 }, 26 } 27 28 _, resp := th.SystemManagerClient.CreateJob(job) 29 CheckForbiddenStatus(t, resp) 30 31 received, resp := th.SystemAdminClient.CreateJob(job) 32 require.Nil(t, resp.Error) 33 34 defer th.App.Srv().Store.Job().Delete(received.Id) 35 36 job = &model.Job{ 37 Type: model.NewId(), 38 } 39 40 _, resp = th.SystemAdminClient.CreateJob(job) 41 CheckBadRequestStatus(t, resp) 42 43 job.Type = model.JOB_TYPE_ELASTICSEARCH_POST_INDEXING 44 _, resp = th.Client.CreateJob(job) 45 CheckForbiddenStatus(t, resp) 46 } 47 48 func TestGetJob(t *testing.T) { 49 th := Setup(t) 50 defer th.TearDown() 51 52 job := &model.Job{ 53 Id: model.NewId(), 54 Status: model.JOB_STATUS_PENDING, 55 Type: model.JOB_TYPE_MESSAGE_EXPORT, 56 } 57 _, err := th.App.Srv().Store.Job().Save(job) 58 require.NoError(t, err) 59 60 defer th.App.Srv().Store.Job().Delete(job.Id) 61 62 received, resp := th.SystemAdminClient.GetJob(job.Id) 63 require.Nil(t, resp.Error) 64 65 require.Equal(t, job.Id, received.Id, "incorrect job received") 66 require.Equal(t, job.Status, received.Status, "incorrect job received") 67 68 _, resp = th.SystemAdminClient.GetJob("1234") 69 CheckBadRequestStatus(t, resp) 70 71 _, resp = th.Client.GetJob(job.Id) 72 CheckForbiddenStatus(t, resp) 73 74 _, resp = th.SystemAdminClient.GetJob(model.NewId()) 75 CheckNotFoundStatus(t, resp) 76 } 77 78 func TestGetJobs(t *testing.T) { 79 th := Setup(t) 80 defer th.TearDown() 81 82 jobType := model.JOB_TYPE_DATA_RETENTION 83 84 t0 := model.GetMillis() 85 jobs := []*model.Job{ 86 { 87 Id: model.NewId(), 88 Type: jobType, 89 CreateAt: t0 + 1, 90 }, 91 { 92 Id: model.NewId(), 93 Type: jobType, 94 CreateAt: t0, 95 }, 96 { 97 Id: model.NewId(), 98 Type: jobType, 99 CreateAt: t0 + 2, 100 }, 101 } 102 103 for _, job := range jobs { 104 _, err := th.App.Srv().Store.Job().Save(job) 105 require.NoError(t, err) 106 defer th.App.Srv().Store.Job().Delete(job.Id) 107 } 108 109 received, resp := th.SystemAdminClient.GetJobs(0, 2) 110 require.Nil(t, resp.Error) 111 112 require.Len(t, received, 2, "received wrong number of jobs") 113 require.Equal(t, jobs[2].Id, received[0].Id, "should've received newest job first") 114 require.Equal(t, jobs[0].Id, received[1].Id, "should've received second newest job second") 115 116 received, resp = th.SystemAdminClient.GetJobs(1, 2) 117 require.Nil(t, resp.Error) 118 119 require.Equal(t, jobs[1].Id, received[0].Id, "should've received oldest job last") 120 121 _, resp = th.Client.GetJobs(0, 60) 122 CheckForbiddenStatus(t, resp) 123 } 124 125 func TestGetJobsByType(t *testing.T) { 126 th := Setup(t) 127 defer th.TearDown() 128 129 jobType := model.JOB_TYPE_DATA_RETENTION 130 131 jobs := []*model.Job{ 132 { 133 Id: model.NewId(), 134 Type: jobType, 135 CreateAt: 1000, 136 }, 137 { 138 Id: model.NewId(), 139 Type: jobType, 140 CreateAt: 999, 141 }, 142 { 143 Id: model.NewId(), 144 Type: jobType, 145 CreateAt: 1001, 146 }, 147 { 148 Id: model.NewId(), 149 Type: model.NewId(), 150 CreateAt: 1002, 151 }, 152 } 153 154 for _, job := range jobs { 155 _, err := th.App.Srv().Store.Job().Save(job) 156 require.NoError(t, err) 157 defer th.App.Srv().Store.Job().Delete(job.Id) 158 } 159 160 received, resp := th.SystemAdminClient.GetJobsByType(jobType, 0, 2) 161 require.Nil(t, resp.Error) 162 163 require.Len(t, received, 2, "received wrong number of jobs") 164 require.Equal(t, jobs[2].Id, received[0].Id, "should've received newest job first") 165 require.Equal(t, jobs[0].Id, received[1].Id, "should've received second newest job second") 166 167 received, resp = th.SystemAdminClient.GetJobsByType(jobType, 1, 2) 168 require.Nil(t, resp.Error) 169 170 require.Len(t, received, 1, "received wrong number of jobs") 171 require.Equal(t, jobs[1].Id, received[0].Id, "should've received oldest job last") 172 173 _, resp = th.SystemAdminClient.GetJobsByType("", 0, 60) 174 CheckNotFoundStatus(t, resp) 175 176 _, resp = th.SystemAdminClient.GetJobsByType(strings.Repeat("a", 33), 0, 60) 177 CheckBadRequestStatus(t, resp) 178 179 _, resp = th.Client.GetJobsByType(jobType, 0, 60) 180 CheckForbiddenStatus(t, resp) 181 182 _, resp = th.SystemManagerClient.GetJobsByType(model.JOB_TYPE_ELASTICSEARCH_POST_INDEXING, 0, 60) 183 require.Nil(t, resp.Error) 184 } 185 186 func TestDownloadJob(t *testing.T) { 187 th := Setup(t).InitBasic() 188 defer th.TearDown() 189 jobName := model.NewId() 190 job := &model.Job{ 191 Id: jobName, 192 Type: model.JOB_TYPE_MESSAGE_EXPORT, 193 Data: map[string]string{ 194 "export_type": "csv", 195 }, 196 Status: model.JOB_STATUS_SUCCESS, 197 } 198 199 // DownloadExportResults is not set to true so we should get a not implemented error status 200 _, resp := th.Client.DownloadJob(job.Id) 201 CheckNotImplementedStatus(t, resp) 202 203 th.App.UpdateConfig(func(cfg *model.Config) { 204 *cfg.MessageExportSettings.DownloadExportResults = true 205 }) 206 207 // Normal user cannot download the results of these job (non-existent job) 208 _, resp = th.Client.DownloadJob(job.Id) 209 CheckNotFoundStatus(t, resp) 210 211 // System admin trying to download the results of a non-existent job 212 _, resp = th.SystemAdminClient.DownloadJob(job.Id) 213 CheckNotFoundStatus(t, resp) 214 215 // Here we have a job that exist in our database but the results do not exist therefore when we try to download the results 216 // as a system admin, we should get a not found status. 217 _, err := th.App.Srv().Store.Job().Save(job) 218 require.NoError(t, err) 219 defer th.App.Srv().Store.Job().Delete(job.Id) 220 221 filePath := "./data/export/" + job.Id + "/testdat.txt" 222 mkdirAllErr := os.MkdirAll(filepath.Dir(filePath), 0770) 223 require.NoError(t, mkdirAllErr) 224 os.Create(filePath) 225 226 // Normal user cannot download the results of these job (not the right permission) 227 _, resp = th.Client.DownloadJob(job.Id) 228 CheckForbiddenStatus(t, resp) 229 230 // System manager with default permissions cannot download the results of these job (Doesn't have correct permissions) 231 _, resp = th.SystemManagerClient.DownloadJob(job.Id) 232 CheckForbiddenStatus(t, resp) 233 234 _, resp = th.SystemAdminClient.DownloadJob(job.Id) 235 CheckBadRequestStatus(t, resp) 236 237 job.Data["is_downloadable"] = "true" 238 updateStatus, err := th.App.Srv().Store.Job().UpdateOptimistically(job, model.JOB_STATUS_SUCCESS) 239 require.True(t, updateStatus) 240 require.NoError(t, err) 241 242 _, resp = th.SystemAdminClient.DownloadJob(job.Id) 243 CheckNotFoundStatus(t, resp) 244 245 // Now we stub the results of the job into the same directory and try to download it again 246 // This time we should successfully retrieve the results without any error 247 filePath = "./data/export/" + job.Id + ".zip" 248 mkdirAllErr = os.MkdirAll(filepath.Dir(filePath), 0770) 249 require.NoError(t, mkdirAllErr) 250 os.Create(filePath) 251 252 _, resp = th.SystemAdminClient.DownloadJob(job.Id) 253 require.Nil(t, resp.Error) 254 255 // Here we are creating a new job which doesn't have type of message export 256 jobName = model.NewId() 257 job = &model.Job{ 258 Id: jobName, 259 Type: model.JOB_TYPE_CLOUD, 260 Data: map[string]string{ 261 "export_type": "csv", 262 }, 263 Status: model.JOB_STATUS_SUCCESS, 264 } 265 _, err = th.App.Srv().Store.Job().Save(job) 266 require.NoError(t, err) 267 defer th.App.Srv().Store.Job().Delete(job.Id) 268 269 // System admin shouldn't be able to download since the job type is not message export 270 _, resp = th.SystemAdminClient.DownloadJob(job.Id) 271 CheckBadRequestStatus(t, resp) 272 } 273 274 func TestCancelJob(t *testing.T) { 275 th := Setup(t) 276 defer th.TearDown() 277 278 jobType := model.JOB_TYPE_MESSAGE_EXPORT 279 jobs := []*model.Job{ 280 { 281 Id: model.NewId(), 282 Type: jobType, 283 Status: model.JOB_STATUS_PENDING, 284 }, 285 { 286 Id: model.NewId(), 287 Type: jobType, 288 Status: model.JOB_STATUS_IN_PROGRESS, 289 }, 290 { 291 Id: model.NewId(), 292 Type: jobType, 293 Status: model.JOB_STATUS_SUCCESS, 294 }, 295 } 296 297 for _, job := range jobs { 298 _, err := th.App.Srv().Store.Job().Save(job) 299 require.NoError(t, err) 300 defer th.App.Srv().Store.Job().Delete(job.Id) 301 } 302 303 _, resp := th.Client.CancelJob(jobs[0].Id) 304 CheckForbiddenStatus(t, resp) 305 306 _, resp = th.SystemAdminClient.CancelJob(jobs[0].Id) 307 require.Nil(t, resp.Error) 308 309 _, resp = th.SystemAdminClient.CancelJob(jobs[1].Id) 310 require.Nil(t, resp.Error) 311 312 _, resp = th.SystemAdminClient.CancelJob(jobs[2].Id) 313 CheckInternalErrorStatus(t, resp) 314 315 _, resp = th.SystemAdminClient.CancelJob(model.NewId()) 316 CheckNotFoundStatus(t, resp) 317 }