]>
Commit | Line | Data |
---|---|---|
1 | /* tslint:disable:no-unused-expression */ | |
2 | ||
3 | import * as chai from 'chai' | |
4 | import 'mocha' | |
5 | import { VideoDetails } from '../../../../shared/models/videos' | |
6 | import { | |
7 | doubleFollow, | |
8 | flushAndRunMultipleServers, | |
9 | flushTests, | |
10 | getFollowingListPaginationAndSort, | |
11 | getVideo, | |
12 | killallServers, | |
13 | ServerInfo, | |
14 | setAccessTokensToServers, | |
15 | uploadVideo, | |
16 | wait, | |
17 | root, viewVideo, immutableAssign | |
18 | } from '../../utils' | |
19 | import { waitJobs } from '../../utils/server/jobs' | |
20 | import * as magnetUtil from 'magnet-uri' | |
21 | import { updateRedundancy } from '../../utils/server/redundancy' | |
22 | import { ActorFollow } from '../../../../shared/models/actors' | |
23 | import { readdir } from 'fs-extra' | |
24 | import { join } from 'path' | |
25 | import { VideoRedundancyStrategy } from '../../../../shared/models/redundancy' | |
26 | import { getStats } from '../../utils/server/stats' | |
27 | import { ServerStats } from '../../../../shared/models/server/server-stats.model' | |
28 | ||
29 | const expect = chai.expect | |
30 | ||
31 | let servers: ServerInfo[] = [] | |
32 | let video1Server2UUID: string | |
33 | let video2Server2UUID: string | |
34 | ||
35 | function checkMagnetWebseeds (file: { magnetUri: string, resolution: { id: number } }, baseWebseeds: string[]) { | |
36 | const parsed = magnetUtil.decode(file.magnetUri) | |
37 | ||
38 | for (const ws of baseWebseeds) { | |
39 | const found = parsed.urlList.find(url => url === `${ws}-${file.resolution.id}.mp4`) | |
40 | expect(found, `Webseed ${ws} not found in ${file.magnetUri}`).to.not.be.undefined | |
41 | } | |
42 | } | |
43 | ||
44 | async function runServers (strategy: VideoRedundancyStrategy, additionalParams: any = {}) { | |
45 | const config = { | |
46 | redundancy: { | |
47 | videos: [ | |
48 | immutableAssign({ | |
49 | strategy: strategy, | |
50 | size: '100KB' | |
51 | }, additionalParams) | |
52 | ] | |
53 | } | |
54 | } | |
55 | servers = await flushAndRunMultipleServers(3, config) | |
56 | ||
57 | // Get the access tokens | |
58 | await setAccessTokensToServers(servers) | |
59 | ||
60 | { | |
61 | const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video 1 server 2' }) | |
62 | video1Server2UUID = res.body.video.uuid | |
63 | ||
64 | await viewVideo(servers[ 1 ].url, video1Server2UUID) | |
65 | } | |
66 | ||
67 | { | |
68 | const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video 2 server 2' }) | |
69 | video2Server2UUID = res.body.video.uuid | |
70 | } | |
71 | ||
72 | await waitJobs(servers) | |
73 | ||
74 | // Server 1 and server 2 follow each other | |
75 | await doubleFollow(servers[ 0 ], servers[ 1 ]) | |
76 | // Server 1 and server 3 follow each other | |
77 | await doubleFollow(servers[ 0 ], servers[ 2 ]) | |
78 | // Server 2 and server 3 follow each other | |
79 | await doubleFollow(servers[ 1 ], servers[ 2 ]) | |
80 | ||
81 | await waitJobs(servers) | |
82 | } | |
83 | ||
84 | async function check1WebSeed (strategy: VideoRedundancyStrategy) { | |
85 | const webseeds = [ | |
86 | 'http://localhost:9002/static/webseed/' + video1Server2UUID | |
87 | ] | |
88 | ||
89 | for (const server of servers) { | |
90 | { | |
91 | const res = await getVideo(server.url, video1Server2UUID) | |
92 | ||
93 | const video: VideoDetails = res.body | |
94 | video.files.forEach(f => checkMagnetWebseeds(f, webseeds)) | |
95 | } | |
96 | ||
97 | { | |
98 | const res = await getStats(server.url) | |
99 | const data: ServerStats = res.body | |
100 | ||
101 | expect(data.videosRedundancy).to.have.lengthOf(1) | |
102 | ||
103 | const stat = data.videosRedundancy[0] | |
104 | expect(stat.strategy).to.equal(strategy) | |
105 | expect(stat.totalSize).to.equal(102400) | |
106 | expect(stat.totalUsed).to.equal(0) | |
107 | expect(stat.totalVideoFiles).to.equal(0) | |
108 | expect(stat.totalVideos).to.equal(0) | |
109 | } | |
110 | } | |
111 | } | |
112 | ||
113 | async function enableRedundancy () { | |
114 | await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, true) | |
115 | ||
116 | const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 5, '-createdAt') | |
117 | const follows: ActorFollow[] = res.body.data | |
118 | const server2 = follows.find(f => f.following.host === 'localhost:9002') | |
119 | const server3 = follows.find(f => f.following.host === 'localhost:9003') | |
120 | ||
121 | expect(server3).to.not.be.undefined | |
122 | expect(server3.following.hostRedundancyAllowed).to.be.false | |
123 | ||
124 | expect(server2).to.not.be.undefined | |
125 | expect(server2.following.hostRedundancyAllowed).to.be.true | |
126 | } | |
127 | ||
128 | async function check2Webseeds (strategy: VideoRedundancyStrategy) { | |
129 | await waitJobs(servers) | |
130 | await wait(15000) | |
131 | await waitJobs(servers) | |
132 | ||
133 | const webseeds = [ | |
134 | 'http://localhost:9001/static/webseed/' + video1Server2UUID, | |
135 | 'http://localhost:9002/static/webseed/' + video1Server2UUID | |
136 | ] | |
137 | ||
138 | for (const server of servers) { | |
139 | { | |
140 | const res = await getVideo(server.url, video1Server2UUID) | |
141 | ||
142 | const video: VideoDetails = res.body | |
143 | ||
144 | for (const file of video.files) { | |
145 | checkMagnetWebseeds(file, webseeds) | |
146 | } | |
147 | } | |
148 | } | |
149 | ||
150 | const files = await readdir(join(root(), 'test1', 'videos')) | |
151 | expect(files).to.have.lengthOf(4) | |
152 | ||
153 | for (const resolution of [ 240, 360, 480, 720 ]) { | |
154 | expect(files.find(f => f === `${video1Server2UUID}-${resolution}.mp4`)).to.not.be.undefined | |
155 | } | |
156 | ||
157 | { | |
158 | const res = await getStats(servers[0].url) | |
159 | const data: ServerStats = res.body | |
160 | ||
161 | expect(data.videosRedundancy).to.have.lengthOf(1) | |
162 | const stat = data.videosRedundancy[0] | |
163 | ||
164 | expect(stat.strategy).to.equal(strategy) | |
165 | expect(stat.totalSize).to.equal(102400) | |
166 | expect(stat.totalUsed).to.be.at.least(1).and.below(102401) | |
167 | expect(stat.totalVideoFiles).to.equal(4) | |
168 | expect(stat.totalVideos).to.equal(1) | |
169 | } | |
170 | } | |
171 | ||
172 | async function cleanServers () { | |
173 | killallServers(servers) | |
174 | } | |
175 | ||
176 | describe('Test videos redundancy', function () { | |
177 | ||
178 | describe('With most-views strategy', function () { | |
179 | const strategy = 'most-views' | |
180 | ||
181 | before(function () { | |
182 | this.timeout(120000) | |
183 | ||
184 | return runServers(strategy) | |
185 | }) | |
186 | ||
187 | it('Should have 1 webseed on the first video', function () { | |
188 | return check1WebSeed(strategy) | |
189 | }) | |
190 | ||
191 | it('Should enable redundancy on server 1', function () { | |
192 | return enableRedundancy() | |
193 | }) | |
194 | ||
195 | it('Should have 2 webseed on the first video', function () { | |
196 | this.timeout(40000) | |
197 | ||
198 | return check2Webseeds(strategy) | |
199 | }) | |
200 | ||
201 | after(function () { | |
202 | return cleanServers() | |
203 | }) | |
204 | }) | |
205 | ||
206 | describe('With trending strategy', function () { | |
207 | const strategy = 'trending' | |
208 | ||
209 | before(function () { | |
210 | this.timeout(120000) | |
211 | ||
212 | return runServers(strategy) | |
213 | }) | |
214 | ||
215 | it('Should have 1 webseed on the first video', function () { | |
216 | return check1WebSeed(strategy) | |
217 | }) | |
218 | ||
219 | it('Should enable redundancy on server 1', function () { | |
220 | return enableRedundancy() | |
221 | }) | |
222 | ||
223 | it('Should have 2 webseed on the first video', function () { | |
224 | this.timeout(40000) | |
225 | ||
226 | return check2Webseeds(strategy) | |
227 | }) | |
228 | ||
229 | after(function () { | |
230 | return cleanServers() | |
231 | }) | |
232 | }) | |
233 | ||
234 | describe('With recently added strategy', function () { | |
235 | const strategy = 'recently-added' | |
236 | ||
237 | before(function () { | |
238 | this.timeout(120000) | |
239 | ||
240 | return runServers(strategy, { minViews: 3 }) | |
241 | }) | |
242 | ||
243 | it('Should have 1 webseed on the first video', function () { | |
244 | return check1WebSeed(strategy) | |
245 | }) | |
246 | ||
247 | it('Should enable redundancy on server 1', function () { | |
248 | return enableRedundancy() | |
249 | }) | |
250 | ||
251 | it('Should still have 1 webseed on the first video', async function () { | |
252 | this.timeout(40000) | |
253 | ||
254 | await waitJobs(servers) | |
255 | await wait(15000) | |
256 | await waitJobs(servers) | |
257 | ||
258 | return check1WebSeed(strategy) | |
259 | }) | |
260 | ||
261 | it('Should view 2 times the first video', async function () { | |
262 | this.timeout(40000) | |
263 | ||
264 | await viewVideo(servers[ 0 ].url, video1Server2UUID) | |
265 | await viewVideo(servers[ 2 ].url, video1Server2UUID) | |
266 | ||
267 | await wait(10000) | |
268 | await waitJobs(servers) | |
269 | }) | |
270 | ||
271 | it('Should have 2 webseed on the first video', function () { | |
272 | this.timeout(40000) | |
273 | ||
274 | return check2Webseeds(strategy) | |
275 | }) | |
276 | ||
277 | after(function () { | |
278 | return cleanServers() | |
279 | }) | |
280 | }) | |
281 | }) |