]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/tests/api/views/video-views-counter.ts
Also retry when fetching master m3u8 playlist
[github/Chocobozzz/PeerTube.git] / server / tests / api / views / video-views-counter.ts
1 /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3 import { expect } from 'chai'
4 import { FfmpegCommand } from 'fluent-ffmpeg'
5 import { prepareViewsServers, prepareViewsVideos, processViewsBuffer } from '@server/tests/shared'
6 import { wait } from '@shared/core-utils'
7 import { cleanupTests, PeerTubeServer, stopFfmpeg, waitJobs } from '@shared/server-commands'
8
9 describe('Test video views/viewers counters', function () {
10 let servers: PeerTubeServer[]
11
12 async function checkCounter (field: 'views' | 'viewers', id: string, expected: number) {
13 for (const server of servers) {
14 const video = await server.videos.get({ id })
15
16 const messageSuffix = video.isLive
17 ? 'live video'
18 : 'vod video'
19
20 expect(video[field]).to.equal(expected, `${field} not valid on server ${server.serverNumber} for ${messageSuffix} ${video.uuid}`)
21 }
22 }
23
24 before(async function () {
25 this.timeout(120000)
26
27 servers = await prepareViewsServers()
28 })
29
30 describe('Test views counter on VOD', function () {
31 let videoUUID: string
32
33 before(async function () {
34 this.timeout(120000)
35
36 const { uuid } = await servers[0].videos.quickUpload({ name: 'video' })
37 videoUUID = uuid
38
39 await waitJobs(servers)
40 })
41
42 it('Should not view a video if watch time is below the threshold', async function () {
43 await servers[0].views.simulateViewer({ id: videoUUID, currentTimes: [ 1, 2 ] })
44 await processViewsBuffer(servers)
45
46 await checkCounter('views', videoUUID, 0)
47 })
48
49 it('Should view a video if watch time is above the threshold', async function () {
50 await servers[0].views.simulateViewer({ id: videoUUID, currentTimes: [ 1, 4 ] })
51 await processViewsBuffer(servers)
52
53 await checkCounter('views', videoUUID, 1)
54 })
55
56 it('Should not view again this video with the same IP', async function () {
57 await servers[0].views.simulateViewer({ id: videoUUID, xForwardedFor: '0.0.0.1,127.0.0.1', currentTimes: [ 1, 4 ] })
58 await servers[0].views.simulateViewer({ id: videoUUID, xForwardedFor: '0.0.0.1,127.0.0.1', currentTimes: [ 1, 4 ] })
59 await processViewsBuffer(servers)
60
61 await checkCounter('views', videoUUID, 2)
62 })
63
64 it('Should view the video from server 2 and send the event', async function () {
65 await servers[1].views.simulateViewer({ id: videoUUID, currentTimes: [ 1, 4 ] })
66 await waitJobs(servers)
67 await processViewsBuffer(servers)
68
69 await checkCounter('views', videoUUID, 3)
70 })
71 })
72
73 describe('Test views and viewers counters on live and VOD', function () {
74 let liveVideoId: string
75 let vodVideoId: string
76 let command: FfmpegCommand
77
78 before(async function () {
79 this.timeout(120000);
80
81 ({ vodVideoId, liveVideoId, ffmpegCommand: command } = await prepareViewsVideos({ servers, live: true, vod: true }))
82 })
83
84 it('Should display no views and viewers', async function () {
85 await checkCounter('views', liveVideoId, 0)
86 await checkCounter('viewers', liveVideoId, 0)
87
88 await checkCounter('views', vodVideoId, 0)
89 await checkCounter('viewers', vodVideoId, 0)
90 })
91
92 it('Should view twice and display 1 view/viewer', async function () {
93 this.timeout(30000)
94
95 await servers[0].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35 ] })
96 await servers[0].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35 ] })
97 await servers[0].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
98 await servers[0].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
99
100 await waitJobs(servers)
101 await checkCounter('viewers', liveVideoId, 1)
102 await checkCounter('viewers', vodVideoId, 1)
103
104 await processViewsBuffer(servers)
105
106 await checkCounter('views', liveVideoId, 1)
107 await checkCounter('views', vodVideoId, 1)
108 })
109
110 it('Should wait and display 0 viewers but still have 1 view', async function () {
111 this.timeout(30000)
112
113 await wait(12000)
114 await waitJobs(servers)
115
116 await checkCounter('views', liveVideoId, 1)
117 await checkCounter('viewers', liveVideoId, 0)
118
119 await checkCounter('views', vodVideoId, 1)
120 await checkCounter('viewers', vodVideoId, 0)
121 })
122
123 it('Should view on a remote and on local and display 2 viewers and 3 views', async function () {
124 this.timeout(30000)
125
126 await servers[0].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
127 await servers[1].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
128 await servers[1].views.simulateViewer({ id: vodVideoId, currentTimes: [ 0, 5 ] })
129
130 await servers[0].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35 ] })
131 await servers[1].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35 ] })
132 await servers[1].views.simulateViewer({ id: liveVideoId, currentTimes: [ 0, 35 ] })
133
134 await waitJobs(servers)
135
136 await checkCounter('viewers', liveVideoId, 2)
137 await checkCounter('viewers', vodVideoId, 2)
138
139 await processViewsBuffer(servers)
140
141 await checkCounter('views', liveVideoId, 3)
142 await checkCounter('views', vodVideoId, 3)
143 })
144
145 after(async function () {
146 await stopFfmpeg(command)
147 })
148 })
149
150 after(async function () {
151 await cleanupTests(servers)
152 })
153 })