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