mirror of https://github.com/Chocobozzz/PeerTube
				
				
				
			
		
			
				
	
	
		
			374 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			TypeScript
		
	
	
			
		
		
	
	
			374 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			TypeScript
		
	
	
/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
 | 
						|
 | 
						|
import * as chai from 'chai'
 | 
						|
import 'mocha'
 | 
						|
import {
 | 
						|
  cleanupTests,
 | 
						|
  doubleFollow,
 | 
						|
  flushAndRunMultipleServers,
 | 
						|
  getLocalIdByUUID,
 | 
						|
  ServerInfo,
 | 
						|
  setAccessTokensToServers,
 | 
						|
  uploadVideo,
 | 
						|
  uploadVideoAndGetId,
 | 
						|
  waitUntilLog
 | 
						|
} from '../../../../shared/extra-utils'
 | 
						|
import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
 | 
						|
import { addVideoRedundancy, listVideoRedundancies, removeVideoRedundancy, updateRedundancy } from '@shared/extra-utils/server/redundancy'
 | 
						|
import { VideoPrivacy, VideoRedundanciesTarget, VideoRedundancy } from '@shared/models'
 | 
						|
 | 
						|
const expect = chai.expect
 | 
						|
 | 
						|
describe('Test manage videos redundancy', function () {
 | 
						|
  const targets: VideoRedundanciesTarget[] = [ 'my-videos', 'remote-videos' ]
 | 
						|
 | 
						|
  let servers: ServerInfo[]
 | 
						|
  let video1Server2UUID: string
 | 
						|
  let video2Server2UUID: string
 | 
						|
  let redundanciesToRemove: number[] = []
 | 
						|
 | 
						|
  before(async function () {
 | 
						|
    this.timeout(120000)
 | 
						|
 | 
						|
    const config = {
 | 
						|
      transcoding: {
 | 
						|
        hls: {
 | 
						|
          enabled: true
 | 
						|
        }
 | 
						|
      },
 | 
						|
      redundancy: {
 | 
						|
        videos: {
 | 
						|
          check_interval: '1 second',
 | 
						|
          strategies: [
 | 
						|
            {
 | 
						|
              strategy: 'recently-added',
 | 
						|
              min_lifetime: '1 hour',
 | 
						|
              size: '10MB',
 | 
						|
              min_views: 0
 | 
						|
            }
 | 
						|
          ]
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    servers = await flushAndRunMultipleServers(3, config)
 | 
						|
 | 
						|
    // Get the access tokens
 | 
						|
    await setAccessTokensToServers(servers)
 | 
						|
 | 
						|
    {
 | 
						|
      const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 1 server 2' })
 | 
						|
      video1Server2UUID = res.body.video.uuid
 | 
						|
    }
 | 
						|
 | 
						|
    {
 | 
						|
      const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 2 server 2' })
 | 
						|
      video2Server2UUID = res.body.video.uuid
 | 
						|
    }
 | 
						|
 | 
						|
    await waitJobs(servers)
 | 
						|
 | 
						|
    // Server 1 and server 2 follow each other
 | 
						|
    await doubleFollow(servers[0], servers[1])
 | 
						|
    await updateRedundancy(servers[0].url, servers[0].accessToken, servers[1].host, true)
 | 
						|
 | 
						|
    await waitJobs(servers)
 | 
						|
  })
 | 
						|
 | 
						|
  it('Should not have redundancies on server 3', async function () {
 | 
						|
    for (const target of targets) {
 | 
						|
      const res = await listVideoRedundancies({
 | 
						|
        url: servers[2].url,
 | 
						|
        accessToken: servers[2].accessToken,
 | 
						|
        target
 | 
						|
      })
 | 
						|
 | 
						|
      expect(res.body.total).to.equal(0)
 | 
						|
      expect(res.body.data).to.have.lengthOf(0)
 | 
						|
    }
 | 
						|
  })
 | 
						|
 | 
						|
  it('Should not have "remote-videos" redundancies on server 2', async function () {
 | 
						|
    this.timeout(120000)
 | 
						|
 | 
						|
    await waitJobs(servers)
 | 
						|
    await waitUntilLog(servers[0], 'Duplicated ', 10)
 | 
						|
    await waitJobs(servers)
 | 
						|
 | 
						|
    const res = await listVideoRedundancies({
 | 
						|
      url: servers[1].url,
 | 
						|
      accessToken: servers[1].accessToken,
 | 
						|
      target: 'remote-videos'
 | 
						|
    })
 | 
						|
 | 
						|
    expect(res.body.total).to.equal(0)
 | 
						|
    expect(res.body.data).to.have.lengthOf(0)
 | 
						|
  })
 | 
						|
 | 
						|
  it('Should have "my-videos" redundancies on server 2', async function () {
 | 
						|
    this.timeout(120000)
 | 
						|
 | 
						|
    const res = await listVideoRedundancies({
 | 
						|
      url: servers[1].url,
 | 
						|
      accessToken: servers[1].accessToken,
 | 
						|
      target: 'my-videos'
 | 
						|
    })
 | 
						|
 | 
						|
    expect(res.body.total).to.equal(2)
 | 
						|
 | 
						|
    const videos = res.body.data as VideoRedundancy[]
 | 
						|
    expect(videos).to.have.lengthOf(2)
 | 
						|
 | 
						|
    const videos1 = videos.find(v => v.uuid === video1Server2UUID)
 | 
						|
    const videos2 = videos.find(v => v.uuid === video2Server2UUID)
 | 
						|
 | 
						|
    expect(videos1.name).to.equal('video 1 server 2')
 | 
						|
    expect(videos2.name).to.equal('video 2 server 2')
 | 
						|
 | 
						|
    expect(videos1.redundancies.files).to.have.lengthOf(4)
 | 
						|
    expect(videos1.redundancies.streamingPlaylists).to.have.lengthOf(1)
 | 
						|
 | 
						|
    const redundancies = videos1.redundancies.files.concat(videos1.redundancies.streamingPlaylists)
 | 
						|
 | 
						|
    for (const r of redundancies) {
 | 
						|
      expect(r.strategy).to.be.null
 | 
						|
      expect(r.fileUrl).to.exist
 | 
						|
      expect(r.createdAt).to.exist
 | 
						|
      expect(r.updatedAt).to.exist
 | 
						|
      expect(r.expiresOn).to.exist
 | 
						|
    }
 | 
						|
  })
 | 
						|
 | 
						|
  it('Should not have "my-videos" redundancies on server 1', async function () {
 | 
						|
    const res = await listVideoRedundancies({
 | 
						|
      url: servers[0].url,
 | 
						|
      accessToken: servers[0].accessToken,
 | 
						|
      target: 'my-videos'
 | 
						|
    })
 | 
						|
 | 
						|
    expect(res.body.total).to.equal(0)
 | 
						|
    expect(res.body.data).to.have.lengthOf(0)
 | 
						|
  })
 | 
						|
 | 
						|
  it('Should have "remote-videos" redundancies on server 1', async function () {
 | 
						|
    this.timeout(120000)
 | 
						|
 | 
						|
    const res = await listVideoRedundancies({
 | 
						|
      url: servers[0].url,
 | 
						|
      accessToken: servers[0].accessToken,
 | 
						|
      target: 'remote-videos'
 | 
						|
    })
 | 
						|
 | 
						|
    expect(res.body.total).to.equal(2)
 | 
						|
 | 
						|
    const videos = res.body.data as VideoRedundancy[]
 | 
						|
    expect(videos).to.have.lengthOf(2)
 | 
						|
 | 
						|
    const videos1 = videos.find(v => v.uuid === video1Server2UUID)
 | 
						|
    const videos2 = videos.find(v => v.uuid === video2Server2UUID)
 | 
						|
 | 
						|
    expect(videos1.name).to.equal('video 1 server 2')
 | 
						|
    expect(videos2.name).to.equal('video 2 server 2')
 | 
						|
 | 
						|
    expect(videos1.redundancies.files).to.have.lengthOf(4)
 | 
						|
    expect(videos1.redundancies.streamingPlaylists).to.have.lengthOf(1)
 | 
						|
 | 
						|
    const redundancies = videos1.redundancies.files.concat(videos1.redundancies.streamingPlaylists)
 | 
						|
 | 
						|
    for (const r of redundancies) {
 | 
						|
      expect(r.strategy).to.equal('recently-added')
 | 
						|
      expect(r.fileUrl).to.exist
 | 
						|
      expect(r.createdAt).to.exist
 | 
						|
      expect(r.updatedAt).to.exist
 | 
						|
      expect(r.expiresOn).to.exist
 | 
						|
    }
 | 
						|
  })
 | 
						|
 | 
						|
  it('Should correctly paginate and sort results', async function () {
 | 
						|
    {
 | 
						|
      const res = await listVideoRedundancies({
 | 
						|
        url: servers[0].url,
 | 
						|
        accessToken: servers[0].accessToken,
 | 
						|
        target: 'remote-videos',
 | 
						|
        sort: 'name',
 | 
						|
        start: 0,
 | 
						|
        count: 2
 | 
						|
      })
 | 
						|
 | 
						|
      const videos = res.body.data
 | 
						|
      expect(videos[0].name).to.equal('video 1 server 2')
 | 
						|
      expect(videos[1].name).to.equal('video 2 server 2')
 | 
						|
    }
 | 
						|
 | 
						|
    {
 | 
						|
      const res = await listVideoRedundancies({
 | 
						|
        url: servers[0].url,
 | 
						|
        accessToken: servers[0].accessToken,
 | 
						|
        target: 'remote-videos',
 | 
						|
        sort: '-name',
 | 
						|
        start: 0,
 | 
						|
        count: 2
 | 
						|
      })
 | 
						|
 | 
						|
      const videos = res.body.data
 | 
						|
      expect(videos[0].name).to.equal('video 2 server 2')
 | 
						|
      expect(videos[1].name).to.equal('video 1 server 2')
 | 
						|
    }
 | 
						|
 | 
						|
    {
 | 
						|
      const res = await listVideoRedundancies({
 | 
						|
        url: servers[0].url,
 | 
						|
        accessToken: servers[0].accessToken,
 | 
						|
        target: 'remote-videos',
 | 
						|
        sort: '-name',
 | 
						|
        start: 1,
 | 
						|
        count: 1
 | 
						|
      })
 | 
						|
 | 
						|
      const videos = res.body.data
 | 
						|
      expect(videos[0].name).to.equal('video 1 server 2')
 | 
						|
    }
 | 
						|
  })
 | 
						|
 | 
						|
  it('Should manually add a redundancy and list it', async function () {
 | 
						|
    this.timeout(120000)
 | 
						|
 | 
						|
    const uuid = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video 3 server 2', privacy: VideoPrivacy.UNLISTED })).uuid
 | 
						|
    await waitJobs(servers)
 | 
						|
    const videoId = await getLocalIdByUUID(servers[0].url, uuid)
 | 
						|
 | 
						|
    await addVideoRedundancy({
 | 
						|
      url: servers[0].url,
 | 
						|
      accessToken: servers[0].accessToken,
 | 
						|
      videoId
 | 
						|
    })
 | 
						|
 | 
						|
    await waitJobs(servers)
 | 
						|
    await waitUntilLog(servers[0], 'Duplicated ', 15)
 | 
						|
    await waitJobs(servers)
 | 
						|
 | 
						|
    {
 | 
						|
      const res = await listVideoRedundancies({
 | 
						|
        url: servers[0].url,
 | 
						|
        accessToken: servers[0].accessToken,
 | 
						|
        target: 'remote-videos',
 | 
						|
        sort: '-name',
 | 
						|
        start: 0,
 | 
						|
        count: 5
 | 
						|
      })
 | 
						|
 | 
						|
      const videos = res.body.data
 | 
						|
      expect(videos[0].name).to.equal('video 3 server 2')
 | 
						|
 | 
						|
      const video = videos[0]
 | 
						|
      expect(video.redundancies.files).to.have.lengthOf(4)
 | 
						|
      expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1)
 | 
						|
 | 
						|
      const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists)
 | 
						|
 | 
						|
      for (const r of redundancies) {
 | 
						|
        redundanciesToRemove.push(r.id)
 | 
						|
 | 
						|
        expect(r.strategy).to.equal('manual')
 | 
						|
        expect(r.fileUrl).to.exist
 | 
						|
        expect(r.createdAt).to.exist
 | 
						|
        expect(r.updatedAt).to.exist
 | 
						|
        expect(r.expiresOn).to.be.null
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    const res = await listVideoRedundancies({
 | 
						|
      url: servers[1].url,
 | 
						|
      accessToken: servers[1].accessToken,
 | 
						|
      target: 'my-videos',
 | 
						|
      sort: '-name',
 | 
						|
      start: 0,
 | 
						|
      count: 5
 | 
						|
    })
 | 
						|
 | 
						|
    const videos = res.body.data
 | 
						|
    expect(videos[0].name).to.equal('video 3 server 2')
 | 
						|
 | 
						|
    const video = videos[0]
 | 
						|
    expect(video.redundancies.files).to.have.lengthOf(4)
 | 
						|
    expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1)
 | 
						|
 | 
						|
    const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists)
 | 
						|
 | 
						|
    for (const r of redundancies) {
 | 
						|
      expect(r.strategy).to.be.null
 | 
						|
      expect(r.fileUrl).to.exist
 | 
						|
      expect(r.createdAt).to.exist
 | 
						|
      expect(r.updatedAt).to.exist
 | 
						|
      expect(r.expiresOn).to.be.null
 | 
						|
    }
 | 
						|
  })
 | 
						|
 | 
						|
  it('Should manually remove a redundancy and remove it from the list', async function () {
 | 
						|
    this.timeout(120000)
 | 
						|
 | 
						|
    for (const redundancyId of redundanciesToRemove) {
 | 
						|
      await removeVideoRedundancy({
 | 
						|
        url: servers[0].url,
 | 
						|
        accessToken: servers[0].accessToken,
 | 
						|
        redundancyId
 | 
						|
      })
 | 
						|
    }
 | 
						|
 | 
						|
    {
 | 
						|
      const res = await listVideoRedundancies({
 | 
						|
        url: servers[0].url,
 | 
						|
        accessToken: servers[0].accessToken,
 | 
						|
        target: 'remote-videos',
 | 
						|
        sort: '-name',
 | 
						|
        start: 0,
 | 
						|
        count: 5
 | 
						|
      })
 | 
						|
 | 
						|
      const videos = res.body.data
 | 
						|
      expect(videos).to.have.lengthOf(2)
 | 
						|
 | 
						|
      expect(videos[0].name).to.equal('video 2 server 2')
 | 
						|
 | 
						|
      redundanciesToRemove = []
 | 
						|
      const video = videos[0]
 | 
						|
      expect(video.redundancies.files).to.have.lengthOf(4)
 | 
						|
      expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1)
 | 
						|
 | 
						|
      const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists)
 | 
						|
 | 
						|
      for (const r of redundancies) {
 | 
						|
        redundanciesToRemove.push(r.id)
 | 
						|
      }
 | 
						|
    }
 | 
						|
  })
 | 
						|
 | 
						|
  it('Should remove another (auto) redundancy', async function () {
 | 
						|
    {
 | 
						|
      for (const redundancyId of redundanciesToRemove) {
 | 
						|
        await removeVideoRedundancy({
 | 
						|
          url: servers[0].url,
 | 
						|
          accessToken: servers[0].accessToken,
 | 
						|
          redundancyId
 | 
						|
        })
 | 
						|
      }
 | 
						|
 | 
						|
      const res = await listVideoRedundancies({
 | 
						|
        url: servers[0].url,
 | 
						|
        accessToken: servers[0].accessToken,
 | 
						|
        target: 'remote-videos',
 | 
						|
        sort: '-name',
 | 
						|
        start: 0,
 | 
						|
        count: 5
 | 
						|
      })
 | 
						|
 | 
						|
      const videos = res.body.data
 | 
						|
      expect(videos[0].name).to.equal('video 1 server 2')
 | 
						|
      expect(videos).to.have.lengthOf(1)
 | 
						|
    }
 | 
						|
  })
 | 
						|
 | 
						|
  after(async function () {
 | 
						|
    await cleanupTests(servers)
 | 
						|
  })
 | 
						|
})
 |