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