1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
3 import { expect } from 'chai'
10 setAccessTokensToServers,
12 } from '@shared/server-commands'
13 import { VideoPrivacy, VideoRedundanciesTarget } from '@shared/models'
15 describe('Test manage videos redundancy', function () {
16 const targets: VideoRedundanciesTarget[] = [ 'my-videos', 'remote-videos' ]
18 let servers: PeerTubeServer[]
19 let video1Server2UUID: string
20 let video2Server2UUID: string
21 let redundanciesToRemove: number[] = []
23 let commands: RedundancyCommand[]
25 before(async function () {
36 check_interval: '1 second',
39 strategy: 'recently-added',
40 min_lifetime: '1 hour',
48 servers = await createMultipleServers(3, config)
50 // Get the access tokens
51 await setAccessTokensToServers(servers)
53 commands = servers.map(s => s.redundancy)
56 const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video 1 server 2' } })
57 video1Server2UUID = uuid
61 const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video 2 server 2' } })
62 video2Server2UUID = uuid
65 await waitJobs(servers)
67 // Server 1 and server 2 follow each other
68 await doubleFollow(servers[0], servers[1])
69 await doubleFollow(servers[0], servers[2])
70 await commands[0].updateRedundancy({ host: servers[1].host, redundancyAllowed: true })
72 await waitJobs(servers)
75 it('Should not have redundancies on server 3', async function () {
76 for (const target of targets) {
77 const body = await commands[2].listVideos({ target })
79 expect(body.total).to.equal(0)
80 expect(body.data).to.have.lengthOf(0)
84 it('Should correctly list followings by redundancy', async function () {
85 const body = await servers[0].follows.getFollowings({ sort: '-redundancyAllowed' })
87 expect(body.total).to.equal(2)
88 expect(body.data).to.have.lengthOf(2)
90 expect(body.data[0].following.host).to.equal(servers[1].host)
91 expect(body.data[1].following.host).to.equal(servers[2].host)
94 it('Should not have "remote-videos" redundancies on server 2', async function () {
97 await waitJobs(servers)
98 await servers[0].servers.waitUntilLog('Duplicated ', 10)
99 await waitJobs(servers)
101 const body = await commands[1].listVideos({ target: 'remote-videos' })
103 expect(body.total).to.equal(0)
104 expect(body.data).to.have.lengthOf(0)
107 it('Should have "my-videos" redundancies on server 2', async function () {
110 const body = await commands[1].listVideos({ target: 'my-videos' })
111 expect(body.total).to.equal(2)
113 const videos = body.data
114 expect(videos).to.have.lengthOf(2)
116 const videos1 = videos.find(v => v.uuid === video1Server2UUID)
117 const videos2 = videos.find(v => v.uuid === video2Server2UUID)
119 expect(videos1.name).to.equal('video 1 server 2')
120 expect(videos2.name).to.equal('video 2 server 2')
122 expect(videos1.redundancies.files).to.have.lengthOf(4)
123 expect(videos1.redundancies.streamingPlaylists).to.have.lengthOf(1)
125 const redundancies = videos1.redundancies.files.concat(videos1.redundancies.streamingPlaylists)
127 for (const r of redundancies) {
128 expect(r.strategy).to.be.null
129 expect(r.fileUrl).to.exist
130 expect(r.createdAt).to.exist
131 expect(r.updatedAt).to.exist
132 expect(r.expiresOn).to.exist
136 it('Should not have "my-videos" redundancies on server 1', async function () {
137 const body = await commands[0].listVideos({ target: 'my-videos' })
139 expect(body.total).to.equal(0)
140 expect(body.data).to.have.lengthOf(0)
143 it('Should have "remote-videos" redundancies on server 1', async function () {
146 const body = await commands[0].listVideos({ target: 'remote-videos' })
147 expect(body.total).to.equal(2)
149 const videos = body.data
150 expect(videos).to.have.lengthOf(2)
152 const videos1 = videos.find(v => v.uuid === video1Server2UUID)
153 const videos2 = videos.find(v => v.uuid === video2Server2UUID)
155 expect(videos1.name).to.equal('video 1 server 2')
156 expect(videos2.name).to.equal('video 2 server 2')
158 expect(videos1.redundancies.files).to.have.lengthOf(4)
159 expect(videos1.redundancies.streamingPlaylists).to.have.lengthOf(1)
161 const redundancies = videos1.redundancies.files.concat(videos1.redundancies.streamingPlaylists)
163 for (const r of redundancies) {
164 expect(r.strategy).to.equal('recently-added')
165 expect(r.fileUrl).to.exist
166 expect(r.createdAt).to.exist
167 expect(r.updatedAt).to.exist
168 expect(r.expiresOn).to.exist
172 it('Should correctly paginate and sort results', async function () {
174 const body = await commands[0].listVideos({
175 target: 'remote-videos',
181 const videos = body.data
182 expect(videos[0].name).to.equal('video 1 server 2')
183 expect(videos[1].name).to.equal('video 2 server 2')
187 const body = await commands[0].listVideos({
188 target: 'remote-videos',
194 const videos = body.data
195 expect(videos[0].name).to.equal('video 2 server 2')
196 expect(videos[1].name).to.equal('video 1 server 2')
200 const body = await commands[0].listVideos({
201 target: 'remote-videos',
207 expect(body.data[0].name).to.equal('video 1 server 2')
211 it('Should manually add a redundancy and list it', async function () {
214 const uuid = (await servers[1].videos.quickUpload({ name: 'video 3 server 2', privacy: VideoPrivacy.UNLISTED })).uuid
215 await waitJobs(servers)
216 const videoId = await servers[0].videos.getId({ uuid })
218 await commands[0].addVideo({ videoId })
220 await waitJobs(servers)
221 await servers[0].servers.waitUntilLog('Duplicated ', 15)
222 await waitJobs(servers)
225 const body = await commands[0].listVideos({
226 target: 'remote-videos',
232 const video = body.data[0]
234 expect(video.name).to.equal('video 3 server 2')
235 expect(video.redundancies.files).to.have.lengthOf(4)
236 expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1)
238 const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists)
240 for (const r of redundancies) {
241 redundanciesToRemove.push(r.id)
243 expect(r.strategy).to.equal('manual')
244 expect(r.fileUrl).to.exist
245 expect(r.createdAt).to.exist
246 expect(r.updatedAt).to.exist
247 expect(r.expiresOn).to.be.null
251 const body = await commands[1].listVideos({
258 const video = body.data[0]
259 expect(video.name).to.equal('video 3 server 2')
260 expect(video.redundancies.files).to.have.lengthOf(4)
261 expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1)
263 const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists)
265 for (const r of redundancies) {
266 expect(r.strategy).to.be.null
267 expect(r.fileUrl).to.exist
268 expect(r.createdAt).to.exist
269 expect(r.updatedAt).to.exist
270 expect(r.expiresOn).to.be.null
274 it('Should manually remove a redundancy and remove it from the list', async function () {
277 for (const redundancyId of redundanciesToRemove) {
278 await commands[0].removeVideo({ redundancyId })
282 const body = await commands[0].listVideos({
283 target: 'remote-videos',
289 const videos = body.data
291 expect(videos).to.have.lengthOf(2)
293 const video = videos[0]
294 expect(video.name).to.equal('video 2 server 2')
295 expect(video.redundancies.files).to.have.lengthOf(4)
296 expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1)
298 const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists)
300 redundanciesToRemove = redundancies.map(r => r.id)
304 it('Should remove another (auto) redundancy', async function () {
305 for (const redundancyId of redundanciesToRemove) {
306 await commands[0].removeVideo({ redundancyId })
309 const body = await commands[0].listVideos({
310 target: 'remote-videos',
316 const videos = body.data
317 expect(videos).to.have.lengthOf(1)
318 expect(videos[0].name).to.equal('video 1 server 2')
321 after(async function () {
322 await cleanupTests(servers)