]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/server/stats.ts
Introduce jobs command
[github/Chocobozzz/PeerTube.git] / server / tests / api / server / stats.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import 'mocha'
4 import * as chai from 'chai'
5 import {
6 addVideoChannel,
7 addVideoCommentThread,
8 cleanupTests,
9 createUser,
10 createVideoPlaylist,
11 doubleFollow,
12 flushAndRunMultipleServers,
13 ServerInfo,
14 setAccessTokensToServers,
15 updateCustomSubConfig,
16 uploadVideo,
17 userLogin,
18 viewVideo,
19 wait,
20 waitJobs
21 } from '@shared/extra-utils'
22 import { getStats } from '@shared/extra-utils/server/stats'
23 import { ActivityType, ServerStats, VideoPlaylistPrivacy } from '@shared/models'
24
25 const expect = chai.expect
26
27 describe('Test stats (excluding redundancy)', function () {
28 let servers: ServerInfo[] = []
29 let channelId
30 const user = {
31 username: 'user1',
32 password: 'super_password'
33 }
34
35 before(async function () {
36 this.timeout(60000)
37
38 servers = await flushAndRunMultipleServers(3)
39
40 await setAccessTokensToServers(servers)
41
42 await doubleFollow(servers[0], servers[1])
43
44 await createUser({ url: servers[0].url, accessToken: servers[0].accessToken, username: user.username, password: user.password })
45
46 const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { fixture: 'video_short.webm' })
47 const videoUUID = resVideo.body.video.uuid
48
49 await addVideoCommentThread(servers[0].url, servers[0].accessToken, videoUUID, 'comment')
50
51 await viewVideo(servers[0].url, videoUUID)
52
53 // Wait the video views repeatable job
54 await wait(8000)
55
56 await servers[2].followsCommand.follow({ targets: [ servers[0].url ] })
57 await waitJobs(servers)
58 })
59
60 it('Should have the correct stats on instance 1', async function () {
61 const res = await getStats(servers[0].url)
62 const data: ServerStats = res.body
63
64 expect(data.totalLocalVideoComments).to.equal(1)
65 expect(data.totalLocalVideos).to.equal(1)
66 expect(data.totalLocalVideoViews).to.equal(1)
67 expect(data.totalLocalVideoFilesSize).to.equal(218910)
68 expect(data.totalUsers).to.equal(2)
69 expect(data.totalVideoComments).to.equal(1)
70 expect(data.totalVideos).to.equal(1)
71 expect(data.totalInstanceFollowers).to.equal(2)
72 expect(data.totalInstanceFollowing).to.equal(1)
73 expect(data.totalLocalPlaylists).to.equal(0)
74 })
75
76 it('Should have the correct stats on instance 2', async function () {
77 const res = await getStats(servers[1].url)
78 const data: ServerStats = res.body
79
80 expect(data.totalLocalVideoComments).to.equal(0)
81 expect(data.totalLocalVideos).to.equal(0)
82 expect(data.totalLocalVideoViews).to.equal(0)
83 expect(data.totalLocalVideoFilesSize).to.equal(0)
84 expect(data.totalUsers).to.equal(1)
85 expect(data.totalVideoComments).to.equal(1)
86 expect(data.totalVideos).to.equal(1)
87 expect(data.totalInstanceFollowers).to.equal(1)
88 expect(data.totalInstanceFollowing).to.equal(1)
89 expect(data.totalLocalPlaylists).to.equal(0)
90 })
91
92 it('Should have the correct stats on instance 3', async function () {
93 const res = await getStats(servers[2].url)
94 const data: ServerStats = res.body
95
96 expect(data.totalLocalVideoComments).to.equal(0)
97 expect(data.totalLocalVideos).to.equal(0)
98 expect(data.totalLocalVideoViews).to.equal(0)
99 expect(data.totalUsers).to.equal(1)
100 expect(data.totalVideoComments).to.equal(1)
101 expect(data.totalVideos).to.equal(1)
102 expect(data.totalInstanceFollowing).to.equal(1)
103 expect(data.totalInstanceFollowers).to.equal(0)
104 expect(data.totalLocalPlaylists).to.equal(0)
105 })
106
107 it('Should have the correct total videos stats after an unfollow', async function () {
108 this.timeout(15000)
109
110 await servers[2].followsCommand.unfollow({ target: servers[0] })
111 await waitJobs(servers)
112
113 const res = await getStats(servers[2].url)
114 const data: ServerStats = res.body
115
116 expect(data.totalVideos).to.equal(0)
117 })
118
119 it('Should have the correct active user stats', async function () {
120 const server = servers[0]
121
122 {
123 const res = await getStats(server.url)
124 const data: ServerStats = res.body
125 expect(data.totalDailyActiveUsers).to.equal(1)
126 expect(data.totalWeeklyActiveUsers).to.equal(1)
127 expect(data.totalMonthlyActiveUsers).to.equal(1)
128 }
129
130 {
131 await userLogin(server, user)
132
133 const res = await getStats(server.url)
134 const data: ServerStats = res.body
135 expect(data.totalDailyActiveUsers).to.equal(2)
136 expect(data.totalWeeklyActiveUsers).to.equal(2)
137 expect(data.totalMonthlyActiveUsers).to.equal(2)
138 }
139 })
140
141 it('Should have the correct active channel stats', async function () {
142 const server = servers[0]
143
144 {
145 const res = await getStats(server.url)
146 const data: ServerStats = res.body
147 expect(data.totalLocalDailyActiveVideoChannels).to.equal(1)
148 expect(data.totalLocalWeeklyActiveVideoChannels).to.equal(1)
149 expect(data.totalLocalMonthlyActiveVideoChannels).to.equal(1)
150 }
151
152 {
153 const channelAttributes = {
154 name: 'stats_channel',
155 displayName: 'My stats channel'
156 }
157 const resChannel = await addVideoChannel(server.url, server.accessToken, channelAttributes)
158 channelId = resChannel.body.videoChannel.id
159
160 const res = await getStats(server.url)
161 const data: ServerStats = res.body
162 expect(data.totalLocalDailyActiveVideoChannels).to.equal(1)
163 expect(data.totalLocalWeeklyActiveVideoChannels).to.equal(1)
164 expect(data.totalLocalMonthlyActiveVideoChannels).to.equal(1)
165 }
166
167 {
168 await uploadVideo(server.url, server.accessToken, { fixture: 'video_short.webm', channelId })
169
170 const res = await getStats(server.url)
171 const data: ServerStats = res.body
172 expect(data.totalLocalDailyActiveVideoChannels).to.equal(2)
173 expect(data.totalLocalWeeklyActiveVideoChannels).to.equal(2)
174 expect(data.totalLocalMonthlyActiveVideoChannels).to.equal(2)
175 }
176 })
177
178 it('Should have the correct playlist stats', async function () {
179 const server = servers[0]
180
181 {
182 const resStats = await getStats(server.url)
183 const dataStats: ServerStats = resStats.body
184 expect(dataStats.totalLocalPlaylists).to.equal(0)
185 }
186
187 {
188 await createVideoPlaylist({
189 url: server.url,
190 token: server.accessToken,
191 playlistAttrs: {
192 displayName: 'playlist for count',
193 privacy: VideoPlaylistPrivacy.PUBLIC,
194 videoChannelId: channelId
195 }
196 })
197
198 const resStats = await getStats(server.url)
199 const dataStats: ServerStats = resStats.body
200 expect(dataStats.totalLocalPlaylists).to.equal(1)
201 }
202 })
203
204 it('Should correctly count video file sizes if transcoding is enabled', async function () {
205 this.timeout(60000)
206
207 await updateCustomSubConfig(servers[0].url, servers[0].accessToken, {
208 transcoding: {
209 enabled: true,
210 webtorrent: {
211 enabled: true
212 },
213 hls: {
214 enabled: true
215 },
216 resolutions: {
217 '0p': false,
218 '240p': false,
219 '360p': false,
220 '480p': false,
221 '720p': false,
222 '1080p': false,
223 '1440p': false,
224 '2160p': false
225 }
226 }
227 })
228
229 await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video', fixture: 'video_short.webm' })
230
231 await waitJobs(servers)
232
233 {
234 const res = await getStats(servers[1].url)
235 const data: ServerStats = res.body
236 expect(data.totalLocalVideoFilesSize).to.equal(0)
237 }
238
239 {
240 const res = await getStats(servers[0].url)
241 const data: ServerStats = res.body
242 expect(data.totalLocalVideoFilesSize).to.be.greaterThan(500000)
243 expect(data.totalLocalVideoFilesSize).to.be.lessThan(600000)
244 }
245 })
246
247 it('Should have the correct AP stats', async function () {
248 this.timeout(60000)
249
250 await updateCustomSubConfig(servers[0].url, servers[0].accessToken, {
251 transcoding: {
252 enabled: false
253 }
254 })
255
256 const res1 = await getStats(servers[1].url)
257 const first = res1.body as ServerStats
258
259 for (let i = 0; i < 10; i++) {
260 await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'video' })
261 }
262
263 await waitJobs(servers)
264
265 await wait(6000)
266
267 const res2 = await getStats(servers[1].url)
268 const second: ServerStats = res2.body
269
270 expect(second.totalActivityPubMessagesProcessed).to.be.greaterThan(first.totalActivityPubMessagesProcessed)
271 const apTypes: ActivityType[] = [
272 'Create', 'Update', 'Delete', 'Follow', 'Accept', 'Announce', 'Undo', 'Like', 'Reject', 'View', 'Dislike', 'Flag'
273 ]
274
275 const processed = apTypes.reduce(
276 (previous, type) => previous + second['totalActivityPub' + type + 'MessagesSuccesses'],
277 0
278 )
279 expect(second.totalActivityPubMessagesProcessed).to.equal(processed)
280 expect(second.totalActivityPubMessagesSuccesses).to.equal(processed)
281
282 expect(second.totalActivityPubMessagesErrors).to.equal(0)
283
284 for (const apType of apTypes) {
285 expect(second['totalActivityPub' + apType + 'MessagesErrors']).to.equal(0)
286 }
287
288 await wait(6000)
289
290 const res3 = await getStats(servers[1].url)
291 const third: ServerStats = res3.body
292
293 expect(third.totalActivityPubMessagesWaiting).to.equal(0)
294 expect(third.activityPubMessagesProcessedPerSecond).to.be.lessThan(second.activityPubMessagesProcessedPerSecond)
295 })
296
297 after(async function () {
298 await cleanupTests(servers)
299 })
300 })