diff options
Diffstat (limited to 'server/tests/api/redundancy')
-rw-r--r-- | server/tests/api/redundancy/manage-redundancy.ts | 193 | ||||
-rw-r--r-- | server/tests/api/redundancy/redundancy-constraints.ts | 69 | ||||
-rw-r--r-- | server/tests/api/redundancy/redundancy.ts | 298 |
3 files changed, 234 insertions, 326 deletions
diff --git a/server/tests/api/redundancy/manage-redundancy.ts b/server/tests/api/redundancy/manage-redundancy.ts index 4253124c8..5fd464ded 100644 --- a/server/tests/api/redundancy/manage-redundancy.ts +++ b/server/tests/api/redundancy/manage-redundancy.ts | |||
@@ -1,32 +1,30 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | 2 | ||
3 | import * as chai from 'chai' | ||
4 | import 'mocha' | 3 | import 'mocha' |
4 | import * as chai from 'chai' | ||
5 | import { | 5 | import { |
6 | cleanupTests, | 6 | cleanupTests, |
7 | createMultipleServers, | ||
7 | doubleFollow, | 8 | doubleFollow, |
8 | flushAndRunMultipleServers, | 9 | PeerTubeServer, |
9 | getLocalIdByUUID, | 10 | RedundancyCommand, |
10 | ServerInfo, | ||
11 | setAccessTokensToServers, | 11 | setAccessTokensToServers, |
12 | uploadVideo, | 12 | waitJobs |
13 | uploadVideoAndGetId, | 13 | } from '@shared/extra-utils' |
14 | waitUntilLog | 14 | import { VideoPrivacy, VideoRedundanciesTarget } from '@shared/models' |
15 | } from '../../../../shared/extra-utils' | ||
16 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' | ||
17 | import { addVideoRedundancy, listVideoRedundancies, removeVideoRedundancy, updateRedundancy } from '@shared/extra-utils/server/redundancy' | ||
18 | import { VideoPrivacy, VideoRedundanciesTarget, VideoRedundancy } from '@shared/models' | ||
19 | 15 | ||
20 | const expect = chai.expect | 16 | const expect = chai.expect |
21 | 17 | ||
22 | describe('Test manage videos redundancy', function () { | 18 | describe('Test manage videos redundancy', function () { |
23 | const targets: VideoRedundanciesTarget[] = [ 'my-videos', 'remote-videos' ] | 19 | const targets: VideoRedundanciesTarget[] = [ 'my-videos', 'remote-videos' ] |
24 | 20 | ||
25 | let servers: ServerInfo[] | 21 | let servers: PeerTubeServer[] |
26 | let video1Server2UUID: string | 22 | let video1Server2UUID: string |
27 | let video2Server2UUID: string | 23 | let video2Server2UUID: string |
28 | let redundanciesToRemove: number[] = [] | 24 | let redundanciesToRemove: number[] = [] |
29 | 25 | ||
26 | let commands: RedundancyCommand[] | ||
27 | |||
30 | before(async function () { | 28 | before(async function () { |
31 | this.timeout(120000) | 29 | this.timeout(120000) |
32 | 30 | ||
@@ -50,40 +48,38 @@ describe('Test manage videos redundancy', function () { | |||
50 | } | 48 | } |
51 | } | 49 | } |
52 | } | 50 | } |
53 | servers = await flushAndRunMultipleServers(3, config) | 51 | servers = await createMultipleServers(3, config) |
54 | 52 | ||
55 | // Get the access tokens | 53 | // Get the access tokens |
56 | await setAccessTokensToServers(servers) | 54 | await setAccessTokensToServers(servers) |
57 | 55 | ||
56 | commands = servers.map(s => s.redundancy) | ||
57 | |||
58 | { | 58 | { |
59 | const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 1 server 2' }) | 59 | const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video 1 server 2' } }) |
60 | video1Server2UUID = res.body.video.uuid | 60 | video1Server2UUID = uuid |
61 | } | 61 | } |
62 | 62 | ||
63 | { | 63 | { |
64 | const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 2 server 2' }) | 64 | const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video 2 server 2' } }) |
65 | video2Server2UUID = res.body.video.uuid | 65 | video2Server2UUID = uuid |
66 | } | 66 | } |
67 | 67 | ||
68 | await waitJobs(servers) | 68 | await waitJobs(servers) |
69 | 69 | ||
70 | // Server 1 and server 2 follow each other | 70 | // Server 1 and server 2 follow each other |
71 | await doubleFollow(servers[0], servers[1]) | 71 | await doubleFollow(servers[0], servers[1]) |
72 | await updateRedundancy(servers[0].url, servers[0].accessToken, servers[1].host, true) | 72 | await commands[0].updateRedundancy({ host: servers[1].host, redundancyAllowed: true }) |
73 | 73 | ||
74 | await waitJobs(servers) | 74 | await waitJobs(servers) |
75 | }) | 75 | }) |
76 | 76 | ||
77 | it('Should not have redundancies on server 3', async function () { | 77 | it('Should not have redundancies on server 3', async function () { |
78 | for (const target of targets) { | 78 | for (const target of targets) { |
79 | const res = await listVideoRedundancies({ | 79 | const body = await commands[2].listVideos({ target }) |
80 | url: servers[2].url, | ||
81 | accessToken: servers[2].accessToken, | ||
82 | target | ||
83 | }) | ||
84 | 80 | ||
85 | expect(res.body.total).to.equal(0) | 81 | expect(body.total).to.equal(0) |
86 | expect(res.body.data).to.have.lengthOf(0) | 82 | expect(body.data).to.have.lengthOf(0) |
87 | } | 83 | } |
88 | }) | 84 | }) |
89 | 85 | ||
@@ -91,31 +87,22 @@ describe('Test manage videos redundancy', function () { | |||
91 | this.timeout(120000) | 87 | this.timeout(120000) |
92 | 88 | ||
93 | await waitJobs(servers) | 89 | await waitJobs(servers) |
94 | await waitUntilLog(servers[0], 'Duplicated ', 10) | 90 | await servers[0].servers.waitUntilLog('Duplicated ', 10) |
95 | await waitJobs(servers) | 91 | await waitJobs(servers) |
96 | 92 | ||
97 | const res = await listVideoRedundancies({ | 93 | const body = await commands[1].listVideos({ target: 'remote-videos' }) |
98 | url: servers[1].url, | ||
99 | accessToken: servers[1].accessToken, | ||
100 | target: 'remote-videos' | ||
101 | }) | ||
102 | 94 | ||
103 | expect(res.body.total).to.equal(0) | 95 | expect(body.total).to.equal(0) |
104 | expect(res.body.data).to.have.lengthOf(0) | 96 | expect(body.data).to.have.lengthOf(0) |
105 | }) | 97 | }) |
106 | 98 | ||
107 | it('Should have "my-videos" redundancies on server 2', async function () { | 99 | it('Should have "my-videos" redundancies on server 2', async function () { |
108 | this.timeout(120000) | 100 | this.timeout(120000) |
109 | 101 | ||
110 | const res = await listVideoRedundancies({ | 102 | const body = await commands[1].listVideos({ target: 'my-videos' }) |
111 | url: servers[1].url, | 103 | expect(body.total).to.equal(2) |
112 | accessToken: servers[1].accessToken, | ||
113 | target: 'my-videos' | ||
114 | }) | ||
115 | |||
116 | expect(res.body.total).to.equal(2) | ||
117 | 104 | ||
118 | const videos = res.body.data as VideoRedundancy[] | 105 | const videos = body.data |
119 | expect(videos).to.have.lengthOf(2) | 106 | expect(videos).to.have.lengthOf(2) |
120 | 107 | ||
121 | const videos1 = videos.find(v => v.uuid === video1Server2UUID) | 108 | const videos1 = videos.find(v => v.uuid === video1Server2UUID) |
@@ -139,28 +126,19 @@ describe('Test manage videos redundancy', function () { | |||
139 | }) | 126 | }) |
140 | 127 | ||
141 | it('Should not have "my-videos" redundancies on server 1', async function () { | 128 | it('Should not have "my-videos" redundancies on server 1', async function () { |
142 | const res = await listVideoRedundancies({ | 129 | const body = await commands[0].listVideos({ target: 'my-videos' }) |
143 | url: servers[0].url, | ||
144 | accessToken: servers[0].accessToken, | ||
145 | target: 'my-videos' | ||
146 | }) | ||
147 | 130 | ||
148 | expect(res.body.total).to.equal(0) | 131 | expect(body.total).to.equal(0) |
149 | expect(res.body.data).to.have.lengthOf(0) | 132 | expect(body.data).to.have.lengthOf(0) |
150 | }) | 133 | }) |
151 | 134 | ||
152 | it('Should have "remote-videos" redundancies on server 1', async function () { | 135 | it('Should have "remote-videos" redundancies on server 1', async function () { |
153 | this.timeout(120000) | 136 | this.timeout(120000) |
154 | 137 | ||
155 | const res = await listVideoRedundancies({ | 138 | const body = await commands[0].listVideos({ target: 'remote-videos' }) |
156 | url: servers[0].url, | 139 | expect(body.total).to.equal(2) |
157 | accessToken: servers[0].accessToken, | ||
158 | target: 'remote-videos' | ||
159 | }) | ||
160 | 140 | ||
161 | expect(res.body.total).to.equal(2) | 141 | const videos = body.data |
162 | |||
163 | const videos = res.body.data as VideoRedundancy[] | ||
164 | expect(videos).to.have.lengthOf(2) | 142 | expect(videos).to.have.lengthOf(2) |
165 | 143 | ||
166 | const videos1 = videos.find(v => v.uuid === video1Server2UUID) | 144 | const videos1 = videos.find(v => v.uuid === video1Server2UUID) |
@@ -185,81 +163,67 @@ describe('Test manage videos redundancy', function () { | |||
185 | 163 | ||
186 | it('Should correctly paginate and sort results', async function () { | 164 | it('Should correctly paginate and sort results', async function () { |
187 | { | 165 | { |
188 | const res = await listVideoRedundancies({ | 166 | const body = await commands[0].listVideos({ |
189 | url: servers[0].url, | ||
190 | accessToken: servers[0].accessToken, | ||
191 | target: 'remote-videos', | 167 | target: 'remote-videos', |
192 | sort: 'name', | 168 | sort: 'name', |
193 | start: 0, | 169 | start: 0, |
194 | count: 2 | 170 | count: 2 |
195 | }) | 171 | }) |
196 | 172 | ||
197 | const videos = res.body.data | 173 | const videos = body.data |
198 | expect(videos[0].name).to.equal('video 1 server 2') | 174 | expect(videos[0].name).to.equal('video 1 server 2') |
199 | expect(videos[1].name).to.equal('video 2 server 2') | 175 | expect(videos[1].name).to.equal('video 2 server 2') |
200 | } | 176 | } |
201 | 177 | ||
202 | { | 178 | { |
203 | const res = await listVideoRedundancies({ | 179 | const body = await commands[0].listVideos({ |
204 | url: servers[0].url, | ||
205 | accessToken: servers[0].accessToken, | ||
206 | target: 'remote-videos', | 180 | target: 'remote-videos', |
207 | sort: '-name', | 181 | sort: '-name', |
208 | start: 0, | 182 | start: 0, |
209 | count: 2 | 183 | count: 2 |
210 | }) | 184 | }) |
211 | 185 | ||
212 | const videos = res.body.data | 186 | const videos = body.data |
213 | expect(videos[0].name).to.equal('video 2 server 2') | 187 | expect(videos[0].name).to.equal('video 2 server 2') |
214 | expect(videos[1].name).to.equal('video 1 server 2') | 188 | expect(videos[1].name).to.equal('video 1 server 2') |
215 | } | 189 | } |
216 | 190 | ||
217 | { | 191 | { |
218 | const res = await listVideoRedundancies({ | 192 | const body = await commands[0].listVideos({ |
219 | url: servers[0].url, | ||
220 | accessToken: servers[0].accessToken, | ||
221 | target: 'remote-videos', | 193 | target: 'remote-videos', |
222 | sort: '-name', | 194 | sort: '-name', |
223 | start: 1, | 195 | start: 1, |
224 | count: 1 | 196 | count: 1 |
225 | }) | 197 | }) |
226 | 198 | ||
227 | const videos = res.body.data | 199 | expect(body.data[0].name).to.equal('video 1 server 2') |
228 | expect(videos[0].name).to.equal('video 1 server 2') | ||
229 | } | 200 | } |
230 | }) | 201 | }) |
231 | 202 | ||
232 | it('Should manually add a redundancy and list it', async function () { | 203 | it('Should manually add a redundancy and list it', async function () { |
233 | this.timeout(120000) | 204 | this.timeout(120000) |
234 | 205 | ||
235 | const uuid = (await uploadVideoAndGetId({ server: servers[1], videoName: 'video 3 server 2', privacy: VideoPrivacy.UNLISTED })).uuid | 206 | const uuid = (await servers[1].videos.quickUpload({ name: 'video 3 server 2', privacy: VideoPrivacy.UNLISTED })).uuid |
236 | await waitJobs(servers) | 207 | await waitJobs(servers) |
237 | const videoId = await getLocalIdByUUID(servers[0].url, uuid) | 208 | const videoId = await servers[0].videos.getId({ uuid }) |
238 | 209 | ||
239 | await addVideoRedundancy({ | 210 | await commands[0].addVideo({ videoId }) |
240 | url: servers[0].url, | ||
241 | accessToken: servers[0].accessToken, | ||
242 | videoId | ||
243 | }) | ||
244 | 211 | ||
245 | await waitJobs(servers) | 212 | await waitJobs(servers) |
246 | await waitUntilLog(servers[0], 'Duplicated ', 15) | 213 | await servers[0].servers.waitUntilLog('Duplicated ', 15) |
247 | await waitJobs(servers) | 214 | await waitJobs(servers) |
248 | 215 | ||
249 | { | 216 | { |
250 | const res = await listVideoRedundancies({ | 217 | const body = await commands[0].listVideos({ |
251 | url: servers[0].url, | ||
252 | accessToken: servers[0].accessToken, | ||
253 | target: 'remote-videos', | 218 | target: 'remote-videos', |
254 | sort: '-name', | 219 | sort: '-name', |
255 | start: 0, | 220 | start: 0, |
256 | count: 5 | 221 | count: 5 |
257 | }) | 222 | }) |
258 | 223 | ||
259 | const videos = res.body.data | 224 | const video = body.data[0] |
260 | expect(videos[0].name).to.equal('video 3 server 2') | ||
261 | 225 | ||
262 | const video = videos[0] | 226 | expect(video.name).to.equal('video 3 server 2') |
263 | expect(video.redundancies.files).to.have.lengthOf(4) | 227 | expect(video.redundancies.files).to.have.lengthOf(4) |
264 | expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1) | 228 | expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1) |
265 | 229 | ||
@@ -276,19 +240,15 @@ describe('Test manage videos redundancy', function () { | |||
276 | } | 240 | } |
277 | } | 241 | } |
278 | 242 | ||
279 | const res = await listVideoRedundancies({ | 243 | const body = await commands[1].listVideos({ |
280 | url: servers[1].url, | ||
281 | accessToken: servers[1].accessToken, | ||
282 | target: 'my-videos', | 244 | target: 'my-videos', |
283 | sort: '-name', | 245 | sort: '-name', |
284 | start: 0, | 246 | start: 0, |
285 | count: 5 | 247 | count: 5 |
286 | }) | 248 | }) |
287 | 249 | ||
288 | const videos = res.body.data | 250 | const video = body.data[0] |
289 | expect(videos[0].name).to.equal('video 3 server 2') | 251 | expect(video.name).to.equal('video 3 server 2') |
290 | |||
291 | const video = videos[0] | ||
292 | expect(video.redundancies.files).to.have.lengthOf(4) | 252 | expect(video.redundancies.files).to.have.lengthOf(4) |
293 | expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1) | 253 | expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1) |
294 | 254 | ||
@@ -307,64 +267,47 @@ describe('Test manage videos redundancy', function () { | |||
307 | this.timeout(120000) | 267 | this.timeout(120000) |
308 | 268 | ||
309 | for (const redundancyId of redundanciesToRemove) { | 269 | for (const redundancyId of redundanciesToRemove) { |
310 | await removeVideoRedundancy({ | 270 | await commands[0].removeVideo({ redundancyId }) |
311 | url: servers[0].url, | ||
312 | accessToken: servers[0].accessToken, | ||
313 | redundancyId | ||
314 | }) | ||
315 | } | 271 | } |
316 | 272 | ||
317 | { | 273 | { |
318 | const res = await listVideoRedundancies({ | 274 | const body = await commands[0].listVideos({ |
319 | url: servers[0].url, | ||
320 | accessToken: servers[0].accessToken, | ||
321 | target: 'remote-videos', | 275 | target: 'remote-videos', |
322 | sort: '-name', | 276 | sort: '-name', |
323 | start: 0, | 277 | start: 0, |
324 | count: 5 | 278 | count: 5 |
325 | }) | 279 | }) |
326 | 280 | ||
327 | const videos = res.body.data | 281 | const videos = body.data |
328 | expect(videos).to.have.lengthOf(2) | ||
329 | 282 | ||
330 | expect(videos[0].name).to.equal('video 2 server 2') | 283 | expect(videos).to.have.lengthOf(2) |
331 | 284 | ||
332 | redundanciesToRemove = [] | ||
333 | const video = videos[0] | 285 | const video = videos[0] |
286 | expect(video.name).to.equal('video 2 server 2') | ||
334 | expect(video.redundancies.files).to.have.lengthOf(4) | 287 | expect(video.redundancies.files).to.have.lengthOf(4) |
335 | expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1) | 288 | expect(video.redundancies.streamingPlaylists).to.have.lengthOf(1) |
336 | 289 | ||
337 | const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists) | 290 | const redundancies = video.redundancies.files.concat(video.redundancies.streamingPlaylists) |
338 | 291 | ||
339 | for (const r of redundancies) { | 292 | redundanciesToRemove = redundancies.map(r => r.id) |
340 | redundanciesToRemove.push(r.id) | ||
341 | } | ||
342 | } | 293 | } |
343 | }) | 294 | }) |
344 | 295 | ||
345 | it('Should remove another (auto) redundancy', async function () { | 296 | it('Should remove another (auto) redundancy', async function () { |
346 | { | 297 | for (const redundancyId of redundanciesToRemove) { |
347 | for (const redundancyId of redundanciesToRemove) { | 298 | await commands[0].removeVideo({ redundancyId }) |
348 | await removeVideoRedundancy({ | 299 | } |
349 | url: servers[0].url, | ||
350 | accessToken: servers[0].accessToken, | ||
351 | redundancyId | ||
352 | }) | ||
353 | } | ||
354 | 300 | ||
355 | const res = await listVideoRedundancies({ | 301 | const body = await commands[0].listVideos({ |
356 | url: servers[0].url, | 302 | target: 'remote-videos', |
357 | accessToken: servers[0].accessToken, | 303 | sort: '-name', |
358 | target: 'remote-videos', | 304 | start: 0, |
359 | sort: '-name', | 305 | count: 5 |
360 | start: 0, | 306 | }) |
361 | count: 5 | ||
362 | }) | ||
363 | 307 | ||
364 | const videos = res.body.data | 308 | const videos = body.data |
365 | expect(videos[0].name).to.equal('video 1 server 2') | 309 | expect(videos).to.have.lengthOf(1) |
366 | expect(videos).to.have.lengthOf(1) | 310 | expect(videos[0].name).to.equal('video 1 server 2') |
367 | } | ||
368 | }) | 311 | }) |
369 | 312 | ||
370 | after(async function () { | 313 | after(async function () { |
diff --git a/server/tests/api/redundancy/redundancy-constraints.ts b/server/tests/api/redundancy/redundancy-constraints.ts index 1cb1603bc..933a2c776 100644 --- a/server/tests/api/redundancy/redundancy-constraints.ts +++ b/server/tests/api/redundancy/redundancy-constraints.ts | |||
@@ -1,29 +1,14 @@ | |||
1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ | 1 | /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ |
2 | 2 | ||
3 | import 'mocha' | 3 | import 'mocha' |
4 | import * as chai from 'chai' | 4 | import { expect } from 'chai' |
5 | import { listVideoRedundancies, updateRedundancy } from '@shared/extra-utils/server/redundancy' | 5 | import { cleanupTests, createSingleServer, killallServers, PeerTubeServer, setAccessTokensToServers, waitJobs } from '@shared/extra-utils' |
6 | import { VideoPrivacy } from '@shared/models' | 6 | import { VideoPrivacy } from '@shared/models' |
7 | import { | ||
8 | cleanupTests, | ||
9 | flushAndRunServer, | ||
10 | follow, | ||
11 | killallServers, | ||
12 | reRunServer, | ||
13 | ServerInfo, | ||
14 | setAccessTokensToServers, | ||
15 | updateVideo, | ||
16 | uploadVideo, | ||
17 | waitUntilLog | ||
18 | } from '../../../../shared/extra-utils' | ||
19 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' | ||
20 | |||
21 | const expect = chai.expect | ||
22 | 7 | ||
23 | describe('Test redundancy constraints', function () { | 8 | describe('Test redundancy constraints', function () { |
24 | let remoteServer: ServerInfo | 9 | let remoteServer: PeerTubeServer |
25 | let localServer: ServerInfo | 10 | let localServer: PeerTubeServer |
26 | let servers: ServerInfo[] | 11 | let servers: PeerTubeServer[] |
27 | 12 | ||
28 | const remoteServerConfig = { | 13 | const remoteServerConfig = { |
29 | redundancy: { | 14 | redundancy: { |
@@ -43,38 +28,30 @@ describe('Test redundancy constraints', function () { | |||
43 | 28 | ||
44 | async function uploadWrapper (videoName: string) { | 29 | async function uploadWrapper (videoName: string) { |
45 | // Wait for transcoding | 30 | // Wait for transcoding |
46 | const res = await uploadVideo(localServer.url, localServer.accessToken, { name: 'to transcode', privacy: VideoPrivacy.PRIVATE }) | 31 | const { id } = await localServer.videos.upload({ attributes: { name: 'to transcode', privacy: VideoPrivacy.PRIVATE } }) |
47 | await waitJobs([ localServer ]) | 32 | await waitJobs([ localServer ]) |
48 | 33 | ||
49 | // Update video to schedule a federation | 34 | // Update video to schedule a federation |
50 | await updateVideo(localServer.url, localServer.accessToken, res.body.video.id, { name: videoName, privacy: VideoPrivacy.PUBLIC }) | 35 | await localServer.videos.update({ id, attributes: { name: videoName, privacy: VideoPrivacy.PUBLIC } }) |
51 | } | 36 | } |
52 | 37 | ||
53 | async function getTotalRedundanciesLocalServer () { | 38 | async function getTotalRedundanciesLocalServer () { |
54 | const res = await listVideoRedundancies({ | 39 | const body = await localServer.redundancy.listVideos({ target: 'my-videos' }) |
55 | url: localServer.url, | ||
56 | accessToken: localServer.accessToken, | ||
57 | target: 'my-videos' | ||
58 | }) | ||
59 | 40 | ||
60 | return res.body.total | 41 | return body.total |
61 | } | 42 | } |
62 | 43 | ||
63 | async function getTotalRedundanciesRemoteServer () { | 44 | async function getTotalRedundanciesRemoteServer () { |
64 | const res = await listVideoRedundancies({ | 45 | const body = await remoteServer.redundancy.listVideos({ target: 'remote-videos' }) |
65 | url: remoteServer.url, | ||
66 | accessToken: remoteServer.accessToken, | ||
67 | target: 'remote-videos' | ||
68 | }) | ||
69 | 46 | ||
70 | return res.body.total | 47 | return body.total |
71 | } | 48 | } |
72 | 49 | ||
73 | before(async function () { | 50 | before(async function () { |
74 | this.timeout(120000) | 51 | this.timeout(120000) |
75 | 52 | ||
76 | { | 53 | { |
77 | remoteServer = await flushAndRunServer(1, remoteServerConfig) | 54 | remoteServer = await createSingleServer(1, remoteServerConfig) |
78 | } | 55 | } |
79 | 56 | ||
80 | { | 57 | { |
@@ -85,7 +62,7 @@ describe('Test redundancy constraints', function () { | |||
85 | } | 62 | } |
86 | } | 63 | } |
87 | } | 64 | } |
88 | localServer = await flushAndRunServer(2, config) | 65 | localServer = await createSingleServer(2, config) |
89 | } | 66 | } |
90 | 67 | ||
91 | servers = [ remoteServer, localServer ] | 68 | servers = [ remoteServer, localServer ] |
@@ -93,14 +70,14 @@ describe('Test redundancy constraints', function () { | |||
93 | // Get the access tokens | 70 | // Get the access tokens |
94 | await setAccessTokensToServers(servers) | 71 | await setAccessTokensToServers(servers) |
95 | 72 | ||
96 | await uploadVideo(localServer.url, localServer.accessToken, { name: 'video 1 server 2' }) | 73 | await localServer.videos.upload({ attributes: { name: 'video 1 server 2' } }) |
97 | 74 | ||
98 | await waitJobs(servers) | 75 | await waitJobs(servers) |
99 | 76 | ||
100 | // Server 1 and server 2 follow each other | 77 | // Server 1 and server 2 follow each other |
101 | await follow(remoteServer.url, [ localServer.url ], remoteServer.accessToken) | 78 | await remoteServer.follows.follow({ hosts: [ localServer.url ] }) |
102 | await waitJobs(servers) | 79 | await waitJobs(servers) |
103 | await updateRedundancy(remoteServer.url, remoteServer.accessToken, localServer.host, true) | 80 | await remoteServer.redundancy.updateRedundancy({ host: localServer.host, redundancyAllowed: true }) |
104 | 81 | ||
105 | await waitJobs(servers) | 82 | await waitJobs(servers) |
106 | }) | 83 | }) |
@@ -109,7 +86,7 @@ describe('Test redundancy constraints', function () { | |||
109 | this.timeout(120000) | 86 | this.timeout(120000) |
110 | 87 | ||
111 | await waitJobs(servers) | 88 | await waitJobs(servers) |
112 | await waitUntilLog(remoteServer, 'Duplicated ', 5) | 89 | await remoteServer.servers.waitUntilLog('Duplicated ', 5) |
113 | await waitJobs(servers) | 90 | await waitJobs(servers) |
114 | 91 | ||
115 | { | 92 | { |
@@ -134,11 +111,11 @@ describe('Test redundancy constraints', function () { | |||
134 | } | 111 | } |
135 | } | 112 | } |
136 | await killallServers([ localServer ]) | 113 | await killallServers([ localServer ]) |
137 | await reRunServer(localServer, config) | 114 | await localServer.run(config) |
138 | 115 | ||
139 | await uploadWrapper('video 2 server 2') | 116 | await uploadWrapper('video 2 server 2') |
140 | 117 | ||
141 | await waitUntilLog(remoteServer, 'Duplicated ', 10) | 118 | await remoteServer.servers.waitUntilLog('Duplicated ', 10) |
142 | await waitJobs(servers) | 119 | await waitJobs(servers) |
143 | 120 | ||
144 | { | 121 | { |
@@ -163,11 +140,11 @@ describe('Test redundancy constraints', function () { | |||
163 | } | 140 | } |
164 | } | 141 | } |
165 | await killallServers([ localServer ]) | 142 | await killallServers([ localServer ]) |
166 | await reRunServer(localServer, config) | 143 | await localServer.run(config) |
167 | 144 | ||
168 | await uploadWrapper('video 3 server 2') | 145 | await uploadWrapper('video 3 server 2') |
169 | 146 | ||
170 | await waitUntilLog(remoteServer, 'Duplicated ', 15) | 147 | await remoteServer.servers.waitUntilLog('Duplicated ', 15) |
171 | await waitJobs(servers) | 148 | await waitJobs(servers) |
172 | 149 | ||
173 | { | 150 | { |
@@ -184,11 +161,11 @@ describe('Test redundancy constraints', function () { | |||
184 | it('Should have redundancy on server 1 and on server 2 with followings filter now server 2 follows server 1', async function () { | 161 | it('Should have redundancy on server 1 and on server 2 with followings filter now server 2 follows server 1', async function () { |
185 | this.timeout(120000) | 162 | this.timeout(120000) |
186 | 163 | ||
187 | await follow(localServer.url, [ remoteServer.url ], localServer.accessToken) | 164 | await localServer.follows.follow({ hosts: [ remoteServer.url ] }) |
188 | await waitJobs(servers) | 165 | await waitJobs(servers) |
189 | 166 | ||
190 | await uploadWrapper('video 4 server 2') | 167 | await uploadWrapper('video 4 server 2') |
191 | await waitUntilLog(remoteServer, 'Duplicated ', 20) | 168 | await remoteServer.servers.waitUntilLog('Duplicated ', 20) |
192 | await waitJobs(servers) | 169 | await waitJobs(servers) |
193 | 170 | ||
194 | { | 171 | { |
diff --git a/server/tests/api/redundancy/redundancy.ts b/server/tests/api/redundancy/redundancy.ts index 0e0a73b9d..e1a12f5f8 100644 --- a/server/tests/api/redundancy/redundancy.ts +++ b/server/tests/api/redundancy/redundancy.ts | |||
@@ -4,72 +4,63 @@ import 'mocha' | |||
4 | import * as chai from 'chai' | 4 | import * as chai from 'chai' |
5 | import { readdir } from 'fs-extra' | 5 | import { readdir } from 'fs-extra' |
6 | import * as magnetUtil from 'magnet-uri' | 6 | import * as magnetUtil from 'magnet-uri' |
7 | import { join } from 'path' | 7 | import { basename, join } from 'path' |
8 | import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' | ||
9 | import { | 8 | import { |
10 | checkSegmentHash, | 9 | checkSegmentHash, |
11 | checkVideoFilesWereRemoved, | 10 | checkVideoFilesWereRemoved, |
12 | cleanupTests, | 11 | cleanupTests, |
12 | createMultipleServers, | ||
13 | doubleFollow, | 13 | doubleFollow, |
14 | flushAndRunMultipleServers, | ||
15 | getFollowingListPaginationAndSort, | ||
16 | getVideo, | ||
17 | getVideoWithToken, | ||
18 | immutableAssign, | ||
19 | killallServers, | 14 | killallServers, |
20 | makeGetRequest, | 15 | makeRawRequest, |
21 | removeVideo, | 16 | PeerTubeServer, |
22 | reRunServer, | ||
23 | root, | 17 | root, |
24 | ServerInfo, | 18 | saveVideoInServers, |
25 | setAccessTokensToServers, | 19 | setAccessTokensToServers, |
26 | unfollow, | ||
27 | updateVideo, | ||
28 | uploadVideo, | ||
29 | viewVideo, | ||
30 | wait, | 20 | wait, |
31 | waitUntilLog | 21 | waitJobs |
32 | } from '../../../../shared/extra-utils' | 22 | } from '@shared/extra-utils' |
33 | import { waitJobs } from '../../../../shared/extra-utils/server/jobs' | ||
34 | import { | 23 | import { |
35 | addVideoRedundancy, | 24 | HttpStatusCode, |
36 | listVideoRedundancies, | 25 | VideoDetails, |
37 | removeVideoRedundancy, | 26 | VideoFile, |
38 | updateRedundancy | 27 | VideoPrivacy, |
39 | } from '../../../../shared/extra-utils/server/redundancy' | 28 | VideoRedundancyStrategy, |
40 | import { getStats } from '../../../../shared/extra-utils/server/stats' | 29 | VideoRedundancyStrategyWithManual |
41 | import { ActorFollow } from '../../../../shared/models/actors' | 30 | } from '@shared/models' |
42 | import { VideoRedundancy, VideoRedundancyStrategy, VideoRedundancyStrategyWithManual } from '../../../../shared/models/redundancy' | ||
43 | import { ServerStats } from '../../../../shared/models/server/server-stats.model' | ||
44 | import { VideoDetails, VideoPrivacy } from '../../../../shared/models/videos' | ||
45 | 31 | ||
46 | const expect = chai.expect | 32 | const expect = chai.expect |
47 | 33 | ||
48 | let servers: ServerInfo[] = [] | 34 | let servers: PeerTubeServer[] = [] |
49 | let video1Server2UUID: string | 35 | let video1Server2: VideoDetails |
50 | let video1Server2Id: number | ||
51 | 36 | ||
52 | function checkMagnetWebseeds (file: { magnetUri: string, resolution: { id: number } }, baseWebseeds: string[], server: ServerInfo) { | 37 | async function checkMagnetWebseeds (file: VideoFile, baseWebseeds: string[], server: PeerTubeServer) { |
53 | const parsed = magnetUtil.decode(file.magnetUri) | 38 | const parsed = magnetUtil.decode(file.magnetUri) |
54 | 39 | ||
55 | for (const ws of baseWebseeds) { | 40 | for (const ws of baseWebseeds) { |
56 | const found = parsed.urlList.find(url => url === `${ws}-${file.resolution.id}.mp4`) | 41 | const found = parsed.urlList.find(url => url === `${ws}${basename(file.fileUrl)}`) |
57 | expect(found, `Webseed ${ws} not found in ${file.magnetUri} on server ${server.url}`).to.not.be.undefined | 42 | expect(found, `Webseed ${ws} not found in ${file.magnetUri} on server ${server.url}`).to.not.be.undefined |
58 | } | 43 | } |
59 | 44 | ||
60 | expect(parsed.urlList).to.have.lengthOf(baseWebseeds.length) | 45 | expect(parsed.urlList).to.have.lengthOf(baseWebseeds.length) |
46 | |||
47 | for (const url of parsed.urlList) { | ||
48 | await makeRawRequest(url, HttpStatusCode.OK_200) | ||
49 | } | ||
61 | } | 50 | } |
62 | 51 | ||
63 | async function flushAndRunServers (strategy: VideoRedundancyStrategy | null, additionalParams: any = {}, withWebtorrent = true) { | 52 | async function createSingleServers (strategy: VideoRedundancyStrategy | null, additionalParams: any = {}, withWebtorrent = true) { |
64 | const strategies: any[] = [] | 53 | const strategies: any[] = [] |
65 | 54 | ||
66 | if (strategy !== null) { | 55 | if (strategy !== null) { |
67 | strategies.push( | 56 | strategies.push( |
68 | immutableAssign({ | 57 | { |
69 | min_lifetime: '1 hour', | 58 | min_lifetime: '1 hour', |
70 | strategy: strategy, | 59 | strategy: strategy, |
71 | size: '400KB' | 60 | size: '400KB', |
72 | }, additionalParams) | 61 | |
62 | ...additionalParams | ||
63 | } | ||
73 | ) | 64 | ) |
74 | } | 65 | } |
75 | 66 | ||
@@ -90,17 +81,16 @@ async function flushAndRunServers (strategy: VideoRedundancyStrategy | null, add | |||
90 | } | 81 | } |
91 | } | 82 | } |
92 | 83 | ||
93 | servers = await flushAndRunMultipleServers(3, config) | 84 | servers = await createMultipleServers(3, config) |
94 | 85 | ||
95 | // Get the access tokens | 86 | // Get the access tokens |
96 | await setAccessTokensToServers(servers) | 87 | await setAccessTokensToServers(servers) |
97 | 88 | ||
98 | { | 89 | { |
99 | const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 1 server 2' }) | 90 | const { id } = await servers[1].videos.upload({ attributes: { name: 'video 1 server 2' } }) |
100 | video1Server2UUID = res.body.video.uuid | 91 | video1Server2 = await servers[1].videos.get({ id }) |
101 | video1Server2Id = res.body.video.id | ||
102 | 92 | ||
103 | await viewVideo(servers[1].url, video1Server2UUID) | 93 | await servers[1].videos.view({ id }) |
104 | } | 94 | } |
105 | 95 | ||
106 | await waitJobs(servers) | 96 | await waitJobs(servers) |
@@ -115,55 +105,65 @@ async function flushAndRunServers (strategy: VideoRedundancyStrategy | null, add | |||
115 | await waitJobs(servers) | 105 | await waitJobs(servers) |
116 | } | 106 | } |
117 | 107 | ||
108 | async function ensureSameFilenames (videoUUID: string) { | ||
109 | let webtorrentFilenames: string[] | ||
110 | let hlsFilenames: string[] | ||
111 | |||
112 | for (const server of servers) { | ||
113 | const video = await server.videos.getWithToken({ id: videoUUID }) | ||
114 | |||
115 | // Ensure we use the same filenames that the origin | ||
116 | |||
117 | const localWebtorrentFilenames = video.files.map(f => basename(f.fileUrl)).sort() | ||
118 | const localHLSFilenames = video.streamingPlaylists[0].files.map(f => basename(f.fileUrl)).sort() | ||
119 | |||
120 | if (webtorrentFilenames) expect(webtorrentFilenames).to.deep.equal(localWebtorrentFilenames) | ||
121 | else webtorrentFilenames = localWebtorrentFilenames | ||
122 | |||
123 | if (hlsFilenames) expect(hlsFilenames).to.deep.equal(localHLSFilenames) | ||
124 | else hlsFilenames = localHLSFilenames | ||
125 | } | ||
126 | |||
127 | return { webtorrentFilenames, hlsFilenames } | ||
128 | } | ||
129 | |||
118 | async function check1WebSeed (videoUUID?: string) { | 130 | async function check1WebSeed (videoUUID?: string) { |
119 | if (!videoUUID) videoUUID = video1Server2UUID | 131 | if (!videoUUID) videoUUID = video1Server2.uuid |
120 | 132 | ||
121 | const webseeds = [ | 133 | const webseeds = [ |
122 | `http://localhost:${servers[1].port}/static/webseed/${videoUUID}` | 134 | `http://localhost:${servers[1].port}/static/webseed/` |
123 | ] | 135 | ] |
124 | 136 | ||
125 | for (const server of servers) { | 137 | for (const server of servers) { |
126 | // With token to avoid issues with video follow constraints | 138 | // With token to avoid issues with video follow constraints |
127 | const res = await getVideoWithToken(server.url, server.accessToken, videoUUID) | 139 | const video = await server.videos.getWithToken({ id: videoUUID }) |
128 | 140 | ||
129 | const video: VideoDetails = res.body | ||
130 | for (const f of video.files) { | 141 | for (const f of video.files) { |
131 | checkMagnetWebseeds(f, webseeds, server) | 142 | await checkMagnetWebseeds(f, webseeds, server) |
132 | } | 143 | } |
133 | } | 144 | } |
145 | |||
146 | await ensureSameFilenames(videoUUID) | ||
134 | } | 147 | } |
135 | 148 | ||
136 | async function check2Webseeds (videoUUID?: string) { | 149 | async function check2Webseeds (videoUUID?: string) { |
137 | if (!videoUUID) videoUUID = video1Server2UUID | 150 | if (!videoUUID) videoUUID = video1Server2.uuid |
138 | 151 | ||
139 | const webseeds = [ | 152 | const webseeds = [ |
140 | `http://localhost:${servers[0].port}/static/redundancy/${videoUUID}`, | 153 | `http://localhost:${servers[0].port}/static/redundancy/`, |
141 | `http://localhost:${servers[1].port}/static/webseed/${videoUUID}` | 154 | `http://localhost:${servers[1].port}/static/webseed/` |
142 | ] | 155 | ] |
143 | 156 | ||
144 | for (const server of servers) { | 157 | for (const server of servers) { |
145 | const res = await getVideo(server.url, videoUUID) | 158 | const video = await server.videos.get({ id: videoUUID }) |
146 | |||
147 | const video: VideoDetails = res.body | ||
148 | 159 | ||
149 | for (const file of video.files) { | 160 | for (const file of video.files) { |
150 | checkMagnetWebseeds(file, webseeds, server) | 161 | await checkMagnetWebseeds(file, webseeds, server) |
151 | |||
152 | await makeGetRequest({ | ||
153 | url: servers[0].url, | ||
154 | statusCodeExpected: HttpStatusCode.OK_200, | ||
155 | path: '/static/redundancy/' + `${videoUUID}-${file.resolution.id}.mp4`, | ||
156 | contentType: null | ||
157 | }) | ||
158 | await makeGetRequest({ | ||
159 | url: servers[1].url, | ||
160 | statusCodeExpected: HttpStatusCode.OK_200, | ||
161 | path: `/static/webseed/${videoUUID}-${file.resolution.id}.mp4`, | ||
162 | contentType: null | ||
163 | }) | ||
164 | } | 162 | } |
165 | } | 163 | } |
166 | 164 | ||
165 | const { webtorrentFilenames } = await ensureSameFilenames(videoUUID) | ||
166 | |||
167 | const directories = [ | 167 | const directories = [ |
168 | 'test' + servers[0].internalServerNumber + '/redundancy', | 168 | 'test' + servers[0].internalServerNumber + '/redundancy', |
169 | 'test' + servers[1].internalServerNumber + '/videos' | 169 | 'test' + servers[1].internalServerNumber + '/videos' |
@@ -173,32 +173,31 @@ async function check2Webseeds (videoUUID?: string) { | |||
173 | const files = await readdir(join(root(), directory)) | 173 | const files = await readdir(join(root(), directory)) |
174 | expect(files).to.have.length.at.least(4) | 174 | expect(files).to.have.length.at.least(4) |
175 | 175 | ||
176 | for (const resolution of [ 240, 360, 480, 720 ]) { | 176 | // Ensure we files exist on disk |
177 | expect(files.find(f => f === `${videoUUID}-${resolution}.mp4`)).to.not.be.undefined | 177 | expect(files.find(f => webtorrentFilenames.includes(f))).to.exist |
178 | } | ||
179 | } | 178 | } |
180 | } | 179 | } |
181 | 180 | ||
182 | async function check0PlaylistRedundancies (videoUUID?: string) { | 181 | async function check0PlaylistRedundancies (videoUUID?: string) { |
183 | if (!videoUUID) videoUUID = video1Server2UUID | 182 | if (!videoUUID) videoUUID = video1Server2.uuid |
184 | 183 | ||
185 | for (const server of servers) { | 184 | for (const server of servers) { |
186 | // With token to avoid issues with video follow constraints | 185 | // With token to avoid issues with video follow constraints |
187 | const res = await getVideoWithToken(server.url, server.accessToken, videoUUID) | 186 | const video = await server.videos.getWithToken({ id: videoUUID }) |
188 | const video: VideoDetails = res.body | ||
189 | 187 | ||
190 | expect(video.streamingPlaylists).to.be.an('array') | 188 | expect(video.streamingPlaylists).to.be.an('array') |
191 | expect(video.streamingPlaylists).to.have.lengthOf(1) | 189 | expect(video.streamingPlaylists).to.have.lengthOf(1) |
192 | expect(video.streamingPlaylists[0].redundancies).to.have.lengthOf(0) | 190 | expect(video.streamingPlaylists[0].redundancies).to.have.lengthOf(0) |
193 | } | 191 | } |
192 | |||
193 | await ensureSameFilenames(videoUUID) | ||
194 | } | 194 | } |
195 | 195 | ||
196 | async function check1PlaylistRedundancies (videoUUID?: string) { | 196 | async function check1PlaylistRedundancies (videoUUID?: string) { |
197 | if (!videoUUID) videoUUID = video1Server2UUID | 197 | if (!videoUUID) videoUUID = video1Server2.uuid |
198 | 198 | ||
199 | for (const server of servers) { | 199 | for (const server of servers) { |
200 | const res = await getVideo(server.url, videoUUID) | 200 | const video = await server.videos.get({ id: videoUUID }) |
201 | const video: VideoDetails = res.body | ||
202 | 201 | ||
203 | expect(video.streamingPlaylists).to.have.lengthOf(1) | 202 | expect(video.streamingPlaylists).to.have.lengthOf(1) |
204 | expect(video.streamingPlaylists[0].redundancies).to.have.lengthOf(1) | 203 | expect(video.streamingPlaylists[0].redundancies).to.have.lengthOf(1) |
@@ -211,13 +210,15 @@ async function check1PlaylistRedundancies (videoUUID?: string) { | |||
211 | const baseUrlPlaylist = servers[1].url + '/static/streaming-playlists/hls' | 210 | const baseUrlPlaylist = servers[1].url + '/static/streaming-playlists/hls' |
212 | const baseUrlSegment = servers[0].url + '/static/redundancy/hls' | 211 | const baseUrlSegment = servers[0].url + '/static/redundancy/hls' |
213 | 212 | ||
214 | const res = await getVideo(servers[0].url, videoUUID) | 213 | const video = await servers[0].videos.get({ id: videoUUID }) |
215 | const hlsPlaylist = (res.body as VideoDetails).streamingPlaylists[0] | 214 | const hlsPlaylist = video.streamingPlaylists[0] |
216 | 215 | ||
217 | for (const resolution of [ 240, 360, 480, 720 ]) { | 216 | for (const resolution of [ 240, 360, 480, 720 ]) { |
218 | await checkSegmentHash(baseUrlPlaylist, baseUrlSegment, videoUUID, resolution, hlsPlaylist) | 217 | await checkSegmentHash({ server: servers[1], baseUrlPlaylist, baseUrlSegment, videoUUID, resolution, hlsPlaylist }) |
219 | } | 218 | } |
220 | 219 | ||
220 | const { hlsFilenames } = await ensureSameFilenames(videoUUID) | ||
221 | |||
221 | const directories = [ | 222 | const directories = [ |
222 | 'test' + servers[0].internalServerNumber + '/redundancy/hls', | 223 | 'test' + servers[0].internalServerNumber + '/redundancy/hls', |
223 | 'test' + servers[1].internalServerNumber + '/streaming-playlists/hls' | 224 | 'test' + servers[1].internalServerNumber + '/streaming-playlists/hls' |
@@ -227,11 +228,8 @@ async function check1PlaylistRedundancies (videoUUID?: string) { | |||
227 | const files = await readdir(join(root(), directory, videoUUID)) | 228 | const files = await readdir(join(root(), directory, videoUUID)) |
228 | expect(files).to.have.length.at.least(4) | 229 | expect(files).to.have.length.at.least(4) |
229 | 230 | ||
230 | for (const resolution of [ 240, 360, 480, 720 ]) { | 231 | // Ensure we files exist on disk |
231 | const filename = `${videoUUID}-${resolution}-fragmented.mp4` | 232 | expect(files.find(f => hlsFilenames.includes(f))).to.exist |
232 | |||
233 | expect(files.find(f => f === filename)).to.not.be.undefined | ||
234 | } | ||
235 | } | 233 | } |
236 | } | 234 | } |
237 | 235 | ||
@@ -244,9 +242,7 @@ async function checkStatsGlobal (strategy: VideoRedundancyStrategyWithManual) { | |||
244 | statsLength = 2 | 242 | statsLength = 2 |
245 | } | 243 | } |
246 | 244 | ||
247 | const res = await getStats(servers[0].url) | 245 | const data = await servers[0].stats.get() |
248 | const data: ServerStats = res.body | ||
249 | |||
250 | expect(data.videosRedundancy).to.have.lengthOf(statsLength) | 246 | expect(data.videosRedundancy).to.have.lengthOf(statsLength) |
251 | 247 | ||
252 | const stat = data.videosRedundancy[0] | 248 | const stat = data.videosRedundancy[0] |
@@ -272,14 +268,20 @@ async function checkStatsWithoutRedundancy (strategy: VideoRedundancyStrategyWit | |||
272 | expect(stat.totalVideos).to.equal(0) | 268 | expect(stat.totalVideos).to.equal(0) |
273 | } | 269 | } |
274 | 270 | ||
275 | async function enableRedundancyOnServer1 () { | 271 | async function findServerFollows () { |
276 | await updateRedundancy(servers[0].url, servers[0].accessToken, servers[1].host, true) | 272 | const body = await servers[0].follows.getFollowings({ start: 0, count: 5, sort: '-createdAt' }) |
277 | 273 | const follows = body.data | |
278 | const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: '-createdAt' }) | ||
279 | const follows: ActorFollow[] = res.body.data | ||
280 | const server2 = follows.find(f => f.following.host === `localhost:${servers[1].port}`) | 274 | const server2 = follows.find(f => f.following.host === `localhost:${servers[1].port}`) |
281 | const server3 = follows.find(f => f.following.host === `localhost:${servers[2].port}`) | 275 | const server3 = follows.find(f => f.following.host === `localhost:${servers[2].port}`) |
282 | 276 | ||
277 | return { server2, server3 } | ||
278 | } | ||
279 | |||
280 | async function enableRedundancyOnServer1 () { | ||
281 | await servers[0].redundancy.updateRedundancy({ host: servers[1].host, redundancyAllowed: true }) | ||
282 | |||
283 | const { server2, server3 } = await findServerFollows() | ||
284 | |||
283 | expect(server3).to.not.be.undefined | 285 | expect(server3).to.not.be.undefined |
284 | expect(server3.following.hostRedundancyAllowed).to.be.false | 286 | expect(server3.following.hostRedundancyAllowed).to.be.false |
285 | 287 | ||
@@ -288,12 +290,9 @@ async function enableRedundancyOnServer1 () { | |||
288 | } | 290 | } |
289 | 291 | ||
290 | async function disableRedundancyOnServer1 () { | 292 | async function disableRedundancyOnServer1 () { |
291 | await updateRedundancy(servers[0].url, servers[0].accessToken, servers[1].host, false) | 293 | await servers[0].redundancy.updateRedundancy({ host: servers[1].host, redundancyAllowed: false }) |
292 | 294 | ||
293 | const res = await getFollowingListPaginationAndSort({ url: servers[0].url, start: 0, count: 5, sort: '-createdAt' }) | 295 | const { server2, server3 } = await findServerFollows() |
294 | const follows: ActorFollow[] = res.body.data | ||
295 | const server2 = follows.find(f => f.following.host === `localhost:${servers[1].port}`) | ||
296 | const server3 = follows.find(f => f.following.host === `localhost:${servers[2].port}`) | ||
297 | 296 | ||
298 | expect(server3).to.not.be.undefined | 297 | expect(server3).to.not.be.undefined |
299 | expect(server3.following.hostRedundancyAllowed).to.be.false | 298 | expect(server3.following.hostRedundancyAllowed).to.be.false |
@@ -310,7 +309,7 @@ describe('Test videos redundancy', function () { | |||
310 | before(function () { | 309 | before(function () { |
311 | this.timeout(120000) | 310 | this.timeout(120000) |
312 | 311 | ||
313 | return flushAndRunServers(strategy) | 312 | return createSingleServers(strategy) |
314 | }) | 313 | }) |
315 | 314 | ||
316 | it('Should have 1 webseed on the first video', async function () { | 315 | it('Should have 1 webseed on the first video', async function () { |
@@ -327,7 +326,7 @@ describe('Test videos redundancy', function () { | |||
327 | this.timeout(80000) | 326 | this.timeout(80000) |
328 | 327 | ||
329 | await waitJobs(servers) | 328 | await waitJobs(servers) |
330 | await waitUntilLog(servers[0], 'Duplicated ', 5) | 329 | await servers[0].servers.waitUntilLog('Duplicated ', 5) |
331 | await waitJobs(servers) | 330 | await waitJobs(servers) |
332 | 331 | ||
333 | await check2Webseeds() | 332 | await check2Webseeds() |
@@ -346,7 +345,7 @@ describe('Test videos redundancy', function () { | |||
346 | await check1WebSeed() | 345 | await check1WebSeed() |
347 | await check0PlaylistRedundancies() | 346 | await check0PlaylistRedundancies() |
348 | 347 | ||
349 | await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].internalServerNumber, [ 'videos', join('playlists', 'hls') ]) | 348 | await checkVideoFilesWereRemoved({ server: servers[0], video: video1Server2, onlyVideoFiles: true }) |
350 | }) | 349 | }) |
351 | 350 | ||
352 | after(async function () { | 351 | after(async function () { |
@@ -360,7 +359,7 @@ describe('Test videos redundancy', function () { | |||
360 | before(function () { | 359 | before(function () { |
361 | this.timeout(120000) | 360 | this.timeout(120000) |
362 | 361 | ||
363 | return flushAndRunServers(strategy) | 362 | return createSingleServers(strategy) |
364 | }) | 363 | }) |
365 | 364 | ||
366 | it('Should have 1 webseed on the first video', async function () { | 365 | it('Should have 1 webseed on the first video', async function () { |
@@ -377,7 +376,7 @@ describe('Test videos redundancy', function () { | |||
377 | this.timeout(80000) | 376 | this.timeout(80000) |
378 | 377 | ||
379 | await waitJobs(servers) | 378 | await waitJobs(servers) |
380 | await waitUntilLog(servers[0], 'Duplicated ', 5) | 379 | await servers[0].servers.waitUntilLog('Duplicated ', 5) |
381 | await waitJobs(servers) | 380 | await waitJobs(servers) |
382 | 381 | ||
383 | await check2Webseeds() | 382 | await check2Webseeds() |
@@ -388,7 +387,7 @@ describe('Test videos redundancy', function () { | |||
388 | it('Should unfollow on server 1 and remove duplicated videos', async function () { | 387 | it('Should unfollow on server 1 and remove duplicated videos', async function () { |
389 | this.timeout(80000) | 388 | this.timeout(80000) |
390 | 389 | ||
391 | await unfollow(servers[0].url, servers[0].accessToken, servers[1]) | 390 | await servers[0].follows.unfollow({ target: servers[1] }) |
392 | 391 | ||
393 | await waitJobs(servers) | 392 | await waitJobs(servers) |
394 | await wait(5000) | 393 | await wait(5000) |
@@ -396,7 +395,7 @@ describe('Test videos redundancy', function () { | |||
396 | await check1WebSeed() | 395 | await check1WebSeed() |
397 | await check0PlaylistRedundancies() | 396 | await check0PlaylistRedundancies() |
398 | 397 | ||
399 | await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].internalServerNumber, [ 'videos' ]) | 398 | await checkVideoFilesWereRemoved({ server: servers[0], video: video1Server2, onlyVideoFiles: true }) |
400 | }) | 399 | }) |
401 | 400 | ||
402 | after(async function () { | 401 | after(async function () { |
@@ -410,7 +409,7 @@ describe('Test videos redundancy', function () { | |||
410 | before(function () { | 409 | before(function () { |
411 | this.timeout(120000) | 410 | this.timeout(120000) |
412 | 411 | ||
413 | return flushAndRunServers(strategy, { min_views: 3 }) | 412 | return createSingleServers(strategy, { min_views: 3 }) |
414 | }) | 413 | }) |
415 | 414 | ||
416 | it('Should have 1 webseed on the first video', async function () { | 415 | it('Should have 1 webseed on the first video', async function () { |
@@ -438,8 +437,8 @@ describe('Test videos redundancy', function () { | |||
438 | it('Should view 2 times the first video to have > min_views config', async function () { | 437 | it('Should view 2 times the first video to have > min_views config', async function () { |
439 | this.timeout(80000) | 438 | this.timeout(80000) |
440 | 439 | ||
441 | await viewVideo(servers[0].url, video1Server2UUID) | 440 | await servers[0].videos.view({ id: video1Server2.uuid }) |
442 | await viewVideo(servers[2].url, video1Server2UUID) | 441 | await servers[2].videos.view({ id: video1Server2.uuid }) |
443 | 442 | ||
444 | await wait(10000) | 443 | await wait(10000) |
445 | await waitJobs(servers) | 444 | await waitJobs(servers) |
@@ -449,7 +448,7 @@ describe('Test videos redundancy', function () { | |||
449 | this.timeout(80000) | 448 | this.timeout(80000) |
450 | 449 | ||
451 | await waitJobs(servers) | 450 | await waitJobs(servers) |
452 | await waitUntilLog(servers[0], 'Duplicated ', 5) | 451 | await servers[0].servers.waitUntilLog('Duplicated ', 5) |
453 | await waitJobs(servers) | 452 | await waitJobs(servers) |
454 | 453 | ||
455 | await check2Webseeds() | 454 | await check2Webseeds() |
@@ -460,12 +459,13 @@ describe('Test videos redundancy', function () { | |||
460 | it('Should remove the video and the redundancy files', async function () { | 459 | it('Should remove the video and the redundancy files', async function () { |
461 | this.timeout(20000) | 460 | this.timeout(20000) |
462 | 461 | ||
463 | await removeVideo(servers[1].url, servers[1].accessToken, video1Server2UUID) | 462 | await saveVideoInServers(servers, video1Server2.uuid) |
463 | await servers[1].videos.remove({ id: video1Server2.uuid }) | ||
464 | 464 | ||
465 | await waitJobs(servers) | 465 | await waitJobs(servers) |
466 | 466 | ||
467 | for (const server of servers) { | 467 | for (const server of servers) { |
468 | await checkVideoFilesWereRemoved(video1Server2UUID, server.internalServerNumber) | 468 | await checkVideoFilesWereRemoved({ server, video: server.store.videoDetails }) |
469 | } | 469 | } |
470 | }) | 470 | }) |
471 | 471 | ||
@@ -480,7 +480,7 @@ describe('Test videos redundancy', function () { | |||
480 | before(async function () { | 480 | before(async function () { |
481 | this.timeout(120000) | 481 | this.timeout(120000) |
482 | 482 | ||
483 | await flushAndRunServers(strategy, { min_views: 3 }, false) | 483 | await createSingleServers(strategy, { min_views: 3 }, false) |
484 | }) | 484 | }) |
485 | 485 | ||
486 | it('Should have 0 playlist redundancy on the first video', async function () { | 486 | it('Should have 0 playlist redundancy on the first video', async function () { |
@@ -506,14 +506,14 @@ describe('Test videos redundancy', function () { | |||
506 | it('Should have 1 redundancy on the first video', async function () { | 506 | it('Should have 1 redundancy on the first video', async function () { |
507 | this.timeout(160000) | 507 | this.timeout(160000) |
508 | 508 | ||
509 | await viewVideo(servers[0].url, video1Server2UUID) | 509 | await servers[0].videos.view({ id: video1Server2.uuid }) |
510 | await viewVideo(servers[2].url, video1Server2UUID) | 510 | await servers[2].videos.view({ id: video1Server2.uuid }) |
511 | 511 | ||
512 | await wait(10000) | 512 | await wait(10000) |
513 | await waitJobs(servers) | 513 | await waitJobs(servers) |
514 | 514 | ||
515 | await waitJobs(servers) | 515 | await waitJobs(servers) |
516 | await waitUntilLog(servers[0], 'Duplicated ', 1) | 516 | await servers[0].servers.waitUntilLog('Duplicated ', 1) |
517 | await waitJobs(servers) | 517 | await waitJobs(servers) |
518 | 518 | ||
519 | await check1PlaylistRedundancies() | 519 | await check1PlaylistRedundancies() |
@@ -523,12 +523,13 @@ describe('Test videos redundancy', function () { | |||
523 | it('Should remove the video and the redundancy files', async function () { | 523 | it('Should remove the video and the redundancy files', async function () { |
524 | this.timeout(20000) | 524 | this.timeout(20000) |
525 | 525 | ||
526 | await removeVideo(servers[1].url, servers[1].accessToken, video1Server2UUID) | 526 | await saveVideoInServers(servers, video1Server2.uuid) |
527 | await servers[1].videos.remove({ id: video1Server2.uuid }) | ||
527 | 528 | ||
528 | await waitJobs(servers) | 529 | await waitJobs(servers) |
529 | 530 | ||
530 | for (const server of servers) { | 531 | for (const server of servers) { |
531 | await checkVideoFilesWereRemoved(video1Server2UUID, server.internalServerNumber) | 532 | await checkVideoFilesWereRemoved({ server, video: server.store.videoDetails }) |
532 | } | 533 | } |
533 | }) | 534 | }) |
534 | 535 | ||
@@ -541,7 +542,7 @@ describe('Test videos redundancy', function () { | |||
541 | before(function () { | 542 | before(function () { |
542 | this.timeout(120000) | 543 | this.timeout(120000) |
543 | 544 | ||
544 | return flushAndRunServers(null) | 545 | return createSingleServers(null) |
545 | }) | 546 | }) |
546 | 547 | ||
547 | it('Should have 1 webseed on the first video', async function () { | 548 | it('Should have 1 webseed on the first video', async function () { |
@@ -551,18 +552,14 @@ describe('Test videos redundancy', function () { | |||
551 | }) | 552 | }) |
552 | 553 | ||
553 | it('Should create a redundancy on first video', async function () { | 554 | it('Should create a redundancy on first video', async function () { |
554 | await addVideoRedundancy({ | 555 | await servers[0].redundancy.addVideo({ videoId: video1Server2.id }) |
555 | url: servers[0].url, | ||
556 | accessToken: servers[0].accessToken, | ||
557 | videoId: video1Server2Id | ||
558 | }) | ||
559 | }) | 556 | }) |
560 | 557 | ||
561 | it('Should have 2 webseeds on the first video', async function () { | 558 | it('Should have 2 webseeds on the first video', async function () { |
562 | this.timeout(80000) | 559 | this.timeout(80000) |
563 | 560 | ||
564 | await waitJobs(servers) | 561 | await waitJobs(servers) |
565 | await waitUntilLog(servers[0], 'Duplicated ', 5) | 562 | await servers[0].servers.waitUntilLog('Duplicated ', 5) |
566 | await waitJobs(servers) | 563 | await waitJobs(servers) |
567 | 564 | ||
568 | await check2Webseeds() | 565 | await check2Webseeds() |
@@ -573,22 +570,15 @@ describe('Test videos redundancy', function () { | |||
573 | it('Should manually remove redundancies on server 1 and remove duplicated videos', async function () { | 570 | it('Should manually remove redundancies on server 1 and remove duplicated videos', async function () { |
574 | this.timeout(80000) | 571 | this.timeout(80000) |
575 | 572 | ||
576 | const res = await listVideoRedundancies({ | 573 | const body = await servers[0].redundancy.listVideos({ target: 'remote-videos' }) |
577 | url: servers[0].url, | ||
578 | accessToken: servers[0].accessToken, | ||
579 | target: 'remote-videos' | ||
580 | }) | ||
581 | 574 | ||
582 | const videos = res.body.data as VideoRedundancy[] | 575 | const videos = body.data |
583 | expect(videos).to.have.lengthOf(1) | 576 | expect(videos).to.have.lengthOf(1) |
584 | 577 | ||
585 | const video = videos[0] | 578 | const video = videos[0] |
579 | |||
586 | for (const r of video.redundancies.files.concat(video.redundancies.streamingPlaylists)) { | 580 | for (const r of video.redundancies.files.concat(video.redundancies.streamingPlaylists)) { |
587 | await removeVideoRedundancy({ | 581 | await servers[0].redundancy.removeVideo({ redundancyId: r.id }) |
588 | url: servers[0].url, | ||
589 | accessToken: servers[0].accessToken, | ||
590 | redundancyId: r.id | ||
591 | }) | ||
592 | } | 582 | } |
593 | 583 | ||
594 | await waitJobs(servers) | 584 | await waitJobs(servers) |
@@ -597,7 +587,7 @@ describe('Test videos redundancy', function () { | |||
597 | await check1WebSeed() | 587 | await check1WebSeed() |
598 | await check0PlaylistRedundancies() | 588 | await check0PlaylistRedundancies() |
599 | 589 | ||
600 | await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos' ]) | 590 | await checkVideoFilesWereRemoved({ server: servers[0], video: video1Server2, onlyVideoFiles: true }) |
601 | }) | 591 | }) |
602 | 592 | ||
603 | after(async function () { | 593 | after(async function () { |
@@ -608,10 +598,9 @@ describe('Test videos redundancy', function () { | |||
608 | describe('Test expiration', function () { | 598 | describe('Test expiration', function () { |
609 | const strategy = 'recently-added' | 599 | const strategy = 'recently-added' |
610 | 600 | ||
611 | async function checkContains (servers: ServerInfo[], str: string) { | 601 | async function checkContains (servers: PeerTubeServer[], str: string) { |
612 | for (const server of servers) { | 602 | for (const server of servers) { |
613 | const res = await getVideo(server.url, video1Server2UUID) | 603 | const video = await server.videos.get({ id: video1Server2.uuid }) |
614 | const video: VideoDetails = res.body | ||
615 | 604 | ||
616 | for (const f of video.files) { | 605 | for (const f of video.files) { |
617 | expect(f.magnetUri).to.contain(str) | 606 | expect(f.magnetUri).to.contain(str) |
@@ -619,10 +608,9 @@ describe('Test videos redundancy', function () { | |||
619 | } | 608 | } |
620 | } | 609 | } |
621 | 610 | ||
622 | async function checkNotContains (servers: ServerInfo[], str: string) { | 611 | async function checkNotContains (servers: PeerTubeServer[], str: string) { |
623 | for (const server of servers) { | 612 | for (const server of servers) { |
624 | const res = await getVideo(server.url, video1Server2UUID) | 613 | const video = await server.videos.get({ id: video1Server2.uuid }) |
625 | const video: VideoDetails = res.body | ||
626 | 614 | ||
627 | for (const f of video.files) { | 615 | for (const f of video.files) { |
628 | expect(f.magnetUri).to.not.contain(str) | 616 | expect(f.magnetUri).to.not.contain(str) |
@@ -633,7 +621,7 @@ describe('Test videos redundancy', function () { | |||
633 | before(async function () { | 621 | before(async function () { |
634 | this.timeout(120000) | 622 | this.timeout(120000) |
635 | 623 | ||
636 | await flushAndRunServers(strategy, { min_lifetime: '7 seconds', min_views: 0 }) | 624 | await createSingleServers(strategy, { min_lifetime: '7 seconds', min_views: 0 }) |
637 | 625 | ||
638 | await enableRedundancyOnServer1() | 626 | await enableRedundancyOnServer1() |
639 | }) | 627 | }) |
@@ -656,7 +644,7 @@ describe('Test videos redundancy', function () { | |||
656 | it('Should stop server 1 and expire video redundancy', async function () { | 644 | it('Should stop server 1 and expire video redundancy', async function () { |
657 | this.timeout(80000) | 645 | this.timeout(80000) |
658 | 646 | ||
659 | killallServers([ servers[0] ]) | 647 | await killallServers([ servers[0] ]) |
660 | 648 | ||
661 | await wait(15000) | 649 | await wait(15000) |
662 | 650 | ||
@@ -675,25 +663,25 @@ describe('Test videos redundancy', function () { | |||
675 | before(async function () { | 663 | before(async function () { |
676 | this.timeout(120000) | 664 | this.timeout(120000) |
677 | 665 | ||
678 | await flushAndRunServers(strategy, { min_lifetime: '7 seconds', min_views: 0 }) | 666 | await createSingleServers(strategy, { min_lifetime: '7 seconds', min_views: 0 }) |
679 | 667 | ||
680 | await enableRedundancyOnServer1() | 668 | await enableRedundancyOnServer1() |
681 | 669 | ||
682 | await waitJobs(servers) | 670 | await waitJobs(servers) |
683 | await waitUntilLog(servers[0], 'Duplicated ', 5) | 671 | await servers[0].servers.waitUntilLog('Duplicated ', 5) |
684 | await waitJobs(servers) | 672 | await waitJobs(servers) |
685 | 673 | ||
686 | await check2Webseeds(video1Server2UUID) | 674 | await check2Webseeds() |
687 | await check1PlaylistRedundancies(video1Server2UUID) | 675 | await check1PlaylistRedundancies() |
688 | await checkStatsWith1Redundancy(strategy) | 676 | await checkStatsWith1Redundancy(strategy) |
689 | 677 | ||
690 | const res = await uploadVideo(servers[1].url, servers[1].accessToken, { name: 'video 2 server 2', privacy: VideoPrivacy.PRIVATE }) | 678 | const { uuid } = await servers[1].videos.upload({ attributes: { name: 'video 2 server 2', privacy: VideoPrivacy.PRIVATE } }) |
691 | video2Server2UUID = res.body.video.uuid | 679 | video2Server2UUID = uuid |
692 | 680 | ||
693 | // Wait transcoding before federation | 681 | // Wait transcoding before federation |
694 | await waitJobs(servers) | 682 | await waitJobs(servers) |
695 | 683 | ||
696 | await updateVideo(servers[1].url, servers[1].accessToken, video2Server2UUID, { privacy: VideoPrivacy.PUBLIC }) | 684 | await servers[1].videos.update({ id: video2Server2UUID, attributes: { privacy: VideoPrivacy.PUBLIC } }) |
697 | }) | 685 | }) |
698 | 686 | ||
699 | it('Should cache video 2 webseeds on the first video', async function () { | 687 | it('Should cache video 2 webseeds on the first video', async function () { |
@@ -707,8 +695,8 @@ describe('Test videos redundancy', function () { | |||
707 | await wait(1000) | 695 | await wait(1000) |
708 | 696 | ||
709 | try { | 697 | try { |
710 | await check1WebSeed(video1Server2UUID) | 698 | await check1WebSeed() |
711 | await check0PlaylistRedundancies(video1Server2UUID) | 699 | await check0PlaylistRedundancies() |
712 | 700 | ||
713 | await check2Webseeds(video2Server2UUID) | 701 | await check2Webseeds(video2Server2UUID) |
714 | await check1PlaylistRedundancies(video2Server2UUID) | 702 | await check1PlaylistRedundancies(video2Server2UUID) |
@@ -725,8 +713,8 @@ describe('Test videos redundancy', function () { | |||
725 | 713 | ||
726 | await waitJobs(servers) | 714 | await waitJobs(servers) |
727 | 715 | ||
728 | killallServers([ servers[0] ]) | 716 | await killallServers([ servers[0] ]) |
729 | await reRunServer(servers[0], { | 717 | await servers[0].run({ |
730 | redundancy: { | 718 | redundancy: { |
731 | videos: { | 719 | videos: { |
732 | check_interval: '1 second', | 720 | check_interval: '1 second', |
@@ -737,7 +725,7 @@ describe('Test videos redundancy', function () { | |||
737 | 725 | ||
738 | await waitJobs(servers) | 726 | await waitJobs(servers) |
739 | 727 | ||
740 | await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].internalServerNumber, [ join('redundancy', 'hls') ]) | 728 | await checkVideoFilesWereRemoved({ server: servers[0], video: video1Server2, onlyVideoFiles: true }) |
741 | }) | 729 | }) |
742 | 730 | ||
743 | after(async function () { | 731 | after(async function () { |