Introduce jobs command
This commit is contained in:
parent
c3d29f694b
commit
9c6327f803
|
@ -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)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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'
|
||||||
|
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue