diff options
Diffstat (limited to 'server/tests/api/redundancy/redundancy.ts')
-rw-r--r-- | server/tests/api/redundancy/redundancy.ts | 298 |
1 files changed, 143 insertions, 155 deletions
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 () { |