Introduce jobs command

This commit is contained in:
Chocobozzz 2021-07-07 09:34:56 +02:00
parent c3d29f694b
commit 9c6327f803
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
8 changed files with 75 additions and 98 deletions

View File

@ -10,7 +10,6 @@ import {
closeAllSequelize, closeAllSequelize,
completeVideoCheck, completeVideoCheck,
flushAndRunMultipleServers, flushAndRunMultipleServers,
getJobsListPaginationAndSort,
getVideo, getVideo,
getVideoCommentThreads, getVideoCommentThreads,
getVideosList, getVideosList,
@ -181,15 +180,13 @@ describe('Test handle downs', function () {
const states: JobState[] = [ 'waiting', 'active' ] const states: JobState[] = [ 'waiting', 'active' ]
for (const state of states) { for (const state of states) {
const res = await getJobsListPaginationAndSort({ const body = await servers[0].jobsCommand.getJobsList({
url: servers[0].url,
accessToken: servers[0].accessToken,
state: state, state: state,
start: 0, start: 0,
count: 50, count: 50,
sort: '-createdAt' sort: '-createdAt'
}) })
expect(res.body.data).to.have.length(0) expect(body.data).to.have.length(0)
} }
}) })

View File

@ -2,13 +2,16 @@
import 'mocha' import 'mocha'
import * as chai from 'chai' import * as chai from 'chai'
import { cleanupTests, ServerInfo, setAccessTokensToServers } from '../../../../shared/extra-utils/index' import {
import { dateIsValid } from '../../../../shared/extra-utils/miscs/miscs' cleanupTests,
import { doubleFollow } from '../../../../shared/extra-utils/server/follows' dateIsValid,
import { getJobsList, getJobsListPaginationAndSort, waitJobs } from '../../../../shared/extra-utils/server/jobs' doubleFollow,
import { flushAndRunMultipleServers } from '../../../../shared/extra-utils/server/servers' flushAndRunMultipleServers,
import { uploadVideo } from '../../../../shared/extra-utils/videos/videos' ServerInfo,
import { Job } from '../../../../shared/models/server' setAccessTokensToServers,
uploadVideo,
waitJobs
} from '@shared/extra-utils'
const expect = chai.expect const expect = chai.expect
@ -36,27 +39,25 @@ describe('Test jobs', function () {
}) })
it('Should list jobs', async function () { it('Should list jobs', async function () {
const res = await getJobsList(servers[1].url, servers[1].accessToken, 'completed') const body = await servers[1].jobsCommand.getJobsList({ state: 'completed' })
expect(res.body.total).to.be.above(2) expect(body.total).to.be.above(2)
expect(res.body.data).to.have.length.above(2) expect(body.data).to.have.length.above(2)
}) })
it('Should list jobs with sort, pagination and job type', async function () { it('Should list jobs with sort, pagination and job type', async function () {
{ {
const res = await getJobsListPaginationAndSort({ const body = await servers[1].jobsCommand.getJobsList({
url: servers[1].url,
accessToken: servers[1].accessToken,
state: 'completed', state: 'completed',
start: 1, start: 1,
count: 2, count: 2,
sort: 'createdAt' sort: 'createdAt'
}) })
expect(res.body.total).to.be.above(2) expect(body.total).to.be.above(2)
expect(res.body.data).to.have.lengthOf(2) expect(body.data).to.have.lengthOf(2)
let job: Job = res.body.data[0] let job = body.data[0]
// Skip repeat jobs // Skip repeat jobs
if (job.type === 'videos-views') job = res.body.data[1] if (job.type === 'videos-views') job = body.data[1]
expect(job.state).to.equal('completed') expect(job.state).to.equal('completed')
expect(job.type.startsWith('activitypub-')).to.be.true expect(job.type.startsWith('activitypub-')).to.be.true
@ -66,29 +67,26 @@ describe('Test jobs', function () {
} }
{ {
const res = await getJobsListPaginationAndSort({ const body = await servers[1].jobsCommand.getJobsList({
url: servers[1].url,
accessToken: servers[1].accessToken,
state: 'completed', state: 'completed',
start: 0, start: 0,
count: 100, count: 100,
sort: 'createdAt', sort: 'createdAt',
jobType: 'activitypub-http-broadcast' jobType: 'activitypub-http-broadcast'
}) })
expect(res.body.total).to.be.above(2) expect(body.total).to.be.above(2)
for (const j of res.body.data as Job[]) { for (const j of body.data) {
expect(j.type).to.equal('activitypub-http-broadcast') expect(j.type).to.equal('activitypub-http-broadcast')
} }
} }
}) })
it('Should list all jobs', async function () { it('Should list all jobs', async function () {
const res = await getJobsList(servers[1].url, servers[1].accessToken) const body = await servers[1].jobsCommand.getJobsList()
expect(body.total).to.be.above(2)
const jobs = res.body.data as Job[] const jobs = body.data
expect(res.body.total).to.be.above(2)
expect(jobs).to.have.length.above(2) expect(jobs).to.have.length.above(2)
// We know there are a least 1 delayed job (video views) and 1 completed job (broadcast) // We know there are a least 1 delayed job (video views) and 1 completed job (broadcast)

View File

@ -16,7 +16,6 @@ import {
flushAndRunMultipleServers, flushAndRunMultipleServers,
generateHighBitrateVideo, generateHighBitrateVideo,
generateVideoWithFramerate, generateVideoWithFramerate,
getJobsListPaginationAndSort,
getMyVideos, getMyVideos,
getServerFileSize, getServerFileSize,
getVideo, getVideo,
@ -709,17 +708,14 @@ describe('Test video transcoding', function () {
describe('Transcoding job queue', function () { describe('Transcoding job queue', function () {
it('Should have the appropriate priorities for transcoding jobs', async function () { it('Should have the appropriate priorities for transcoding jobs', async function () {
const res = await getJobsListPaginationAndSort({ const body = await servers[1].jobsCommand.getJobsList({
url: servers[1].url,
accessToken: servers[1].accessToken,
start: 0, start: 0,
count: 100, count: 100,
sort: '-createdAt', sort: '-createdAt',
jobType: 'video-transcoding' jobType: 'video-transcoding'
}) })
const jobs = res.body.data as Job[] const jobs = body.data
const transcodingJobs = jobs.filter(j => j.data.videoUUID === video4k) const transcodingJobs = jobs.filter(j => j.data.videoUUID === video4k)
expect(transcodingJobs).to.have.lengthOf(14) expect(transcodingJobs).to.have.lengthOf(14)

View File

@ -15,7 +15,6 @@ export * from './requests/requests'
export * from './server/clients' export * from './server/clients'
export * from './server/config' export * from './server/config'
export * from './server/jobs'
export * from './server/plugins' export * from './server/plugins'
export * from './server/servers' export * from './server/servers'

View File

@ -2,3 +2,5 @@ export * from './contact-form-command'
export * from './debug-command' export * from './debug-command'
export * from './follows-command' export * from './follows-command'
export * from './follows' export * from './follows'
export * from './jobs'
export * from './jobs-command'

View File

@ -0,0 +1,35 @@
import { pick } from 'lodash'
import { HttpStatusCode } from '../../core-utils/miscs/http-error-codes'
import { Job, JobState, JobType, ResultList } from '../../models'
import { AbstractCommand, OverrideCommandOptions } from '../shared'
export class JobsCommand extends AbstractCommand {
getJobsList (options: OverrideCommandOptions & {
state?: JobState
jobType?: JobType
start?: number
count?: number
sort?: string
} = {}) {
const path = this.buildJobsUrl(options.state)
const query = pick(options, [ 'start', 'count', 'sort', 'jobType' ])
return this.getRequestBody<ResultList<Job>>({
...options,
path,
query,
defaultExpectedStatus: HttpStatusCode.OK_200
})
}
private buildJobsUrl (state?: JobState) {
let path = '/api/v1/jobs'
if (state) path += '/' + state
return path
}
}

View File

@ -1,57 +1,8 @@
import * as request from 'supertest'
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' import { JobState } from '../../models'
import { makeGetRequest } from '../../../shared/extra-utils'
import { Job, JobState, JobType } from '../../models'
import { wait } from '../miscs/miscs' import { wait } from '../miscs/miscs'
import { ServerInfo } from './servers' import { ServerInfo } from './servers'
function buildJobsUrl (state?: JobState) {
let path = '/api/v1/jobs'
if (state) path += '/' + state
return path
}
function getJobsList (url: string, accessToken: string, state?: JobState) {
const path = buildJobsUrl(state)
return request(url)
.get(path)
.set('Accept', 'application/json')
.set('Authorization', 'Bearer ' + accessToken)
.expect(HttpStatusCode.OK_200)
.expect('Content-Type', /json/)
}
function getJobsListPaginationAndSort (options: {
url: string
accessToken: string
start: number
count: number
sort: string
state?: JobState
jobType?: JobType
}) {
const { url, accessToken, state, start, count, sort, jobType } = options
const path = buildJobsUrl(state)
const query = {
start,
count,
sort,
jobType
}
return makeGetRequest({
url,
path,
token: accessToken,
statusCodeExpected: HttpStatusCode.OK_200,
query
})
}
async function waitJobs (serversArg: ServerInfo[] | ServerInfo) { async function waitJobs (serversArg: ServerInfo[] | ServerInfo) {
const pendingJobWait = process.env.NODE_PENDING_JOB_WAIT const pendingJobWait = process.env.NODE_PENDING_JOB_WAIT
? parseInt(process.env.NODE_PENDING_JOB_WAIT, 10) ? parseInt(process.env.NODE_PENDING_JOB_WAIT, 10)
@ -72,15 +23,13 @@ async function waitJobs (serversArg: ServerInfo[] | ServerInfo) {
// Check if each server has pending request // Check if each server has pending request
for (const server of servers) { for (const server of servers) {
for (const state of states) { for (const state of states) {
const p = getJobsListPaginationAndSort({ const p = server.jobsCommand.getJobsList({
url: server.url, state,
accessToken: server.accessToken,
state: state,
start: 0, start: 0,
count: 10, count: 10,
sort: '-createdAt' sort: '-createdAt'
}).then(res => res.body.data) }).then(body => body.data)
.then((jobs: Job[]) => jobs.filter(j => !repeatableJobs.includes(j.type))) .then(jobs => jobs.filter(j => !repeatableJobs.includes(j.type)))
.then(jobs => { .then(jobs => {
if (jobs.length !== 0) { if (jobs.length !== 0) {
pendingRequests = true pendingRequests = true
@ -122,7 +71,5 @@ async function waitJobs (serversArg: ServerInfo[] | ServerInfo) {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
export { export {
getJobsList, waitJobs
waitJobs,
getJobsListPaginationAndSort
} }

View File

@ -19,6 +19,7 @@ import { SearchCommand } from '../search'
import { ContactFormCommand } from './contact-form-command' import { ContactFormCommand } from './contact-form-command'
import { DebugCommand } from './debug-command' import { DebugCommand } from './debug-command'
import { FollowsCommand } from './follows-command' import { FollowsCommand } from './follows-command'
import { JobsCommand } from './jobs-command'
interface ServerInfo { interface ServerInfo {
app: ChildProcess app: ChildProcess
@ -83,6 +84,7 @@ interface ServerInfo {
contactFormCommand?: ContactFormCommand contactFormCommand?: ContactFormCommand
debugCommand?: DebugCommand debugCommand?: DebugCommand
followsCommand?: FollowsCommand followsCommand?: FollowsCommand
jobsCommand?: JobsCommand
} }
function parallelTests () { function parallelTests () {
@ -299,6 +301,7 @@ async function runServer (server: ServerInfo, configOverrideArg?: any, args = []
server.contactFormCommand = new ContactFormCommand(server) server.contactFormCommand = new ContactFormCommand(server)
server.debugCommand = new DebugCommand(server) server.debugCommand = new DebugCommand(server)
server.followsCommand = new FollowsCommand(server) server.followsCommand = new FollowsCommand(server)
server.jobsCommand = new JobsCommand(server)
res(server) res(server)
}) })