]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/redundancy/manage-redundancy.ts
b607900f881b62303da5d0517a4409c8af4ad07b
[github/Chocobozzz/PeerTube.git] / server / tests / api / redundancy / manage-redundancy.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import * as chai from 'chai'
4 import {
5 cleanupTests,
6 createMultipleServers,
7 doubleFollow,
8 PeerTubeServer,
9 RedundancyCommand,
10 setAccessTokensToServers,
11 waitJobs
12 } from '@shared/server-commands'
13 import { VideoPrivacy, VideoRedundanciesTarget } from '@shared/models'
14
15 const expect = chai.expect
16
17 describe('Test manage videos redundancy', function () {
18 const targets: VideoRedundanciesTarget[] = [ 'my-videos', 'remote-videos' ]
19
20 let servers: PeerTubeServer[]
21 let video1Server2UUID: string
22 let video2Server2UUID: string
23 let redundanciesToRemove: number[] = []
24
25 let commands: RedundancyCommand[]
26
27 before(async function () {
28 this.timeout(120000)
29
30 const config = {
31 transcoding: {
32 hls: {
33 enabled: true
34 }
35 },
36 redundancy: {
37 videos: {
38 check_interval: '1 second',
39 strategies: [
40 {
41 strategy: 'recently-added',
42 min_lifetime: '1 hour',
43 size: '10MB',
44 min_views: 0
45 }
46 ]
47 }
48 }
49 }
50 servers = await createMultipleServers(3, config)
51
52 // Get the access tokens
53 await setAccessTokensToServers(servers)
54
55 commands = servers.map(s => s.redundancy)
56
57 {
58 const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video 1 server 2' } })
59 video1Server2UUID = uuid
60 }
61
62 {
63 const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video 2 server 2' } })
64 video2Server2UUID = uuid
65 }
66
67 await waitJobs(servers)
68
69 // Server 1 and server 2 follow each other
70 await doubleFollow(servers[0], servers[1])
71 await doubleFollow(servers[0], servers[2])
72 await commands[0].updateRedundancy({ host: servers[1].host, redundancyAllowed: true })
73
74 await waitJobs(servers)
75 })
76
77 it('Should not have redundancies on server 3', async function () {
78 for (const target of targets) {
79 const body = await commands[2].listVideos({ target })
80
81 expect(body.total).to.equal(0)
82 expect(body.data).to.have.lengthOf(0)
83 }
84 })
85
86 it('Should correctly list followings by redundancy', async function () {
87 const body = await servers[0].follows.getFollowings({ sort: '-redundancyAllowed' })
88
89 expect(body.total).to.equal(2)
90 expect(body.data).to.have.lengthOf(2)
91
92 expect(body.data[0].following.host).to.equal(servers[1].host)
93 expect(body.data[1].following.host).to.equal(servers[2].host)
94 })
95
96 it('Should not have "remote-videos" redundancies on server 2', async function () {
97 this.timeout(120000)
98
99 await waitJobs(servers)
100 await servers[0].servers.waitUntilLog('Duplicated ', 10)
101 await waitJobs(servers)
102
103 const body = await commands[1].listVideos({ target: 'remote-videos' })
104
105 expect(body.total).to.equal(0)
106 expect(body.data).to.have.lengthOf(0)
107 })
108
109 it('Should have "my-videos" redundancies on server 2', async function () {
110 this.timeout(120000)
111
112 const body = await commands[1].listVideos({ target: 'my-videos' })
113 expect(body.total).to.equal(2)
114
115 const videos = body.data
116 expect(videos).to.have.lengthOf(2)
117
118 const videos1 = videos.find(v => v.uuid === video1Server2UUID)
119 const videos2 = videos.find(v => v.uuid === video2Server2UUID)
120
121 expect(videos1.name).to.equal('video 1 server 2')
122 expect(videos2.name).to.equal('video 2 server 2')
123
124 expect(videos1.redundancies.files).to.have.lengthOf(4)
125 expect(videos1.redundancies.streamingPlaylists).to.have.lengthOf(1)
126
127 const redundancies = videos1.redundancies.files.concat(videos1.redundancies.streamingPlaylists)
128
129 for (const r of redundancies) {
130 expect(r.strategy).to.be.null
131 expect(r.fileUrl).to.exist
132 expect(r.createdAt).to.exist
133 expect(r.updatedAt).to.exist
134 expect(r.expiresOn).to.exist
135 }
136 })
137
138 it('Should not have "my-videos" redundancies on server 1', async function () {
139 const body = await commands[0].listVideos({ target: 'my-videos' })
140
141 expect(body.total).to.equal(0)
142 expect(body.data).to.have.lengthOf(0)
143 })
144
145 it('Should have "remote-videos" redundancies on server 1', async function () {
146 this.timeout(120000)
147
148 const body = await commands[0].listVideos({ target: 'remote-videos' })
149 expect(body.total).to.equal(2)
150
151 const videos = body.data
152 expect(videos).to.have.lengthOf(2)
153
154 const videos1 = videos.find(v => v.uuid === video1Server2UUID)
155 const videos2 = videos.find(v => v.uuid === video2Server2UUID)
156
157 expect(videos1.name).to.equal('video 1 server 2')
158 expect(videos2.name).to.equal('video 2 server 2')
159
160 expect(videos1.redundancies.files).to.have.lengthOf(4)
161 expect(videos1.redundancies.streamingPlaylists).to.have.lengthOf(1)
162
163 const redundancies = videos1.redundancies.files.concat(videos1.redundancies.streamingPlaylists)
164
165 for (const r of redundancies) {
166 expect(r.strategy).to.equal('recently-added')
167 expect(r.fileUrl).to.exist
168 expect(r.createdAt).to.exist
169 expect(r.updatedAt).to.exist
170 expect(r.expiresOn).to.exist
171 }
172 })
173
174 it('Should correctly paginate and sort results', async function () {
175 {
176 const body = await commands[0].listVideos({
177 target: 'remote-videos',
178 sort: 'name',
179 start: 0,
180 count: 2
181 })
182
183 const videos = body.data
184 expect(videos[0].name).to.equal('video 1 server 2')
185 expect(videos[1].name).to.equal('video 2 server 2')
186 }
187
188 {
189 const body = await commands[0].listVideos({
190 target: 'remote-videos',
191 sort: '-name',
192 start: 0,
193 count: 2
194 })
195
196 const videos = body.data
197 expect(videos[0].name).to.equal('video 2 server 2')
198 expect(videos[1].name).to.equal('video 1 server 2')
199 }
200
201 {
202 const body = await commands[0].listVideos({
203 target: 'remote-videos',
204 sort: '-name',
205 start: 1,
206 count: 1
207 })
208
209 expect(body.data[0].name).to.equal('video 1 server 2')
210 }
211 })
212
213 it('Should manually add a redundancy and list it', async function () {
214 this.timeout(120000)
215
216 const uuid = (await servers[1].videos.quickUpload({ name: 'video 3 server 2', privacy: VideoPrivacy.UNLISTED })).uuid
217 await waitJobs(servers)
218 const videoId = await servers[0].videos.getId({ uuid })
219
220 await commands[0].addVideo({ videoId })
221
222 await waitJobs(servers)
223 await servers[0].servers.waitUntilLog('Duplicated ', 15)
224 await waitJobs(servers)
225
226 {
227 const body = await commands[0].listVideos({
228 target: 'remote-videos',
229 sort: '-name',
230 start: 0,
231 count: 5
232 })
233
234 const video = body.data[0]
235
236 expect(video.name).to.equal('video 3 server 2')
237 expect(video.redundancies.files).to.have.lengthOf(4)
238 expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1)
239
240 const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists)
241
242 for (const r of redundancies) {
243 redundanciesToRemove.push(r.id)
244
245 expect(r.strategy).to.equal('manual')
246 expect(r.fileUrl).to.exist
247 expect(r.createdAt).to.exist
248 expect(r.updatedAt).to.exist
249 expect(r.expiresOn).to.be.null
250 }
251 }
252
253 const body = await commands[1].listVideos({
254 target: 'my-videos',
255 sort: '-name',
256 start: 0,
257 count: 5
258 })
259
260 const video = body.data[0]
261 expect(video.name).to.equal('video 3 server 2')
262 expect(video.redundancies.files).to.have.lengthOf(4)
263 expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1)
264
265 const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists)
266
267 for (const r of redundancies) {
268 expect(r.strategy).to.be.null
269 expect(r.fileUrl).to.exist
270 expect(r.createdAt).to.exist
271 expect(r.updatedAt).to.exist
272 expect(r.expiresOn).to.be.null
273 }
274 })
275
276 it('Should manually remove a redundancy and remove it from the list', async function () {
277 this.timeout(120000)
278
279 for (const redundancyId of redundanciesToRemove) {
280 await commands[0].removeVideo({ redundancyId })
281 }
282
283 {
284 const body = await commands[0].listVideos({
285 target: 'remote-videos',
286 sort: '-name',
287 start: 0,
288 count: 5
289 })
290
291 const videos = body.data
292
293 expect(videos).to.have.lengthOf(2)
294
295 const video = videos[0]
296 expect(video.name).to.equal('video 2 server 2')
297 expect(video.redundancies.files).to.have.lengthOf(4)
298 expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1)
299
300 const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists)
301
302 redundanciesToRemove = redundancies.map(r => r.id)
303 }
304 })
305
306 it('Should remove another (auto) redundancy', async function () {
307 for (const redundancyId of redundanciesToRemove) {
308 await commands[0].removeVideo({ redundancyId })
309 }
310
311 const body = await commands[0].listVideos({
312 target: 'remote-videos',
313 sort: '-name',
314 start: 0,
315 count: 5
316 })
317
318 const videos = body.data
319 expect(videos).to.have.lengthOf(1)
320 expect(videos[0].name).to.equal('video 1 server 2')
321 })
322
323 after(async function () {
324 await cleanupTests(servers)
325 })
326 })