]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/tests/api/live/live-socket-messages.ts
Introduce live command
[github/Chocobozzz/PeerTube.git] / server / tests / api / live / live-socket-messages.ts
CommitLineData
8ebf2a5d
C
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import 'mocha'
4import * as chai from 'chai'
8ebf2a5d
C
5import { VideoPrivacy, VideoState } from '@shared/models'
6import {
7 cleanupTests,
8ebf2a5d
C
8 doubleFollow,
9 flushAndRunMultipleServers,
10 getVideoIdFromUUID,
8ebf2a5d
C
11 ServerInfo,
12 setAccessTokensToServers,
13 setDefaultVideoChannel,
14 stopFfmpeg,
8ebf2a5d
C
15 viewVideo,
16 wait,
17 waitJobs,
8ebf2a5d
C
18 waitUntilLivePublishedOnAllServers
19} from '../../../../shared/extra-utils'
20
21const expect = chai.expect
22
23describe('Test live', function () {
24 let servers: ServerInfo[] = []
25
26 before(async function () {
27 this.timeout(120000)
28
29 servers = await flushAndRunMultipleServers(2)
30
31 // Get the access tokens
32 await setAccessTokensToServers(servers)
33 await setDefaultVideoChannel(servers)
34
65e6e260
C
35 await servers[0].configCommand.updateCustomSubConfig({
36 newConfig: {
37 live: {
38 enabled: true,
39 allowReplay: true,
40 transcoding: {
41 enabled: false
42 }
8ebf2a5d
C
43 }
44 }
45 })
46
47 // Server 1 and server 2 follow each other
48 await doubleFollow(servers[0], servers[1])
49 })
50
51 describe('Live socket messages', function () {
52
53 async function createLiveWrapper () {
54 const liveAttributes = {
55 name: 'live video',
56 channelId: servers[0].videoChannel.id,
57 privacy: VideoPrivacy.PUBLIC
58 }
59
4f219914
C
60 const { uuid } = await servers[0].liveCommand.createLive({ fields: liveAttributes })
61 return uuid
8ebf2a5d
C
62 }
63
64 it('Should correctly send a message when the live starts and ends', async function () {
65 this.timeout(60000)
66
67 const localStateChanges: VideoState[] = []
68 const remoteStateChanges: VideoState[] = []
69
70 const liveVideoUUID = await createLiveWrapper()
71 await waitJobs(servers)
72
73 {
74 const videoId = await getVideoIdFromUUID(servers[0].url, liveVideoUUID)
75
87e2635a 76 const localSocket = servers[0].socketIOCommand.getLiveNotificationSocket()
8ebf2a5d
C
77 localSocket.on('state-change', data => localStateChanges.push(data.state))
78 localSocket.emit('subscribe', { videoId })
79 }
80
81 {
82 const videoId = await getVideoIdFromUUID(servers[1].url, liveVideoUUID)
83
87e2635a 84 const remoteSocket = servers[1].socketIOCommand.getLiveNotificationSocket()
8ebf2a5d
C
85 remoteSocket.on('state-change', data => remoteStateChanges.push(data.state))
86 remoteSocket.emit('subscribe', { videoId })
87 }
88
4f219914 89 const ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
8ebf2a5d
C
90
91 await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID)
92 await waitJobs(servers)
93
94 for (const stateChanges of [ localStateChanges, remoteStateChanges ]) {
95 expect(stateChanges).to.have.length.at.least(1)
96 expect(stateChanges[stateChanges.length - 1]).to.equal(VideoState.PUBLISHED)
97 }
98
4f219914 99 await stopFfmpeg(ffmpegCommand)
8ebf2a5d
C
100
101 for (const server of servers) {
4f219914 102 await server.liveCommand.waitUntilLiveEnded({ videoId: liveVideoUUID })
8ebf2a5d
C
103 }
104 await waitJobs(servers)
105
106 for (const stateChanges of [ localStateChanges, remoteStateChanges ]) {
107 expect(stateChanges).to.have.length.at.least(2)
108 expect(stateChanges[stateChanges.length - 1]).to.equal(VideoState.LIVE_ENDED)
109 }
110 })
111
112 it('Should correctly send views change notification', async function () {
113 this.timeout(60000)
114
115 let localLastVideoViews = 0
116 let remoteLastVideoViews = 0
117
118 const liveVideoUUID = await createLiveWrapper()
119 await waitJobs(servers)
120
121 {
122 const videoId = await getVideoIdFromUUID(servers[0].url, liveVideoUUID)
123
87e2635a 124 const localSocket = servers[0].socketIOCommand.getLiveNotificationSocket()
8ebf2a5d
C
125 localSocket.on('views-change', data => { localLastVideoViews = data.views })
126 localSocket.emit('subscribe', { videoId })
127 }
128
129 {
130 const videoId = await getVideoIdFromUUID(servers[1].url, liveVideoUUID)
131
87e2635a 132 const remoteSocket = servers[1].socketIOCommand.getLiveNotificationSocket()
8ebf2a5d
C
133 remoteSocket.on('views-change', data => { remoteLastVideoViews = data.views })
134 remoteSocket.emit('subscribe', { videoId })
135 }
136
4f219914 137 const ffmpegCommand = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
8ebf2a5d
C
138
139 await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID)
140 await waitJobs(servers)
141
142 expect(localLastVideoViews).to.equal(0)
143 expect(remoteLastVideoViews).to.equal(0)
144
145 await viewVideo(servers[0].url, liveVideoUUID)
146 await viewVideo(servers[1].url, liveVideoUUID)
147
148 await waitJobs(servers)
149 await wait(5000)
150 await waitJobs(servers)
151
152 expect(localLastVideoViews).to.equal(2)
153 expect(remoteLastVideoViews).to.equal(2)
154
4f219914 155 await stopFfmpeg(ffmpegCommand)
8ebf2a5d
C
156 })
157
158 it('Should not receive a notification after unsubscribe', async function () {
159 this.timeout(120000)
160
161 const stateChanges: VideoState[] = []
162
163 const liveVideoUUID = await createLiveWrapper()
164 await waitJobs(servers)
165
166 const videoId = await getVideoIdFromUUID(servers[0].url, liveVideoUUID)
167
87e2635a 168 const socket = servers[0].socketIOCommand.getLiveNotificationSocket()
8ebf2a5d
C
169 socket.on('state-change', data => stateChanges.push(data.state))
170 socket.emit('subscribe', { videoId })
171
4f219914 172 const command = await servers[0].liveCommand.sendRTMPStreamInVideo({ videoId: liveVideoUUID })
8ebf2a5d
C
173
174 await waitUntilLivePublishedOnAllServers(servers, liveVideoUUID)
175 await waitJobs(servers)
176
177 // Notifier waits before sending a notification
178 await wait(10000)
179
180 expect(stateChanges).to.have.lengthOf(1)
181 socket.emit('unsubscribe', { videoId })
182
183 await stopFfmpeg(command)
184 await waitJobs(servers)
185
186 expect(stateChanges).to.have.lengthOf(1)
187 })
188 })
189
190 after(async function () {
191 await cleanupTests(servers)
192 })
193})