handle-down.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. /* tslint:disable:no-unused-expression */
  2. import * as chai from 'chai'
  3. import 'mocha'
  4. import { JobState, Video } from '../../../../shared/models'
  5. import { VideoPrivacy } from '../../../../shared/models/videos'
  6. import { VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
  7. import {
  8. cleanupTests,
  9. completeVideoCheck,
  10. flushAndRunMultipleServers,
  11. getVideo,
  12. getVideosList,
  13. immutableAssign,
  14. killallServers,
  15. reRunServer,
  16. ServerInfo,
  17. setAccessTokensToServers,
  18. unfollow,
  19. updateVideo,
  20. uploadVideo, uploadVideoAndGetId,
  21. wait,
  22. setActorFollowScores, closeAllSequelize
  23. } from '../../../../shared/extra-utils'
  24. import { follow, getFollowersListPaginationAndSort } from '../../../../shared/extra-utils/server/follows'
  25. import { getJobsListPaginationAndSort, waitJobs } from '../../../../shared/extra-utils/server/jobs'
  26. import {
  27. addVideoCommentReply,
  28. addVideoCommentThread,
  29. getVideoCommentThreads,
  30. getVideoThreadComments
  31. } from '../../../../shared/extra-utils/videos/video-comments'
  32. const expect = chai.expect
  33. describe('Test handle downs', function () {
  34. let servers: ServerInfo[] = []
  35. let threadIdServer1: number
  36. let threadIdServer2: number
  37. let commentIdServer1: number
  38. let commentIdServer2: number
  39. let missedVideo1: Video
  40. let missedVideo2: Video
  41. let unlistedVideo: Video
  42. let videoIdsServer1: number[] = []
  43. const videoAttributes = {
  44. name: 'my super name for server 1',
  45. category: 5,
  46. licence: 4,
  47. language: 'ja',
  48. nsfw: true,
  49. privacy: VideoPrivacy.PUBLIC,
  50. description: 'my super description for server 1',
  51. support: 'my super support text for server 1',
  52. tags: [ 'tag1p1', 'tag2p1' ],
  53. fixture: 'video_short1.webm'
  54. }
  55. const unlistedVideoAttributes = immutableAssign(videoAttributes, {
  56. privacy: VideoPrivacy.UNLISTED
  57. })
  58. let checkAttributes: any
  59. let unlistedCheckAttributes: any
  60. before(async function () {
  61. this.timeout(30000)
  62. servers = await flushAndRunMultipleServers(3)
  63. checkAttributes = {
  64. name: 'my super name for server 1',
  65. category: 5,
  66. licence: 4,
  67. language: 'ja',
  68. nsfw: true,
  69. description: 'my super description for server 1',
  70. support: 'my super support text for server 1',
  71. account: {
  72. name: 'root',
  73. host: 'localhost:' + servers[0].port
  74. },
  75. isLocal: false,
  76. duration: 10,
  77. tags: [ 'tag1p1', 'tag2p1' ],
  78. privacy: VideoPrivacy.PUBLIC,
  79. commentsEnabled: true,
  80. downloadEnabled: true,
  81. channel: {
  82. name: 'root_channel',
  83. displayName: 'Main root channel',
  84. description: '',
  85. isLocal: false
  86. },
  87. fixture: 'video_short1.webm',
  88. files: [
  89. {
  90. resolution: 720,
  91. size: 572456
  92. }
  93. ]
  94. }
  95. unlistedCheckAttributes = immutableAssign(checkAttributes, {
  96. privacy: VideoPrivacy.UNLISTED
  97. })
  98. // Get the access tokens
  99. await setAccessTokensToServers(servers)
  100. })
  101. it('Should remove followers that are often down', async function () {
  102. this.timeout(240000)
  103. // Server 2 and 3 follow server 1
  104. await follow(servers[1].url, [ servers[0].url ], servers[1].accessToken)
  105. await follow(servers[2].url, [ servers[0].url ], servers[2].accessToken)
  106. await waitJobs(servers)
  107. // Upload a video to server 1
  108. await uploadVideo(servers[0].url, servers[0].accessToken, videoAttributes)
  109. await waitJobs(servers)
  110. // And check all servers have this video
  111. for (const server of servers) {
  112. const res = await getVideosList(server.url)
  113. expect(res.body.data).to.be.an('array')
  114. expect(res.body.data).to.have.lengthOf(1)
  115. }
  116. // Kill server 2
  117. killallServers([ servers[1] ])
  118. // Remove server 2 follower
  119. for (let i = 0; i < 10; i++) {
  120. await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, videoAttributes)
  121. }
  122. await waitJobs(servers[0])
  123. // Kill server 3
  124. killallServers([ servers[2] ])
  125. const resLastVideo1 = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, videoAttributes)
  126. missedVideo1 = resLastVideo1.body.video
  127. const resLastVideo2 = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, videoAttributes)
  128. missedVideo2 = resLastVideo2.body.video
  129. // Unlisted video
  130. let resVideo = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, unlistedVideoAttributes)
  131. unlistedVideo = resVideo.body.video
  132. // Add comments to video 2
  133. {
  134. const text = 'thread 1'
  135. let resComment = await addVideoCommentThread(servers[0].url, servers[0].accessToken, missedVideo2.uuid, text)
  136. let comment = resComment.body.comment
  137. threadIdServer1 = comment.id
  138. resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, missedVideo2.uuid, comment.id, 'comment 1-1')
  139. comment = resComment.body.comment
  140. resComment = await addVideoCommentReply(servers[0].url, servers[0].accessToken, missedVideo2.uuid, comment.id, 'comment 1-2')
  141. commentIdServer1 = resComment.body.comment.id
  142. }
  143. await waitJobs(servers[0])
  144. // Wait scheduler
  145. await wait(11000)
  146. // Only server 3 is still a follower of server 1
  147. const res = await getFollowersListPaginationAndSort(servers[0].url, 0, 2, 'createdAt')
  148. expect(res.body.data).to.be.an('array')
  149. expect(res.body.data).to.have.lengthOf(1)
  150. expect(res.body.data[0].follower.host).to.equal('localhost:' + servers[2].port)
  151. })
  152. it('Should not have pending/processing jobs anymore', async function () {
  153. const states: JobState[] = [ 'waiting', 'active' ]
  154. for (const state of states) {
  155. const res = await getJobsListPaginationAndSort(servers[ 0 ].url, servers[ 0 ].accessToken, state,0, 50, '-createdAt')
  156. expect(res.body.data).to.have.length(0)
  157. }
  158. })
  159. it('Should re-follow server 1', async function () {
  160. this.timeout(35000)
  161. await reRunServer(servers[1])
  162. await reRunServer(servers[2])
  163. await unfollow(servers[1].url, servers[1].accessToken, servers[0])
  164. await waitJobs(servers)
  165. await follow(servers[1].url, [ servers[0].url ], servers[1].accessToken)
  166. await waitJobs(servers)
  167. const res = await getFollowersListPaginationAndSort(servers[0].url, 0, 2, 'createdAt')
  168. expect(res.body.data).to.be.an('array')
  169. expect(res.body.data).to.have.lengthOf(2)
  170. })
  171. it('Should send an update to server 3, and automatically fetch the video', async function () {
  172. this.timeout(15000)
  173. const res1 = await getVideosList(servers[2].url)
  174. expect(res1.body.data).to.be.an('array')
  175. expect(res1.body.data).to.have.lengthOf(11)
  176. await updateVideo(servers[0].url, servers[0].accessToken, missedVideo1.uuid, { })
  177. await updateVideo(servers[0].url, servers[0].accessToken, unlistedVideo.uuid, { })
  178. await waitJobs(servers)
  179. const res = await getVideosList(servers[2].url)
  180. expect(res.body.data).to.be.an('array')
  181. // 1 video is unlisted
  182. expect(res.body.data).to.have.lengthOf(12)
  183. // Check unlisted video
  184. const resVideo = await getVideo(servers[2].url, unlistedVideo.uuid)
  185. expect(resVideo.body).not.to.be.undefined
  186. await completeVideoCheck(servers[2].url, resVideo.body, unlistedCheckAttributes)
  187. })
  188. it('Should send comments on a video to server 3, and automatically fetch the video', async function () {
  189. this.timeout(25000)
  190. await addVideoCommentReply(servers[0].url, servers[0].accessToken, missedVideo2.uuid, commentIdServer1, 'comment 1-3')
  191. await waitJobs(servers)
  192. const resVideo = await getVideo(servers[2].url, missedVideo2.uuid)
  193. expect(resVideo.body).not.to.be.undefined
  194. {
  195. let resComment = await getVideoCommentThreads(servers[2].url, missedVideo2.uuid, 0, 5)
  196. expect(resComment.body.data).to.be.an('array')
  197. expect(resComment.body.data).to.have.lengthOf(1)
  198. threadIdServer2 = resComment.body.data[0].id
  199. resComment = await getVideoThreadComments(servers[2].url, missedVideo2.uuid, threadIdServer2)
  200. const tree: VideoCommentThreadTree = resComment.body
  201. expect(tree.comment.text).equal('thread 1')
  202. expect(tree.children).to.have.lengthOf(1)
  203. const firstChild = tree.children[0]
  204. expect(firstChild.comment.text).to.equal('comment 1-1')
  205. expect(firstChild.children).to.have.lengthOf(1)
  206. const childOfFirstChild = firstChild.children[0]
  207. expect(childOfFirstChild.comment.text).to.equal('comment 1-2')
  208. expect(childOfFirstChild.children).to.have.lengthOf(1)
  209. const childOfChildFirstChild = childOfFirstChild.children[0]
  210. expect(childOfChildFirstChild.comment.text).to.equal('comment 1-3')
  211. expect(childOfChildFirstChild.children).to.have.lengthOf(0)
  212. commentIdServer2 = childOfChildFirstChild.comment.id
  213. }
  214. })
  215. it('Should correctly reply to the comment', async function () {
  216. this.timeout(15000)
  217. await addVideoCommentReply(servers[2].url, servers[2].accessToken, missedVideo2.uuid, commentIdServer2, 'comment 1-4')
  218. await waitJobs(servers)
  219. {
  220. const resComment = await getVideoThreadComments(servers[0].url, missedVideo2.uuid, threadIdServer1)
  221. const tree: VideoCommentThreadTree = resComment.body
  222. expect(tree.comment.text).equal('thread 1')
  223. expect(tree.children).to.have.lengthOf(1)
  224. const firstChild = tree.children[0]
  225. expect(firstChild.comment.text).to.equal('comment 1-1')
  226. expect(firstChild.children).to.have.lengthOf(1)
  227. const childOfFirstChild = firstChild.children[0]
  228. expect(childOfFirstChild.comment.text).to.equal('comment 1-2')
  229. expect(childOfFirstChild.children).to.have.lengthOf(1)
  230. const childOfChildFirstChild = childOfFirstChild.children[0]
  231. expect(childOfChildFirstChild.comment.text).to.equal('comment 1-3')
  232. expect(childOfChildFirstChild.children).to.have.lengthOf(1)
  233. const childOfChildOfChildOfFirstChild = childOfChildFirstChild.children[0]
  234. expect(childOfChildOfChildOfFirstChild.comment.text).to.equal('comment 1-4')
  235. expect(childOfChildOfChildOfFirstChild.children).to.have.lengthOf(0)
  236. }
  237. })
  238. it('Should upload many videos on server 1', async function () {
  239. this.timeout(120000)
  240. for (let i = 0; i < 10; i++) {
  241. const uuid = (await uploadVideoAndGetId({ server: servers[ 0 ], videoName: 'video ' + i })).uuid
  242. videoIdsServer1.push(uuid)
  243. }
  244. await waitJobs(servers)
  245. for (const id of videoIdsServer1) {
  246. await getVideo(servers[ 1 ].url, id)
  247. }
  248. await waitJobs(servers)
  249. await setActorFollowScores(servers[1].internalServerNumber, 20)
  250. // Wait video expiration
  251. await wait(11000)
  252. // Refresh video -> score + 10 = 30
  253. await getVideo(servers[1].url, videoIdsServer1[0])
  254. await waitJobs(servers)
  255. })
  256. it('Should remove followings that are down', async function () {
  257. this.timeout(120000)
  258. killallServers([ servers[0] ])
  259. // Wait video expiration
  260. await wait(11000)
  261. for (let i = 0; i < 3; i++) {
  262. await getVideo(servers[1].url, videoIdsServer1[i])
  263. await wait(1000)
  264. await waitJobs([ servers[1] ])
  265. }
  266. for (const id of videoIdsServer1) {
  267. await getVideo(servers[1].url, id, 403)
  268. }
  269. })
  270. after(async function () {
  271. await closeAllSequelize([ servers[1] ])
  272. await cleanupTests(servers)
  273. })
  274. })