aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/api/server
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-02-11 11:52:34 +0100
committerChocobozzz <me@florianbigard.com>2019-02-11 11:52:34 +0100
commit88108880bbdba473cfe36ecbebc1c3c4f972e102 (patch)
treeb242efb3b4f0d7e49d88f2d1f2063b5b3b0489c0 /server/tests/api/server
parent53a94c7cfa8368da4cd248d65df8346905938f0c (diff)
parent9b712a2017e4ab3cf12cd6bd58278905520159d0 (diff)
downloadPeerTube-88108880bbdba473cfe36ecbebc1c3c4f972e102.tar.gz
PeerTube-88108880bbdba473cfe36ecbebc1c3c4f972e102.tar.zst
PeerTube-88108880bbdba473cfe36ecbebc1c3c4f972e102.zip
Merge branch 'develop' into pr/1217
Diffstat (limited to 'server/tests/api/server')
-rw-r--r--server/tests/api/server/config.ts62
-rw-r--r--server/tests/api/server/contact-form.ts86
-rw-r--r--server/tests/api/server/email.ts16
-rw-r--r--server/tests/api/server/follow-constraints.ts225
-rw-r--r--server/tests/api/server/follows.ts67
-rw-r--r--server/tests/api/server/handle-down.ts22
-rw-r--r--server/tests/api/server/index.ts4
-rw-r--r--server/tests/api/server/jobs.ts12
-rw-r--r--server/tests/api/server/no-client.ts36
-rw-r--r--server/tests/api/server/redundancy.ts483
-rw-r--r--server/tests/api/server/reverse-proxy.ts6
-rw-r--r--server/tests/api/server/stats.ts14
-rw-r--r--server/tests/api/server/tracker.ts4
13 files changed, 506 insertions, 531 deletions
diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts
index facd1688d..0dfe6e4fe 100644
--- a/server/tests/api/server/config.ts
+++ b/server/tests/api/server/config.ts
@@ -4,8 +4,11 @@ import 'mocha'
4import * as chai from 'chai' 4import * as chai from 'chai'
5import { About } from '../../../../shared/models/server/about.model' 5import { About } from '../../../../shared/models/server/about.model'
6import { CustomConfig } from '../../../../shared/models/server/custom-config.model' 6import { CustomConfig } from '../../../../shared/models/server/custom-config.model'
7import { deleteCustomConfig, getAbout, killallServers, reRunServer } from '../../utils'
8import { 7import {
8 deleteCustomConfig,
9 getAbout,
10 killallServers,
11 reRunServer,
9 flushTests, 12 flushTests,
10 getConfig, 13 getConfig,
11 getCustomConfig, 14 getCustomConfig,
@@ -13,7 +16,8 @@ import {
13 runServer, 16 runServer,
14 setAccessTokensToServers, 17 setAccessTokensToServers,
15 updateCustomConfig 18 updateCustomConfig
16} from '../../utils/index' 19} from '../../../../shared/utils'
20import { ServerConfig } from '../../../../shared/models'
17 21
18const expect = chai.expect 22const expect = chai.expect
19 23
@@ -29,23 +33,32 @@ function checkInitialConfig (data: CustomConfig) {
29 expect(data.instance.defaultNSFWPolicy).to.equal('display') 33 expect(data.instance.defaultNSFWPolicy).to.equal('display')
30 expect(data.instance.customizations.css).to.be.empty 34 expect(data.instance.customizations.css).to.be.empty
31 expect(data.instance.customizations.javascript).to.be.empty 35 expect(data.instance.customizations.javascript).to.be.empty
36
32 expect(data.services.twitter.username).to.equal('@Chocobozzz') 37 expect(data.services.twitter.username).to.equal('@Chocobozzz')
33 expect(data.services.twitter.whitelisted).to.be.false 38 expect(data.services.twitter.whitelisted).to.be.false
39
34 expect(data.cache.previews.size).to.equal(1) 40 expect(data.cache.previews.size).to.equal(1)
35 expect(data.cache.captions.size).to.equal(1) 41 expect(data.cache.captions.size).to.equal(1)
42
36 expect(data.signup.enabled).to.be.true 43 expect(data.signup.enabled).to.be.true
37 expect(data.signup.limit).to.equal(4) 44 expect(data.signup.limit).to.equal(4)
38 expect(data.signup.requiresEmailVerification).to.be.false 45 expect(data.signup.requiresEmailVerification).to.be.false
46
39 expect(data.admin.email).to.equal('admin1@example.com') 47 expect(data.admin.email).to.equal('admin1@example.com')
48 expect(data.contactForm.enabled).to.be.true
49
40 expect(data.user.videoQuota).to.equal(5242880) 50 expect(data.user.videoQuota).to.equal(5242880)
41 expect(data.user.videoQuotaDaily).to.equal(-1) 51 expect(data.user.videoQuotaDaily).to.equal(-1)
42 expect(data.transcoding.enabled).to.be.false 52 expect(data.transcoding.enabled).to.be.false
53 expect(data.transcoding.allowAdditionalExtensions).to.be.false
43 expect(data.transcoding.threads).to.equal(2) 54 expect(data.transcoding.threads).to.equal(2)
44 expect(data.transcoding.resolutions['240p']).to.be.true 55 expect(data.transcoding.resolutions['240p']).to.be.true
45 expect(data.transcoding.resolutions['360p']).to.be.true 56 expect(data.transcoding.resolutions['360p']).to.be.true
46 expect(data.transcoding.resolutions['480p']).to.be.true 57 expect(data.transcoding.resolutions['480p']).to.be.true
47 expect(data.transcoding.resolutions['720p']).to.be.true 58 expect(data.transcoding.resolutions['720p']).to.be.true
48 expect(data.transcoding.resolutions['1080p']).to.be.true 59 expect(data.transcoding.resolutions['1080p']).to.be.true
60 expect(data.transcoding.hls.enabled).to.be.true
61
49 expect(data.import.videos.http.enabled).to.be.true 62 expect(data.import.videos.http.enabled).to.be.true
50 expect(data.import.videos.torrent.enabled).to.be.true 63 expect(data.import.videos.torrent.enabled).to.be.true
51} 64}
@@ -59,23 +72,33 @@ function checkUpdatedConfig (data: CustomConfig) {
59 expect(data.instance.defaultNSFWPolicy).to.equal('blur') 72 expect(data.instance.defaultNSFWPolicy).to.equal('blur')
60 expect(data.instance.customizations.javascript).to.equal('alert("coucou")') 73 expect(data.instance.customizations.javascript).to.equal('alert("coucou")')
61 expect(data.instance.customizations.css).to.equal('body { background-color: red; }') 74 expect(data.instance.customizations.css).to.equal('body { background-color: red; }')
75
62 expect(data.services.twitter.username).to.equal('@Kuja') 76 expect(data.services.twitter.username).to.equal('@Kuja')
63 expect(data.services.twitter.whitelisted).to.be.true 77 expect(data.services.twitter.whitelisted).to.be.true
78
64 expect(data.cache.previews.size).to.equal(2) 79 expect(data.cache.previews.size).to.equal(2)
65 expect(data.cache.captions.size).to.equal(3) 80 expect(data.cache.captions.size).to.equal(3)
81
66 expect(data.signup.enabled).to.be.false 82 expect(data.signup.enabled).to.be.false
67 expect(data.signup.limit).to.equal(5) 83 expect(data.signup.limit).to.equal(5)
68 expect(data.signup.requiresEmailVerification).to.be.true 84 expect(data.signup.requiresEmailVerification).to.be.true
85
69 expect(data.admin.email).to.equal('superadmin1@example.com') 86 expect(data.admin.email).to.equal('superadmin1@example.com')
87 expect(data.contactForm.enabled).to.be.false
88
70 expect(data.user.videoQuota).to.equal(5242881) 89 expect(data.user.videoQuota).to.equal(5242881)
71 expect(data.user.videoQuotaDaily).to.equal(318742) 90 expect(data.user.videoQuotaDaily).to.equal(318742)
91
72 expect(data.transcoding.enabled).to.be.true 92 expect(data.transcoding.enabled).to.be.true
73 expect(data.transcoding.threads).to.equal(1) 93 expect(data.transcoding.threads).to.equal(1)
94 expect(data.transcoding.allowAdditionalExtensions).to.be.true
74 expect(data.transcoding.resolutions['240p']).to.be.false 95 expect(data.transcoding.resolutions['240p']).to.be.false
75 expect(data.transcoding.resolutions['360p']).to.be.true 96 expect(data.transcoding.resolutions['360p']).to.be.true
76 expect(data.transcoding.resolutions['480p']).to.be.true 97 expect(data.transcoding.resolutions['480p']).to.be.true
77 expect(data.transcoding.resolutions['720p']).to.be.false 98 expect(data.transcoding.resolutions['720p']).to.be.false
78 expect(data.transcoding.resolutions['1080p']).to.be.false 99 expect(data.transcoding.resolutions['1080p']).to.be.false
100 expect(data.transcoding.hls.enabled).to.be.false
101
79 expect(data.import.videos.http.enabled).to.be.false 102 expect(data.import.videos.http.enabled).to.be.false
80 expect(data.import.videos.torrent.enabled).to.be.false 103 expect(data.import.videos.torrent.enabled).to.be.false
81} 104}
@@ -93,7 +116,7 @@ describe('Test config', function () {
93 116
94 it('Should have a correct config on a server with registration enabled', async function () { 117 it('Should have a correct config on a server with registration enabled', async function () {
95 const res = await getConfig(server.url) 118 const res = await getConfig(server.url)
96 const data = res.body 119 const data: ServerConfig = res.body
97 120
98 expect(data.signup.allowed).to.be.true 121 expect(data.signup.allowed).to.be.true
99 }) 122 })
@@ -108,11 +131,23 @@ describe('Test config', function () {
108 ]) 131 ])
109 132
110 const res = await getConfig(server.url) 133 const res = await getConfig(server.url)
111 const data = res.body 134 const data: ServerConfig = res.body
112 135
113 expect(data.signup.allowed).to.be.false 136 expect(data.signup.allowed).to.be.false
114 }) 137 })
115 138
139 it('Should have the correct video allowed extensions', async function () {
140 const res = await getConfig(server.url)
141 const data: ServerConfig = res.body
142
143 expect(data.video.file.extensions).to.have.lengthOf(3)
144 expect(data.video.file.extensions).to.contain('.mp4')
145 expect(data.video.file.extensions).to.contain('.webm')
146 expect(data.video.file.extensions).to.contain('.ogv')
147
148 expect(data.contactForm.enabled).to.be.true
149 })
150
116 it('Should get the customized configuration', async function () { 151 it('Should get the customized configuration', async function () {
117 const res = await getCustomConfig(server.url, server.accessToken) 152 const res = await getCustomConfig(server.url, server.accessToken)
118 const data = res.body as CustomConfig 153 const data = res.body as CustomConfig
@@ -156,12 +191,16 @@ describe('Test config', function () {
156 admin: { 191 admin: {
157 email: 'superadmin1@example.com' 192 email: 'superadmin1@example.com'
158 }, 193 },
194 contactForm: {
195 enabled: false
196 },
159 user: { 197 user: {
160 videoQuota: 5242881, 198 videoQuota: 5242881,
161 videoQuotaDaily: 318742 199 videoQuotaDaily: 318742
162 }, 200 },
163 transcoding: { 201 transcoding: {
164 enabled: true, 202 enabled: true,
203 allowAdditionalExtensions: true,
165 threads: 1, 204 threads: 1,
166 resolutions: { 205 resolutions: {
167 '240p': false, 206 '240p': false,
@@ -169,6 +208,9 @@ describe('Test config', function () {
169 '480p': true, 208 '480p': true,
170 '720p': false, 209 '720p': false,
171 '1080p': false 210 '1080p': false
211 },
212 hls: {
213 enabled: false
172 } 214 }
173 }, 215 },
174 import: { 216 import: {
@@ -190,6 +232,18 @@ describe('Test config', function () {
190 checkUpdatedConfig(data) 232 checkUpdatedConfig(data)
191 }) 233 })
192 234
235 it('Should have the correct updated video allowed extensions', async function () {
236 const res = await getConfig(server.url)
237 const data: ServerConfig = res.body
238
239 expect(data.video.file.extensions).to.have.length.above(3)
240 expect(data.video.file.extensions).to.contain('.mp4')
241 expect(data.video.file.extensions).to.contain('.webm')
242 expect(data.video.file.extensions).to.contain('.ogv')
243 expect(data.video.file.extensions).to.contain('.flv')
244 expect(data.video.file.extensions).to.contain('.mkv')
245 })
246
193 it('Should have the configuration updated after a restart', async function () { 247 it('Should have the configuration updated after a restart', async function () {
194 this.timeout(10000) 248 this.timeout(10000)
195 249
diff --git a/server/tests/api/server/contact-form.ts b/server/tests/api/server/contact-form.ts
new file mode 100644
index 000000000..93221d0a3
--- /dev/null
+++ b/server/tests/api/server/contact-form.ts
@@ -0,0 +1,86 @@
1/* tslint:disable:no-unused-expression */
2
3import * as chai from 'chai'
4import 'mocha'
5import { flushTests, killallServers, runServer, ServerInfo, setAccessTokensToServers, wait } from '../../../../shared/utils'
6import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
7import { waitJobs } from '../../../../shared/utils/server/jobs'
8import { sendContactForm } from '../../../../shared/utils/server/contact-form'
9
10const expect = chai.expect
11
12describe('Test contact form', function () {
13 let server: ServerInfo
14 const emails: object[] = []
15
16 before(async function () {
17 this.timeout(30000)
18
19 await MockSmtpServer.Instance.collectEmails(emails)
20
21 await flushTests()
22
23 const overrideConfig = {
24 smtp: {
25 hostname: 'localhost'
26 }
27 }
28 server = await runServer(1, overrideConfig)
29 await setAccessTokensToServers([ server ])
30 })
31
32 it('Should send a contact form', async function () {
33 this.timeout(10000)
34
35 await sendContactForm({
36 url: server.url,
37 fromEmail: 'toto@example.com',
38 body: 'my super message',
39 fromName: 'Super toto'
40 })
41
42 await waitJobs(server)
43
44 expect(emails).to.have.lengthOf(1)
45
46 const email = emails[0]
47
48 expect(email['from'][0]['address']).equal('toto@example.com')
49 expect(email['to'][0]['address']).equal('admin1@example.com')
50 expect(email['subject']).contains('Contact form')
51 expect(email['text']).contains('my super message')
52 })
53
54 it('Should not be able to send another contact form because of the anti spam checker', async function () {
55 await sendContactForm({
56 url: server.url,
57 fromEmail: 'toto@example.com',
58 body: 'my super message',
59 fromName: 'Super toto'
60 })
61
62 await sendContactForm({
63 url: server.url,
64 fromEmail: 'toto@example.com',
65 body: 'my super message',
66 fromName: 'Super toto',
67 expectedStatus: 403
68 })
69 })
70
71 it('Should be able to send another contact form after a while', async function () {
72 await wait(1000)
73
74 await sendContactForm({
75 url: server.url,
76 fromEmail: 'toto@example.com',
77 body: 'my super message',
78 fromName: 'Super toto'
79 })
80 })
81
82 after(async function () {
83 MockSmtpServer.Instance.kill()
84 killallServers([ server ])
85 })
86})
diff --git a/server/tests/api/server/email.ts b/server/tests/api/server/email.ts
index 713a27143..f96c57b66 100644
--- a/server/tests/api/server/email.ts
+++ b/server/tests/api/server/email.ts
@@ -14,11 +14,14 @@ import {
14 unblockUser, 14 unblockUser,
15 uploadVideo, 15 uploadVideo,
16 userLogin, 16 userLogin,
17 verifyEmail 17 verifyEmail,
18} from '../../utils' 18 flushTests,
19import { flushTests, killallServers, ServerInfo, setAccessTokensToServers } from '../../utils/index' 19 killallServers,
20import { mockSmtpServer } from '../../utils/miscs/email' 20 ServerInfo,
21import { waitJobs } from '../../utils/server/jobs' 21 setAccessTokensToServers
22} from '../../../../shared/utils'
23import { MockSmtpServer } from '../../../../shared/utils/miscs/email'
24import { waitJobs } from '../../../../shared/utils/server/jobs'
22 25
23const expect = chai.expect 26const expect = chai.expect
24 27
@@ -38,7 +41,7 @@ describe('Test emails', function () {
38 before(async function () { 41 before(async function () {
39 this.timeout(30000) 42 this.timeout(30000)
40 43
41 await mockSmtpServer(emails) 44 await MockSmtpServer.Instance.collectEmails(emails)
42 45
43 await flushTests() 46 await flushTests()
44 47
@@ -248,6 +251,7 @@ describe('Test emails', function () {
248 }) 251 })
249 252
250 after(async function () { 253 after(async function () {
254 MockSmtpServer.Instance.kill()
251 killallServers([ server ]) 255 killallServers([ server ])
252 }) 256 })
253}) 257})
diff --git a/server/tests/api/server/follow-constraints.ts b/server/tests/api/server/follow-constraints.ts
new file mode 100644
index 000000000..8bb073c41
--- /dev/null
+++ b/server/tests/api/server/follow-constraints.ts
@@ -0,0 +1,225 @@
1/* tslint:disable:no-unused-expression */
2
3import * as chai from 'chai'
4import 'mocha'
5import {
6 doubleFollow,
7 getAccountVideos,
8 getVideo,
9 getVideoChannelVideos,
10 getVideoWithToken,
11 flushAndRunMultipleServers,
12 killallServers,
13 ServerInfo,
14 setAccessTokensToServers,
15 uploadVideo
16} from '../../../../shared/utils'
17import { unfollow } from '../../../../shared/utils/server/follows'
18import { userLogin } from '../../../../shared/utils/users/login'
19import { createUser } from '../../../../shared/utils/users/users'
20
21const expect = chai.expect
22
23describe('Test follow constraints', function () {
24 let servers: ServerInfo[] = []
25 let video1UUID: string
26 let video2UUID: string
27 let userAccessToken: string
28
29 before(async function () {
30 this.timeout(30000)
31
32 servers = await flushAndRunMultipleServers(2)
33
34 // Get the access tokens
35 await setAccessTokensToServers(servers)
36
37 {
38 const res = await uploadVideo(servers[ 0 ].url, servers[ 0 ].accessToken, { name: 'video server 1' })
39 video1UUID = res.body.video.uuid
40 }
41 {
42 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video server 2' })
43 video2UUID = res.body.video.uuid
44 }
45
46 const user = {
47 username: 'user1',
48 password: 'super_password'
49 }
50 await createUser(servers[0].url, servers[0].accessToken, user.username, user.password)
51 userAccessToken = await userLogin(servers[0], user)
52
53 await doubleFollow(servers[0], servers[1])
54 })
55
56 describe('With a followed instance', function () {
57
58 describe('With an unlogged user', function () {
59
60 it('Should get the local video', async function () {
61 await getVideo(servers[0].url, video1UUID, 200)
62 })
63
64 it('Should get the remote video', async function () {
65 await getVideo(servers[0].url, video2UUID, 200)
66 })
67
68 it('Should list local account videos', async function () {
69 const res = await getAccountVideos(servers[0].url, undefined, 'root@localhost:9001', 0, 5)
70
71 expect(res.body.total).to.equal(1)
72 expect(res.body.data).to.have.lengthOf(1)
73 })
74
75 it('Should list remote account videos', async function () {
76 const res = await getAccountVideos(servers[0].url, undefined, 'root@localhost:9002', 0, 5)
77
78 expect(res.body.total).to.equal(1)
79 expect(res.body.data).to.have.lengthOf(1)
80 })
81
82 it('Should list local channel videos', async function () {
83 const res = await getVideoChannelVideos(servers[0].url, undefined, 'root_channel@localhost:9001', 0, 5)
84
85 expect(res.body.total).to.equal(1)
86 expect(res.body.data).to.have.lengthOf(1)
87 })
88
89 it('Should list remote channel videos', async function () {
90 const res = await getVideoChannelVideos(servers[0].url, undefined, 'root_channel@localhost:9002', 0, 5)
91
92 expect(res.body.total).to.equal(1)
93 expect(res.body.data).to.have.lengthOf(1)
94 })
95 })
96
97 describe('With a logged user', function () {
98 it('Should get the local video', async function () {
99 await getVideoWithToken(servers[0].url, userAccessToken, video1UUID, 200)
100 })
101
102 it('Should get the remote video', async function () {
103 await getVideoWithToken(servers[0].url, userAccessToken, video2UUID, 200)
104 })
105
106 it('Should list local account videos', async function () {
107 const res = await getAccountVideos(servers[0].url, userAccessToken, 'root@localhost:9001', 0, 5)
108
109 expect(res.body.total).to.equal(1)
110 expect(res.body.data).to.have.lengthOf(1)
111 })
112
113 it('Should list remote account videos', async function () {
114 const res = await getAccountVideos(servers[0].url, userAccessToken, 'root@localhost:9002', 0, 5)
115
116 expect(res.body.total).to.equal(1)
117 expect(res.body.data).to.have.lengthOf(1)
118 })
119
120 it('Should list local channel videos', async function () {
121 const res = await getVideoChannelVideos(servers[0].url, userAccessToken, 'root_channel@localhost:9001', 0, 5)
122
123 expect(res.body.total).to.equal(1)
124 expect(res.body.data).to.have.lengthOf(1)
125 })
126
127 it('Should list remote channel videos', async function () {
128 const res = await getVideoChannelVideos(servers[0].url, userAccessToken, 'root_channel@localhost:9002', 0, 5)
129
130 expect(res.body.total).to.equal(1)
131 expect(res.body.data).to.have.lengthOf(1)
132 })
133 })
134 })
135
136 describe('With a non followed instance', function () {
137
138 before(async function () {
139 this.timeout(30000)
140
141 await unfollow(servers[0].url, servers[0].accessToken, servers[1])
142 })
143
144 describe('With an unlogged user', function () {
145
146 it('Should get the local video', async function () {
147 await getVideo(servers[0].url, video1UUID, 200)
148 })
149
150 it('Should not get the remote video', async function () {
151 await getVideo(servers[0].url, video2UUID, 403)
152 })
153
154 it('Should list local account videos', async function () {
155 const res = await getAccountVideos(servers[0].url, undefined, 'root@localhost:9001', 0, 5)
156
157 expect(res.body.total).to.equal(1)
158 expect(res.body.data).to.have.lengthOf(1)
159 })
160
161 it('Should not list remote account videos', async function () {
162 const res = await getAccountVideos(servers[0].url, undefined, 'root@localhost:9002', 0, 5)
163
164 expect(res.body.total).to.equal(0)
165 expect(res.body.data).to.have.lengthOf(0)
166 })
167
168 it('Should list local channel videos', async function () {
169 const res = await getVideoChannelVideos(servers[0].url, undefined, 'root_channel@localhost:9001', 0, 5)
170
171 expect(res.body.total).to.equal(1)
172 expect(res.body.data).to.have.lengthOf(1)
173 })
174
175 it('Should not list remote channel videos', async function () {
176 const res = await getVideoChannelVideos(servers[0].url, undefined, 'root_channel@localhost:9002', 0, 5)
177
178 expect(res.body.total).to.equal(0)
179 expect(res.body.data).to.have.lengthOf(0)
180 })
181 })
182
183 describe('With a logged user', function () {
184 it('Should get the local video', async function () {
185 await getVideoWithToken(servers[0].url, userAccessToken, video1UUID, 200)
186 })
187
188 it('Should get the remote video', async function () {
189 await getVideoWithToken(servers[0].url, userAccessToken, video2UUID, 200)
190 })
191
192 it('Should list local account videos', async function () {
193 const res = await getAccountVideos(servers[0].url, userAccessToken, 'root@localhost:9001', 0, 5)
194
195 expect(res.body.total).to.equal(1)
196 expect(res.body.data).to.have.lengthOf(1)
197 })
198
199 it('Should list remote account videos', async function () {
200 const res = await getAccountVideos(servers[0].url, userAccessToken, 'root@localhost:9002', 0, 5)
201
202 expect(res.body.total).to.equal(1)
203 expect(res.body.data).to.have.lengthOf(1)
204 })
205
206 it('Should list local channel videos', async function () {
207 const res = await getVideoChannelVideos(servers[0].url, userAccessToken, 'root_channel@localhost:9001', 0, 5)
208
209 expect(res.body.total).to.equal(1)
210 expect(res.body.data).to.have.lengthOf(1)
211 })
212
213 it('Should list remote channel videos', async function () {
214 const res = await getVideoChannelVideos(servers[0].url, userAccessToken, 'root_channel@localhost:9002', 0, 5)
215
216 expect(res.body.total).to.equal(1)
217 expect(res.body.data).to.have.lengthOf(1)
218 })
219 })
220 })
221
222 after(async function () {
223 killallServers(servers)
224 })
225})
diff --git a/server/tests/api/server/follows.ts b/server/tests/api/server/follows.ts
index e8914a9d4..ad4c87c73 100644
--- a/server/tests/api/server/follows.ts
+++ b/server/tests/api/server/follows.ts
@@ -4,7 +4,7 @@ import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { Video, VideoPrivacy } from '../../../../shared/models/videos' 5import { Video, VideoPrivacy } from '../../../../shared/models/videos'
6import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' 6import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
7import { completeVideoCheck } from '../../utils' 7import { completeVideoCheck } from '../../../../shared/utils'
8import { 8import {
9 flushAndRunMultipleServers, 9 flushAndRunMultipleServers,
10 getVideosList, 10 getVideosList,
@@ -12,21 +12,26 @@ import {
12 ServerInfo, 12 ServerInfo,
13 setAccessTokensToServers, 13 setAccessTokensToServers,
14 uploadVideo 14 uploadVideo
15} from '../../utils/index' 15} from '../../../../shared/utils/index'
16import { dateIsValid } from '../../utils/miscs/miscs' 16import { dateIsValid } from '../../../../shared/utils/miscs/miscs'
17import { follow, getFollowersListPaginationAndSort, getFollowingListPaginationAndSort, unfollow } from '../../utils/server/follows' 17import {
18import { expectAccountFollows } from '../../utils/users/accounts' 18 follow,
19import { userLogin } from '../../utils/users/login' 19 getFollowersListPaginationAndSort,
20import { createUser } from '../../utils/users/users' 20 getFollowingListPaginationAndSort,
21 unfollow
22} from '../../../../shared/utils/server/follows'
23import { expectAccountFollows } from '../../../../shared/utils/users/accounts'
24import { userLogin } from '../../../../shared/utils/users/login'
25import { createUser } from '../../../../shared/utils/users/users'
21import { 26import {
22 addVideoCommentReply, 27 addVideoCommentReply,
23 addVideoCommentThread, 28 addVideoCommentThread,
24 getVideoCommentThreads, 29 getVideoCommentThreads,
25 getVideoThreadComments 30 getVideoThreadComments
26} from '../../utils/videos/video-comments' 31} from '../../../../shared/utils/videos/video-comments'
27import { rateVideo } from '../../utils/videos/videos' 32import { rateVideo } from '../../../../shared/utils/videos/videos'
28import { waitJobs } from '../../utils/server/jobs' 33import { waitJobs } from '../../../../shared/utils/server/jobs'
29import { createVideoCaption, listVideoCaptions, testCaptionFile } from '../../utils/videos/video-captions' 34import { createVideoCaption, listVideoCaptions, testCaptionFile } from '../../../../shared/utils/videos/video-captions'
30import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model' 35import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model'
31 36
32const expect = chai.expect 37const expect = chai.expect
@@ -93,7 +98,26 @@ describe('Test follows', function () {
93 expect(server3Follow.state).to.equal('accepted') 98 expect(server3Follow.state).to.equal('accepted')
94 }) 99 })
95 100
96 it('Should have 0 followings on server 1 and 2', async function () { 101 it('Should search followings on server 1', async function () {
102 {
103 const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', ':9002')
104 const follows = res.body.data
105
106 expect(res.body.total).to.equal(1)
107 expect(follows.length).to.equal(1)
108 expect(follows[ 0 ].following.host).to.equal('localhost:9002')
109 }
110
111 {
112 const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 1, 'createdAt', 'bla')
113 const follows = res.body.data
114
115 expect(res.body.total).to.equal(0)
116 expect(follows.length).to.equal(0)
117 }
118 })
119
120 it('Should have 0 followings on server 2 and 3', async function () {
97 for (const server of [ servers[1], servers[2] ]) { 121 for (const server of [ servers[1], servers[2] ]) {
98 const res = await getFollowingListPaginationAndSort(server.url, 0, 5, 'createdAt') 122 const res = await getFollowingListPaginationAndSort(server.url, 0, 5, 'createdAt')
99 const follows = res.body.data 123 const follows = res.body.data
@@ -116,6 +140,25 @@ describe('Test follows', function () {
116 } 140 }
117 }) 141 })
118 142
143 it('Should search followers on server 2', async function () {
144 {
145 const res = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', '9001')
146 const follows = res.body.data
147
148 expect(res.body.total).to.equal(1)
149 expect(follows.length).to.equal(1)
150 expect(follows[ 0 ].following.host).to.equal('localhost:9003')
151 }
152
153 {
154 const res = await getFollowersListPaginationAndSort(servers[ 2 ].url, 0, 5, 'createdAt', 'bla')
155 const follows = res.body.data
156
157 expect(res.body.total).to.equal(0)
158 expect(follows.length).to.equal(0)
159 }
160 })
161
119 it('Should have 0 followers on server 1', async function () { 162 it('Should have 0 followers on server 1', async function () {
120 const res = await getFollowersListPaginationAndSort(servers[0].url, 0, 5, 'createdAt') 163 const res = await getFollowersListPaginationAndSort(servers[0].url, 0, 5, 'createdAt')
121 const follows = res.body.data 164 const follows = res.body.data
diff --git a/server/tests/api/server/handle-down.ts b/server/tests/api/server/handle-down.ts
index b0a3d029a..cd5acbe16 100644
--- a/server/tests/api/server/handle-down.ts
+++ b/server/tests/api/server/handle-down.ts
@@ -5,24 +5,30 @@ import 'mocha'
5import { JobState, Video } from '../../../../shared/models' 5import { JobState, Video } from '../../../../shared/models'
6import { VideoPrivacy } from '../../../../shared/models/videos' 6import { VideoPrivacy } from '../../../../shared/models/videos'
7import { VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model' 7import { VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
8import { completeVideoCheck, getVideo, immutableAssign, reRunServer, unfollow, viewVideo } from '../../utils' 8
9import { 9import {
10 completeVideoCheck,
10 flushAndRunMultipleServers, 11 flushAndRunMultipleServers,
12 getVideo,
11 getVideosList, 13 getVideosList,
14 immutableAssign,
12 killallServers, 15 killallServers,
16 reRunServer,
13 ServerInfo, 17 ServerInfo,
14 setAccessTokensToServers, 18 setAccessTokensToServers,
19 unfollow,
20 updateVideo,
15 uploadVideo, 21 uploadVideo,
16 wait 22 wait
17} from '../../utils/index' 23} from '../../../../shared/utils'
18import { follow, getFollowersListPaginationAndSort } from '../../utils/server/follows' 24import { follow, getFollowersListPaginationAndSort } from '../../../../shared/utils/server/follows'
19import { getJobsListPaginationAndSort, waitJobs } from '../../utils/server/jobs' 25import { getJobsListPaginationAndSort, waitJobs } from '../../../../shared/utils/server/jobs'
20import { 26import {
21 addVideoCommentReply, 27 addVideoCommentReply,
22 addVideoCommentThread, 28 addVideoCommentThread,
23 getVideoCommentThreads, 29 getVideoCommentThreads,
24 getVideoThreadComments 30 getVideoThreadComments
25} from '../../utils/videos/video-comments' 31} from '../../../../shared/utils/videos/video-comments'
26 32
27const expect = chai.expect 33const expect = chai.expect
28 34
@@ -195,15 +201,15 @@ describe('Test handle downs', function () {
195 expect(res.body.data).to.have.lengthOf(2) 201 expect(res.body.data).to.have.lengthOf(2)
196 }) 202 })
197 203
198 it('Should send a view to server 3, and automatically fetch the video', async function () { 204 it('Should send an update to server 3, and automatically fetch the video', async function () {
199 this.timeout(15000) 205 this.timeout(15000)
200 206
201 const res1 = await getVideosList(servers[2].url) 207 const res1 = await getVideosList(servers[2].url)
202 expect(res1.body.data).to.be.an('array') 208 expect(res1.body.data).to.be.an('array')
203 expect(res1.body.data).to.have.lengthOf(11) 209 expect(res1.body.data).to.have.lengthOf(11)
204 210
205 await viewVideo(servers[0].url, missedVideo1.uuid) 211 await updateVideo(servers[0].url, servers[0].accessToken, missedVideo1.uuid, { })
206 await viewVideo(servers[0].url, unlistedVideo.uuid) 212 await updateVideo(servers[0].url, servers[0].accessToken, unlistedVideo.uuid, { })
207 213
208 await waitJobs(servers) 214 await waitJobs(servers)
209 215
diff --git a/server/tests/api/server/index.ts b/server/tests/api/server/index.ts
index c74c68a33..1f80cc6cf 100644
--- a/server/tests/api/server/index.ts
+++ b/server/tests/api/server/index.ts
@@ -1,9 +1,11 @@
1import './config' 1import './config'
2import './contact-form'
2import './email' 3import './email'
4import './follow-constraints'
3import './follows' 5import './follows'
4import './handle-down' 6import './handle-down'
5import './jobs' 7import './jobs'
6import './redundancy'
7import './reverse-proxy' 8import './reverse-proxy'
8import './stats' 9import './stats'
9import './tracker' 10import './tracker'
11import './no-client'
diff --git a/server/tests/api/server/jobs.ts b/server/tests/api/server/jobs.ts
index cd59d9a1b..52948b1d6 100644
--- a/server/tests/api/server/jobs.ts
+++ b/server/tests/api/server/jobs.ts
@@ -2,12 +2,12 @@
2 2
3import * as chai from 'chai' 3import * as chai from 'chai'
4import 'mocha' 4import 'mocha'
5import { killallServers, ServerInfo, setAccessTokensToServers } from '../../utils/index' 5import { killallServers, ServerInfo, setAccessTokensToServers } from '../../../../shared/utils/index'
6import { doubleFollow } from '../../utils/server/follows' 6import { doubleFollow } from '../../../../shared/utils/server/follows'
7import { getJobsList, getJobsListPaginationAndSort, waitJobs } from '../../utils/server/jobs' 7import { getJobsList, getJobsListPaginationAndSort, waitJobs } from '../../../../shared/utils/server/jobs'
8import { flushAndRunMultipleServers } from '../../utils/server/servers' 8import { flushAndRunMultipleServers } from '../../../../shared/utils/server/servers'
9import { uploadVideo } from '../../utils/videos/videos' 9import { uploadVideo } from '../../../../shared/utils/videos/videos'
10import { dateIsValid } from '../../utils/miscs/miscs' 10import { dateIsValid } from '../../../../shared/utils/miscs/miscs'
11 11
12const expect = chai.expect 12const expect = chai.expect
13 13
diff --git a/server/tests/api/server/no-client.ts b/server/tests/api/server/no-client.ts
new file mode 100644
index 000000000..3b95ce945
--- /dev/null
+++ b/server/tests/api/server/no-client.ts
@@ -0,0 +1,36 @@
1import 'mocha'
2import * as request from 'supertest'
3import {
4 flushTests,
5 killallServers,
6 ServerInfo
7} from '../../../../shared/utils'
8import { runServer } from '../../../../shared/utils/server/servers'
9
10describe('Start and stop server without web client routes', function () {
11 let server: ServerInfo
12
13 before(async function () {
14 this.timeout(30000)
15
16 await flushTests()
17
18 server = await runServer(1, {}, ['--no-client'])
19 })
20
21 it('Should fail getting the client', function () {
22 const req = request(server.url)
23 .get('/')
24
25 return req.expect(404)
26 })
27
28 after(async function () {
29 killallServers([ server ])
30
31 // Keep the logs if the test failed
32 if (this['ok']) {
33 await flushTests()
34 }
35 })
36})
diff --git a/server/tests/api/server/redundancy.ts b/server/tests/api/server/redundancy.ts
deleted file mode 100644
index 1960854b6..000000000
--- a/server/tests/api/server/redundancy.ts
+++ /dev/null
@@ -1,483 +0,0 @@
1/* tslint:disable:no-unused-expression */
2
3import * as chai from 'chai'
4import 'mocha'
5import { VideoDetails } from '../../../../shared/models/videos'
6import {
7 doubleFollow,
8 flushAndRunMultipleServers,
9 getFollowingListPaginationAndSort,
10 getVideo,
11 immutableAssign,
12 killallServers, makeGetRequest,
13 root,
14 ServerInfo,
15 setAccessTokensToServers, unfollow,
16 uploadVideo,
17 viewVideo,
18 wait,
19 waitUntilLog,
20 checkVideoFilesWereRemoved, removeVideo
21} from '../../utils'
22import { waitJobs } from '../../utils/server/jobs'
23import * as magnetUtil from 'magnet-uri'
24import { updateRedundancy } from '../../utils/server/redundancy'
25import { ActorFollow } from '../../../../shared/models/actors'
26import { readdir } from 'fs-extra'
27import { join } from 'path'
28import { VideoRedundancyStrategy } from '../../../../shared/models/redundancy'
29import { getStats } from '../../utils/server/stats'
30import { ServerStats } from '../../../../shared/models/server/server-stats.model'
31
32const expect = chai.expect
33
34let servers: ServerInfo[] = []
35let video1Server2UUID: string
36
37function checkMagnetWebseeds (file: { magnetUri: string, resolution: { id: number } }, baseWebseeds: string[], server: ServerInfo) {
38 const parsed = magnetUtil.decode(file.magnetUri)
39
40 for (const ws of baseWebseeds) {
41 const found = parsed.urlList.find(url => url === `${ws}-${file.resolution.id}.mp4`)
42 expect(found, `Webseed ${ws} not found in ${file.magnetUri} on server ${server.url}`).to.not.be.undefined
43 }
44
45 expect(parsed.urlList).to.have.lengthOf(baseWebseeds.length)
46}
47
48async function runServers (strategy: VideoRedundancyStrategy, additionalParams: any = {}) {
49 const config = {
50 redundancy: {
51 videos: {
52 check_interval: '5 seconds',
53 strategies: [
54 immutableAssign({
55 min_lifetime: '1 hour',
56 strategy: strategy,
57 size: '100KB'
58 }, additionalParams)
59 ]
60 }
61 }
62 }
63 servers = await flushAndRunMultipleServers(3, config)
64
65 // Get the access tokens
66 await setAccessTokensToServers(servers)
67
68 {
69 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video 1 server 2' })
70 video1Server2UUID = res.body.video.uuid
71
72 await viewVideo(servers[ 1 ].url, video1Server2UUID)
73 }
74
75 await waitJobs(servers)
76
77 // Server 1 and server 2 follow each other
78 await doubleFollow(servers[ 0 ], servers[ 1 ])
79 // Server 1 and server 3 follow each other
80 await doubleFollow(servers[ 0 ], servers[ 2 ])
81 // Server 2 and server 3 follow each other
82 await doubleFollow(servers[ 1 ], servers[ 2 ])
83
84 await waitJobs(servers)
85}
86
87async function check1WebSeed (strategy: VideoRedundancyStrategy, videoUUID?: string) {
88 if (!videoUUID) videoUUID = video1Server2UUID
89
90 const webseeds = [
91 'http://localhost:9002/static/webseed/' + videoUUID
92 ]
93
94 for (const server of servers) {
95 {
96 const res = await getVideo(server.url, videoUUID)
97
98 const video: VideoDetails = res.body
99 for (const f of video.files) {
100 checkMagnetWebseeds(f, webseeds, server)
101 }
102 }
103 }
104}
105
106async function checkStatsWith2Webseed (strategy: VideoRedundancyStrategy) {
107 const res = await getStats(servers[0].url)
108 const data: ServerStats = res.body
109
110 expect(data.videosRedundancy).to.have.lengthOf(1)
111 const stat = data.videosRedundancy[0]
112
113 expect(stat.strategy).to.equal(strategy)
114 expect(stat.totalSize).to.equal(102400)
115 expect(stat.totalUsed).to.be.at.least(1).and.below(102401)
116 expect(stat.totalVideoFiles).to.equal(4)
117 expect(stat.totalVideos).to.equal(1)
118}
119
120async function checkStatsWith1Webseed (strategy: VideoRedundancyStrategy) {
121 const res = await getStats(servers[0].url)
122 const data: ServerStats = res.body
123
124 expect(data.videosRedundancy).to.have.lengthOf(1)
125
126 const stat = data.videosRedundancy[0]
127 expect(stat.strategy).to.equal(strategy)
128 expect(stat.totalSize).to.equal(102400)
129 expect(stat.totalUsed).to.equal(0)
130 expect(stat.totalVideoFiles).to.equal(0)
131 expect(stat.totalVideos).to.equal(0)
132}
133
134async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: string) {
135 if (!videoUUID) videoUUID = video1Server2UUID
136
137 const webseeds = [
138 'http://localhost:9001/static/webseed/' + videoUUID,
139 'http://localhost:9002/static/webseed/' + videoUUID
140 ]
141
142 for (const server of servers) {
143 const res = await getVideo(server.url, videoUUID)
144
145 const video: VideoDetails = res.body
146
147 for (const file of video.files) {
148 checkMagnetWebseeds(file, webseeds, server)
149
150 // Only servers 1 and 2 have the video
151 if (server.serverNumber !== 3) {
152 await makeGetRequest({
153 url: server.url,
154 statusCodeExpected: 200,
155 path: '/static/webseed/' + `${videoUUID}-${file.resolution.id}.mp4`,
156 contentType: null
157 })
158 }
159 }
160 }
161
162 for (const directory of [ 'test1', 'test2' ]) {
163 const files = await readdir(join(root(), directory, 'videos'))
164 expect(files).to.have.length.at.least(4)
165
166 for (const resolution of [ 240, 360, 480, 720 ]) {
167 expect(files.find(f => f === `${videoUUID}-${resolution}.mp4`)).to.not.be.undefined
168 }
169 }
170}
171
172async function enableRedundancyOnServer1 () {
173 await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, true)
174
175 const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 5, '-createdAt')
176 const follows: ActorFollow[] = res.body.data
177 const server2 = follows.find(f => f.following.host === 'localhost:9002')
178 const server3 = follows.find(f => f.following.host === 'localhost:9003')
179
180 expect(server3).to.not.be.undefined
181 expect(server3.following.hostRedundancyAllowed).to.be.false
182
183 expect(server2).to.not.be.undefined
184 expect(server2.following.hostRedundancyAllowed).to.be.true
185}
186
187async function disableRedundancyOnServer1 () {
188 await updateRedundancy(servers[ 0 ].url, servers[ 0 ].accessToken, servers[ 1 ].host, false)
189
190 const res = await getFollowingListPaginationAndSort(servers[ 0 ].url, 0, 5, '-createdAt')
191 const follows: ActorFollow[] = res.body.data
192 const server2 = follows.find(f => f.following.host === 'localhost:9002')
193 const server3 = follows.find(f => f.following.host === 'localhost:9003')
194
195 expect(server3).to.not.be.undefined
196 expect(server3.following.hostRedundancyAllowed).to.be.false
197
198 expect(server2).to.not.be.undefined
199 expect(server2.following.hostRedundancyAllowed).to.be.false
200}
201
202async function cleanServers () {
203 killallServers(servers)
204}
205
206describe('Test videos redundancy', function () {
207
208 describe('With most-views strategy', function () {
209 const strategy = 'most-views'
210
211 before(function () {
212 this.timeout(120000)
213
214 return runServers(strategy)
215 })
216
217 it('Should have 1 webseed on the first video', async function () {
218 await check1WebSeed(strategy)
219 await checkStatsWith1Webseed(strategy)
220 })
221
222 it('Should enable redundancy on server 1', function () {
223 return enableRedundancyOnServer1()
224 })
225
226 it('Should have 2 webseed on the first video', async function () {
227 this.timeout(40000)
228
229 await waitJobs(servers)
230 await waitUntilLog(servers[0], 'Duplicated ', 4)
231 await waitJobs(servers)
232
233 await check2Webseeds(strategy)
234 await checkStatsWith2Webseed(strategy)
235 })
236
237 it('Should undo redundancy on server 1 and remove duplicated videos', async function () {
238 this.timeout(40000)
239
240 await disableRedundancyOnServer1()
241
242 await waitJobs(servers)
243 await wait(5000)
244
245 await check1WebSeed(strategy)
246
247 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos' ])
248 })
249
250 after(function () {
251 return cleanServers()
252 })
253 })
254
255 describe('With trending strategy', function () {
256 const strategy = 'trending'
257
258 before(function () {
259 this.timeout(120000)
260
261 return runServers(strategy)
262 })
263
264 it('Should have 1 webseed on the first video', async function () {
265 await check1WebSeed(strategy)
266 await checkStatsWith1Webseed(strategy)
267 })
268
269 it('Should enable redundancy on server 1', function () {
270 return enableRedundancyOnServer1()
271 })
272
273 it('Should have 2 webseed on the first video', async function () {
274 this.timeout(40000)
275
276 await waitJobs(servers)
277 await waitUntilLog(servers[0], 'Duplicated ', 4)
278 await waitJobs(servers)
279
280 await check2Webseeds(strategy)
281 await checkStatsWith2Webseed(strategy)
282 })
283
284 it('Should unfollow on server 1 and remove duplicated videos', async function () {
285 this.timeout(40000)
286
287 await unfollow(servers[0].url, servers[0].accessToken, servers[1])
288
289 await waitJobs(servers)
290 await wait(5000)
291
292 await check1WebSeed(strategy)
293
294 await checkVideoFilesWereRemoved(video1Server2UUID, servers[0].serverNumber, [ 'videos' ])
295 })
296
297 after(function () {
298 return cleanServers()
299 })
300 })
301
302 describe('With recently added strategy', function () {
303 const strategy = 'recently-added'
304
305 before(function () {
306 this.timeout(120000)
307
308 return runServers(strategy, { min_views: 3 })
309 })
310
311 it('Should have 1 webseed on the first video', async function () {
312 await check1WebSeed(strategy)
313 await checkStatsWith1Webseed(strategy)
314 })
315
316 it('Should enable redundancy on server 1', function () {
317 return enableRedundancyOnServer1()
318 })
319
320 it('Should still have 1 webseed on the first video', async function () {
321 this.timeout(40000)
322
323 await waitJobs(servers)
324 await wait(15000)
325 await waitJobs(servers)
326
327 await check1WebSeed(strategy)
328 await checkStatsWith1Webseed(strategy)
329 })
330
331 it('Should view 2 times the first video to have > min_views config', async function () {
332 this.timeout(40000)
333
334 await viewVideo(servers[ 0 ].url, video1Server2UUID)
335 await viewVideo(servers[ 2 ].url, video1Server2UUID)
336
337 await wait(10000)
338 await waitJobs(servers)
339 })
340
341 it('Should have 2 webseed on the first video', async function () {
342 this.timeout(40000)
343
344 await waitJobs(servers)
345 await waitUntilLog(servers[0], 'Duplicated ', 4)
346 await waitJobs(servers)
347
348 await check2Webseeds(strategy)
349 await checkStatsWith2Webseed(strategy)
350 })
351
352 it('Should remove the video and the redundancy files', async function () {
353 this.timeout(20000)
354
355 await removeVideo(servers[1].url, servers[1].accessToken, video1Server2UUID)
356
357 await waitJobs(servers)
358
359 for (const server of servers) {
360 await checkVideoFilesWereRemoved(video1Server2UUID, server.serverNumber)
361 }
362 })
363
364 after(function () {
365 return cleanServers()
366 })
367 })
368
369 describe('Test expiration', function () {
370 const strategy = 'recently-added'
371
372 async function checkContains (servers: ServerInfo[], str: string) {
373 for (const server of servers) {
374 const res = await getVideo(server.url, video1Server2UUID)
375 const video: VideoDetails = res.body
376
377 for (const f of video.files) {
378 expect(f.magnetUri).to.contain(str)
379 }
380 }
381 }
382
383 async function checkNotContains (servers: ServerInfo[], str: string) {
384 for (const server of servers) {
385 const res = await getVideo(server.url, video1Server2UUID)
386 const video: VideoDetails = res.body
387
388 for (const f of video.files) {
389 expect(f.magnetUri).to.not.contain(str)
390 }
391 }
392 }
393
394 before(async function () {
395 this.timeout(120000)
396
397 await runServers(strategy, { min_lifetime: '7 seconds', min_views: 0 })
398
399 await enableRedundancyOnServer1()
400 })
401
402 it('Should still have 2 webseeds after 10 seconds', async function () {
403 this.timeout(40000)
404
405 await wait(10000)
406
407 try {
408 await checkContains(servers, 'http%3A%2F%2Flocalhost%3A9001')
409 } catch {
410 // Maybe a server deleted a redundancy in the scheduler
411 await wait(2000)
412
413 await checkContains(servers, 'http%3A%2F%2Flocalhost%3A9001')
414 }
415 })
416
417 it('Should stop server 1 and expire video redundancy', async function () {
418 this.timeout(40000)
419
420 killallServers([ servers[0] ])
421
422 await wait(10000)
423
424 await checkNotContains([ servers[1], servers[2] ], 'http%3A%2F%2Flocalhost%3A9001')
425 })
426
427 after(function () {
428 return killallServers([ servers[1], servers[2] ])
429 })
430 })
431
432 describe('Test file replacement', function () {
433 let video2Server2UUID: string
434 const strategy = 'recently-added'
435
436 before(async function () {
437 this.timeout(120000)
438
439 await runServers(strategy, { min_lifetime: '7 seconds', min_views: 0 })
440
441 await enableRedundancyOnServer1()
442
443 await waitJobs(servers)
444 await waitUntilLog(servers[0], 'Duplicated ', 4)
445 await waitJobs(servers)
446
447 await check2Webseeds(strategy)
448 await checkStatsWith2Webseed(strategy)
449
450 const res = await uploadVideo(servers[ 1 ].url, servers[ 1 ].accessToken, { name: 'video 2 server 2' })
451 video2Server2UUID = res.body.video.uuid
452 })
453
454 it('Should cache video 2 webseed on the first video', async function () {
455 this.timeout(50000)
456
457 await waitJobs(servers)
458
459 await wait(7000)
460
461 try {
462 await check1WebSeed(strategy, video1Server2UUID)
463 await check2Webseeds(strategy, video2Server2UUID)
464 } catch {
465 await wait(3000)
466
467 try {
468 await check1WebSeed(strategy, video1Server2UUID)
469 await check2Webseeds(strategy, video2Server2UUID)
470 } catch {
471 await wait(5000)
472
473 await check1WebSeed(strategy, video1Server2UUID)
474 await check2Webseeds(strategy, video2Server2UUID)
475 }
476 }
477 })
478
479 after(function () {
480 return cleanServers()
481 })
482 })
483})
diff --git a/server/tests/api/server/reverse-proxy.ts b/server/tests/api/server/reverse-proxy.ts
index e2c2a293e..ee0fffd5a 100644
--- a/server/tests/api/server/reverse-proxy.ts
+++ b/server/tests/api/server/reverse-proxy.ts
@@ -15,7 +15,7 @@ import {
15 userLogin, 15 userLogin,
16 viewVideo, 16 viewVideo,
17 wait 17 wait
18} from '../../utils' 18} from '../../../../shared/utils'
19const expect = chai.expect 19const expect = chai.expect
20 20
21import { 21import {
@@ -23,7 +23,7 @@ import {
23 flushTests, 23 flushTests,
24 runServer, 24 runServer,
25 registerUser, getCustomConfig, setAccessTokensToServers, updateCustomConfig 25 registerUser, getCustomConfig, setAccessTokensToServers, updateCustomConfig
26} from '../../utils/index' 26} from '../../../../shared/utils/index'
27 27
28describe('Test application behind a reverse proxy', function () { 28describe('Test application behind a reverse proxy', function () {
29 let server = null 29 let server = null
@@ -95,7 +95,7 @@ describe('Test application behind a reverse proxy', function () {
95 it('Should rate limit logins', async function () { 95 it('Should rate limit logins', async function () {
96 const user = { username: 'root', password: 'fail' } 96 const user = { username: 'root', password: 'fail' }
97 97
98 for (let i = 0; i < 14; i++) { 98 for (let i = 0; i < 19; i++) {
99 await userLogin(server, user, 400) 99 await userLogin(server, user, 400)
100 } 100 }
101 101
diff --git a/server/tests/api/server/stats.ts b/server/tests/api/server/stats.ts
index cb229e876..aaa6c62f7 100644
--- a/server/tests/api/server/stats.ts
+++ b/server/tests/api/server/stats.ts
@@ -13,11 +13,11 @@ import {
13 uploadVideo, 13 uploadVideo,
14 viewVideo, 14 viewVideo,
15 wait 15 wait
16} from '../../utils' 16} from '../../../../shared/utils'
17import { flushTests, setAccessTokensToServers } from '../../utils/index' 17import { flushTests, setAccessTokensToServers } from '../../../../shared/utils/index'
18import { getStats } from '../../utils/server/stats' 18import { getStats } from '../../../../shared/utils/server/stats'
19import { addVideoCommentThread } from '../../utils/videos/video-comments' 19import { addVideoCommentThread } from '../../../../shared/utils/videos/video-comments'
20import { waitJobs } from '../../utils/server/jobs' 20import { waitJobs } from '../../../../shared/utils/server/jobs'
21 21
22const expect = chai.expect 22const expect = chai.expect
23 23
@@ -39,7 +39,7 @@ describe('Test stats (excluding redundancy)', function () {
39 } 39 }
40 await createUser(servers[0].url, servers[0].accessToken, user.username, user.password) 40 await createUser(servers[0].url, servers[0].accessToken, user.username, user.password)
41 41
42 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, {}) 42 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { fixture: 'video_short.webm' })
43 const videoUUID = resVideo.body.video.uuid 43 const videoUUID = resVideo.body.video.uuid
44 44
45 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment') 45 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment')
@@ -60,6 +60,7 @@ describe('Test stats (excluding redundancy)', function () {
60 expect(data.totalLocalVideoComments).to.equal(1) 60 expect(data.totalLocalVideoComments).to.equal(1)
61 expect(data.totalLocalVideos).to.equal(1) 61 expect(data.totalLocalVideos).to.equal(1)
62 expect(data.totalLocalVideoViews).to.equal(1) 62 expect(data.totalLocalVideoViews).to.equal(1)
63 expect(data.totalLocalVideoFilesSize).to.equal(218910)
63 expect(data.totalUsers).to.equal(2) 64 expect(data.totalUsers).to.equal(2)
64 expect(data.totalVideoComments).to.equal(1) 65 expect(data.totalVideoComments).to.equal(1)
65 expect(data.totalVideos).to.equal(1) 66 expect(data.totalVideos).to.equal(1)
@@ -74,6 +75,7 @@ describe('Test stats (excluding redundancy)', function () {
74 expect(data.totalLocalVideoComments).to.equal(0) 75 expect(data.totalLocalVideoComments).to.equal(0)
75 expect(data.totalLocalVideos).to.equal(0) 76 expect(data.totalLocalVideos).to.equal(0)
76 expect(data.totalLocalVideoViews).to.equal(0) 77 expect(data.totalLocalVideoViews).to.equal(0)
78 expect(data.totalLocalVideoFilesSize).to.equal(0)
77 expect(data.totalUsers).to.equal(1) 79 expect(data.totalUsers).to.equal(1)
78 expect(data.totalVideoComments).to.equal(1) 80 expect(data.totalVideoComments).to.equal(1)
79 expect(data.totalVideos).to.equal(1) 81 expect(data.totalVideos).to.equal(1)
diff --git a/server/tests/api/server/tracker.ts b/server/tests/api/server/tracker.ts
index 856f2f4d1..25ca00029 100644
--- a/server/tests/api/server/tracker.ts
+++ b/server/tests/api/server/tracker.ts
@@ -2,8 +2,8 @@
2 2
3import * as magnetUtil from 'magnet-uri' 3import * as magnetUtil from 'magnet-uri'
4import 'mocha' 4import 'mocha'
5import { getVideo, killallServers, runServer, ServerInfo, uploadVideo } from '../../utils' 5import { getVideo, killallServers, runServer, ServerInfo, uploadVideo } from '../../../../shared/utils'
6import { flushTests, setAccessTokensToServers } from '../../utils/index' 6import { flushTests, setAccessTokensToServers } from '../../../../shared/utils/index'
7import { VideoDetails } from '../../../../shared/models/videos' 7import { VideoDetails } from '../../../../shared/models/videos'
8import * as WebTorrent from 'webtorrent' 8import * as WebTorrent from 'webtorrent'
9 9