]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/server/handle-down.ts
Introduce accounts command
[github/Chocobozzz/PeerTube.git] / server / tests / api / server / handle-down.ts
CommitLineData
a1587156 1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2ccaeeb3 2
2ccaeeb3 3import 'mocha'
c3d29f69
C
4import * as chai from 'chai'
5import { HttpStatusCode } from '@shared/core-utils'
2ccaeeb3 6import {
c3d29f69
C
7 addVideoCommentReply,
8 addVideoCommentThread,
7c3b7976 9 cleanupTests,
a1587156 10 closeAllSequelize,
9639bd17 11 completeVideoCheck,
94831479 12 flushAndRunMultipleServers,
a4101923 13 getVideo,
c3d29f69 14 getVideoCommentThreads,
94831479 15 getVideosList,
c3d29f69 16 getVideoThreadComments,
a4101923 17 immutableAssign,
94831479 18 killallServers,
a4101923 19 reRunServer,
94831479
C
20 ServerInfo,
21 setAccessTokensToServers,
a1587156 22 setActorFollowScores,
ae28cdf3 23 updateVideo,
a1587156
C
24 uploadVideo,
25 uploadVideoAndGetId,
c3d29f69
C
26 wait,
27 waitJobs
28} from '@shared/extra-utils'
29import { JobState, Video, VideoCommentThreadTree, VideoPrivacy } from '@shared/models'
2ccaeeb3
C
30
31const expect = chai.expect
32
33describe('Test handle downs', function () {
34 let servers: ServerInfo[] = []
7bc29171
C
35 let threadIdServer1: number
36 let threadIdServer2: number
37 let commentIdServer1: number
38 let commentIdServer2: number
cc6373e6
C
39 let missedVideo1: Video
40 let missedVideo2: Video
41 let unlistedVideo: Video
2ccaeeb3 42
d4a8e7a6 43 const videoIdsServer1: string[] = []
6b9c966f 44
2ccaeeb3
C
45 const videoAttributes = {
46 name: 'my super name for server 1',
47 category: 5,
48 licence: 4,
9d3ef9fe 49 language: 'ja',
2ccaeeb3 50 nsfw: true,
7bc29171 51 privacy: VideoPrivacy.PUBLIC,
2ccaeeb3 52 description: 'my super description for server 1',
2422c46b 53 support: 'my super support text for server 1',
2ccaeeb3
C
54 tags: [ 'tag1p1', 'tag2p1' ],
55 fixture: 'video_short1.webm'
56 }
57
7bc29171
C
58 const unlistedVideoAttributes = immutableAssign(videoAttributes, {
59 privacy: VideoPrivacy.UNLISTED
60 })
61
48f07b4a
C
62 let checkAttributes: any
63 let unlistedCheckAttributes: any
7bc29171 64
2ccaeeb3 65 before(async function () {
e212f887 66 this.timeout(30000)
2ccaeeb3 67
cc6373e6 68 servers = await flushAndRunMultipleServers(3)
2ccaeeb3 69
48f07b4a
C
70 checkAttributes = {
71 name: 'my super name for server 1',
72 category: 5,
73 licence: 4,
74 language: 'ja',
75 nsfw: true,
76 description: 'my super description for server 1',
77 support: 'my super support text for server 1',
78 account: {
79 name: 'root',
80 host: 'localhost:' + servers[0].port
81 },
82 isLocal: false,
83 duration: 10,
84 tags: [ 'tag1p1', 'tag2p1' ],
85 privacy: VideoPrivacy.PUBLIC,
86 commentsEnabled: true,
87 downloadEnabled: true,
88 channel: {
89 name: 'root_channel',
90 displayName: 'Main root channel',
91 description: '',
92 isLocal: false
93 },
94 fixture: 'video_short1.webm',
95 files: [
96 {
97 resolution: 720,
98 size: 572456
99 }
100 ]
101 }
102 unlistedCheckAttributes = immutableAssign(checkAttributes, {
103 privacy: VideoPrivacy.UNLISTED
104 })
105
2ccaeeb3
C
106 // Get the access tokens
107 await setAccessTokensToServers(servers)
108 })
109
110 it('Should remove followers that are often down', async function () {
2284f202 111 this.timeout(240000)
2ccaeeb3 112
cc6373e6 113 // Server 2 and 3 follow server 1
c3d29f69
C
114 await servers[1].followsCommand.follow({ targets: [ servers[0].url ] })
115 await servers[2].followsCommand.follow({ targets: [ servers[0].url ] })
2ccaeeb3 116
3cd0734f 117 await waitJobs(servers)
2ccaeeb3 118
cc6373e6 119 // Upload a video to server 1
2ccaeeb3
C
120 await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
121
3cd0734f 122 await waitJobs(servers)
2ccaeeb3 123
cc6373e6 124 // And check all servers have this video
2ccaeeb3
C
125 for (const server of servers) {
126 const res = await getVideosList(server.url)
127 expect(res.body.data).to.be.an('array')
128 expect(res.body.data).to.have.lengthOf(1)
129 }
130
cc6373e6 131 // Kill server 2
2ccaeeb3
C
132 killallServers([ servers[1] ])
133
134 // Remove server 2 follower
135 for (let i = 0; i < 10; i++) {
a1587156 136 await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
7bc29171
C
137 }
138
f67d1dca 139 await waitJobs([ servers[0], servers[2] ])
6502c3d4 140
cc6373e6
C
141 // Kill server 3
142 killallServers([ servers[2] ])
143
a1587156 144 const resLastVideo1 = await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
cc6373e6
C
145 missedVideo1 = resLastVideo1.body.video
146
a1587156 147 const resLastVideo2 = await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
cc6373e6
C
148 missedVideo2 = resLastVideo2.body.video
149
150 // Unlisted video
a1587156 151 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, unlistedVideoAttributes)
cc6373e6 152 unlistedVideo = resVideo.body.video
6502c3d4 153
7bc29171
C
154 // Add comments to video 2
155 {
156 const text = 'thread 1'
cc6373e6 157 let resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, missedVideo2.uuid, text)
7bc29171
C
158 let comment = resComment.body.comment
159 threadIdServer1 = comment.id
160
cc6373e6 161 resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, missedVideo2.uuid, comment.id, 'comment 1-1')
7bc29171
C
162 comment = resComment.body.comment
163
cc6373e6 164 resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, missedVideo2.uuid, comment.id, 'comment 1-2')
7bc29171 165 commentIdServer1 = resComment.body.comment.id
2ccaeeb3
C
166 }
167
3cd0734f
C
168 await waitJobs(servers[0])
169 // Wait scheduler
9a4a9b6c 170 await wait(11000)
2ccaeeb3 171
cc6373e6 172 // Only server 3 is still a follower of server 1
c3d29f69
C
173 const body = await servers[0].followsCommand.getFollowers({ start: 0, count: 2, sort: 'createdAt' })
174 expect(body.data).to.be.an('array')
175 expect(body.data).to.have.lengthOf(1)
176 expect(body.data[0].follower.host).to.equal('localhost:' + servers[2].port)
2ccaeeb3
C
177 })
178
179 it('Should not have pending/processing jobs anymore', async function () {
94831479 180 const states: JobState[] = [ 'waiting', 'active' ]
2ccaeeb3 181
94a5ff8a 182 for (const state of states) {
9c6327f8 183 const body = await servers[0].jobsCommand.getJobsList({
1061c73f
C
184 state: state,
185 start: 0,
186 count: 50,
187 sort: '-createdAt'
188 })
9c6327f8 189 expect(body.data).to.have.length(0)
2ccaeeb3
C
190 }
191 })
192
cc6373e6 193 it('Should re-follow server 1', async function () {
cf7a61b5 194 this.timeout(35000)
7bc29171
C
195
196 await reRunServer(servers[1])
cc6373e6
C
197 await reRunServer(servers[2])
198
c3d29f69 199 await servers[1].followsCommand.unfollow({ target: servers[0] })
cc6373e6 200 await waitJobs(servers)
2ccaeeb3 201
c3d29f69 202 await servers[1].followsCommand.follow({ targets: [ servers[0].url ] })
2ccaeeb3 203
3cd0734f 204 await waitJobs(servers)
2ccaeeb3 205
c3d29f69
C
206 const body = await servers[0].followsCommand.getFollowers({ start: 0, count: 2, sort: 'createdAt' })
207 expect(body.data).to.be.an('array')
208 expect(body.data).to.have.lengthOf(2)
2ccaeeb3
C
209 })
210
8cf99873 211 it('Should send an update to server 3, and automatically fetch the video', async function () {
7bc29171 212 this.timeout(15000)
2ccaeeb3 213
cc6373e6
C
214 const res1 = await getVideosList(servers[2].url)
215 expect(res1.body.data).to.be.an('array')
216 expect(res1.body.data).to.have.lengthOf(11)
217
a1587156
C
218 await updateVideo(servers[0].url, servers[0].accessToken, missedVideo1.uuid, {})
219 await updateVideo(servers[0].url, servers[0].accessToken, unlistedVideo.uuid, {})
2ccaeeb3 220
3cd0734f 221 await waitJobs(servers)
2ccaeeb3 222
cc6373e6 223 const res = await getVideosList(servers[2].url)
7bc29171 224 expect(res.body.data).to.be.an('array')
cc6373e6
C
225 // 1 video is unlisted
226 expect(res.body.data).to.have.lengthOf(12)
7bc29171 227
cc6373e6
C
228 // Check unlisted video
229 const resVideo = await getVideo(servers[2].url, unlistedVideo.uuid)
7bc29171
C
230 expect(resVideo.body).not.to.be.undefined
231
cc6373e6 232 await completeVideoCheck(servers[2].url, resVideo.body, unlistedCheckAttributes)
7bc29171
C
233 })
234
cc6373e6 235 it('Should send comments on a video to server 3, and automatically fetch the video', async function () {
7bc29171 236 this.timeout(25000)
2ccaeeb3 237
cc6373e6 238 await addVideoCommentReply(servers[0].url, servers[0].accessToken, missedVideo2.uuid, commentIdServer1, 'comment 1-3')
7bc29171 239
3cd0734f 240 await waitJobs(servers)
7bc29171 241
cc6373e6 242 const resVideo = await getVideo(servers[2].url, missedVideo2.uuid)
7bc29171
C
243 expect(resVideo.body).not.to.be.undefined
244
7bc29171 245 {
cc6373e6 246 let resComment = await getVideoCommentThreads(servers[2].url, missedVideo2.uuid, 0, 5)
7bc29171
C
247 expect(resComment.body.data).to.be.an('array')
248 expect(resComment.body.data).to.have.lengthOf(1)
249
250 threadIdServer2 = resComment.body.data[0].id
251
cc6373e6 252 resComment = await getVideoThreadComments(servers[2].url, missedVideo2.uuid, threadIdServer2)
7bc29171
C
253
254 const tree: VideoCommentThreadTree = resComment.body
255 expect(tree.comment.text).equal('thread 1')
256 expect(tree.children).to.have.lengthOf(1)
257
258 const firstChild = tree.children[0]
259 expect(firstChild.comment.text).to.equal('comment 1-1')
260 expect(firstChild.children).to.have.lengthOf(1)
261
262 const childOfFirstChild = firstChild.children[0]
263 expect(childOfFirstChild.comment.text).to.equal('comment 1-2')
264 expect(childOfFirstChild.children).to.have.lengthOf(1)
265
266 const childOfChildFirstChild = childOfFirstChild.children[0]
267 expect(childOfChildFirstChild.comment.text).to.equal('comment 1-3')
268 expect(childOfChildFirstChild.children).to.have.lengthOf(0)
269
270 commentIdServer2 = childOfChildFirstChild.comment.id
271 }
272 })
273
274 it('Should correctly reply to the comment', async function () {
275 this.timeout(15000)
276
cc6373e6 277 await addVideoCommentReply(servers[2].url, servers[2].accessToken, missedVideo2.uuid, commentIdServer2, 'comment 1-4')
7bc29171 278
3cd0734f 279 await waitJobs(servers)
7bc29171
C
280
281 {
cc6373e6 282 const resComment = await getVideoThreadComments(servers[0].url, missedVideo2.uuid, threadIdServer1)
7bc29171
C
283
284 const tree: VideoCommentThreadTree = resComment.body
285 expect(tree.comment.text).equal('thread 1')
286 expect(tree.children).to.have.lengthOf(1)
287
288 const firstChild = tree.children[0]
289 expect(firstChild.comment.text).to.equal('comment 1-1')
290 expect(firstChild.children).to.have.lengthOf(1)
291
292 const childOfFirstChild = firstChild.children[0]
293 expect(childOfFirstChild.comment.text).to.equal('comment 1-2')
294 expect(childOfFirstChild.children).to.have.lengthOf(1)
295
296 const childOfChildFirstChild = childOfFirstChild.children[0]
297 expect(childOfChildFirstChild.comment.text).to.equal('comment 1-3')
298 expect(childOfChildFirstChild.children).to.have.lengthOf(1)
299
300 const childOfChildOfChildOfFirstChild = childOfChildFirstChild.children[0]
301 expect(childOfChildOfChildOfFirstChild.comment.text).to.equal('comment 1-4')
302 expect(childOfChildOfChildOfFirstChild.children).to.have.lengthOf(0)
303 }
2ccaeeb3
C
304 })
305
6b9c966f
C
306 it('Should upload many videos on server 1', async function () {
307 this.timeout(120000)
308
309 for (let i = 0; i < 10; i++) {
a1587156 310 const uuid = (await uploadVideoAndGetId({ server: servers[0], videoName: 'video ' + i })).uuid
6b9c966f
C
311 videoIdsServer1.push(uuid)
312 }
313
314 await waitJobs(servers)
315
316 for (const id of videoIdsServer1) {
a1587156 317 await getVideo(servers[1].url, id)
6b9c966f
C
318 }
319
320 await waitJobs(servers)
321 await setActorFollowScores(servers[1].internalServerNumber, 20)
322
323 // Wait video expiration
324 await wait(11000)
325
326 // Refresh video -> score + 10 = 30
327 await getVideo(servers[1].url, videoIdsServer1[0])
328
329 await waitJobs(servers)
330 })
331
332 it('Should remove followings that are down', async function () {
333 this.timeout(120000)
334
335 killallServers([ servers[0] ])
336
337 // Wait video expiration
338 await wait(11000)
339
a3c997b3
C
340 for (let i = 0; i < 5; i++) {
341 try {
342 await getVideo(servers[1].url, videoIdsServer1[i])
343 await waitJobs([ servers[1] ])
344 await wait(1500)
345 } catch {}
6b9c966f
C
346 }
347
348 for (const id of videoIdsServer1) {
f2eb23cd 349 await getVideo(servers[1].url, id, HttpStatusCode.FORBIDDEN_403)
6b9c966f
C
350 }
351 })
352
7c3b7976 353 after(async function () {
6b9c966f
C
354 await closeAllSequelize([ servers[1] ])
355
7c3b7976 356 await cleanupTests(servers)
2ccaeeb3
C
357 })
358})