livechannel_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. package oss
  2. import (
  3. "fmt"
  4. "strings"
  5. "time"
  6. . "gopkg.in/check.v1"
  7. )
  8. type OssBucketLiveChannelSuite struct {
  9. client *Client
  10. bucket *Bucket
  11. }
  12. var _ = Suite(&OssBucketLiveChannelSuite{})
  13. // SetUpSuite Run once when the suite starts running
  14. func (s *OssBucketLiveChannelSuite) SetUpSuite(c *C) {
  15. client, err := New(endpoint, accessID, accessKey)
  16. c.Assert(err, IsNil)
  17. s.client = client
  18. err = s.client.CreateBucket(bucketName)
  19. c.Assert(err, IsNil)
  20. time.Sleep(5 * time.Second)
  21. bucket, err := s.client.Bucket(bucketName)
  22. c.Assert(err, IsNil)
  23. s.bucket = bucket
  24. testLogger.Println("test livechannel started...")
  25. }
  26. // TearDownSuite Run once after all tests or benchmarks
  27. func (s *OssBucketLiveChannelSuite) TearDownSuite(c *C) {
  28. marker := ""
  29. for {
  30. result, err := s.bucket.ListLiveChannel(Marker(marker))
  31. c.Assert(err, IsNil)
  32. for _, channel := range result.LiveChannel {
  33. err := s.bucket.DeleteLiveChannel(channel.Name)
  34. c.Assert(err, IsNil)
  35. }
  36. if result.IsTruncated {
  37. marker = result.NextMarker
  38. } else {
  39. break
  40. }
  41. }
  42. testLogger.Println("test livechannel done...")
  43. }
  44. // SetUpTest Run before each test or benchmark starts
  45. func (s *OssBucketLiveChannelSuite) SetUpTest(c *C) {
  46. }
  47. // TearDownTest Run after each test or benchmark runs.
  48. func (s *OssBucketLiveChannelSuite) TearDownTest(c *C) {
  49. }
  50. // TestCreateLiveChannel
  51. func (s *OssBucketLiveChannelSuite) TestCreateLiveChannel(c *C) {
  52. channelName := "test-create-channel"
  53. playlistName := "test-create-channel.m3u8"
  54. target := LiveChannelTarget{
  55. PlaylistName: playlistName,
  56. Type: "HLS",
  57. }
  58. config := LiveChannelConfiguration{
  59. Description: "livechannel for test",
  60. Status: "enabled",
  61. Target: target,
  62. }
  63. result, err := s.bucket.CreateLiveChannel(channelName, config)
  64. c.Assert(err, IsNil)
  65. playURL := getPlayURL(bucketName, channelName, playlistName)
  66. publishURL := getPublishURL(bucketName, channelName)
  67. c.Assert(result.PlayUrls[0], Equals, playURL)
  68. c.Assert(result.PublishUrls[0], Equals, publishURL)
  69. err = s.bucket.DeleteLiveChannel(channelName)
  70. c.Assert(err, IsNil)
  71. invalidType := RandStr(4)
  72. invalidTarget := LiveChannelTarget{
  73. PlaylistName: playlistName,
  74. Type: invalidType,
  75. }
  76. invalidConfig := LiveChannelConfiguration{
  77. Description: "livechannel for test",
  78. Status: "enabled",
  79. Target: invalidTarget,
  80. }
  81. _, err = s.bucket.CreateLiveChannel(channelName, invalidConfig)
  82. c.Assert(err, NotNil)
  83. }
  84. // TestDeleteLiveChannel
  85. func (s *OssBucketLiveChannelSuite) TestDeleteLiveChannel(c *C) {
  86. channelName := "test-delete-channel"
  87. target := LiveChannelTarget{
  88. Type: "HLS",
  89. }
  90. config := LiveChannelConfiguration{
  91. Target: target,
  92. }
  93. _, err := s.bucket.CreateLiveChannel(channelName, config)
  94. c.Assert(err, IsNil)
  95. err = s.bucket.DeleteLiveChannel(channelName)
  96. c.Assert(err, IsNil)
  97. emptyChannelName := ""
  98. err = s.bucket.DeleteLiveChannel(emptyChannelName)
  99. c.Assert(err, NotNil)
  100. longChannelName := RandStr(65)
  101. err = s.bucket.DeleteLiveChannel(longChannelName)
  102. c.Assert(err, NotNil)
  103. config, err = s.bucket.GetLiveChannelInfo(channelName)
  104. c.Assert(err, NotNil)
  105. }
  106. // TestGetLiveChannelInfo
  107. func (s *OssBucketLiveChannelSuite) TestGetLiveChannelInfo(c *C) {
  108. channelName := "test-get-channel-status"
  109. _, err := s.bucket.GetLiveChannelInfo(channelName)
  110. c.Assert(err, NotNil)
  111. createCfg := LiveChannelConfiguration{
  112. Target: LiveChannelTarget{
  113. Type: "HLS",
  114. FragDuration: 10,
  115. FragCount: 4,
  116. PlaylistName: "test-get-channel-status.m3u8",
  117. },
  118. }
  119. _, err = s.bucket.CreateLiveChannel(channelName, createCfg)
  120. c.Assert(err, IsNil)
  121. getCfg, err := s.bucket.GetLiveChannelInfo(channelName)
  122. c.Assert(err, IsNil)
  123. c.Assert("enabled", Equals, getCfg.Status) //The default value is enabled
  124. c.Assert("HLS", Equals, getCfg.Target.Type)
  125. c.Assert(10, Equals, getCfg.Target.FragDuration)
  126. c.Assert(4, Equals, getCfg.Target.FragCount)
  127. c.Assert("test-get-channel-status.m3u8", Equals, getCfg.Target.PlaylistName)
  128. err = s.bucket.DeleteLiveChannel(channelName)
  129. c.Assert(err, IsNil)
  130. }
  131. // TestPutLiveChannelStatus
  132. func (s *OssBucketLiveChannelSuite) TestPutLiveChannelStatus(c *C) {
  133. channelName := "test-put-channel-status"
  134. config := LiveChannelConfiguration{
  135. Status: "disabled",
  136. Target: LiveChannelTarget{
  137. Type: "HLS",
  138. },
  139. }
  140. _, err := s.bucket.CreateLiveChannel(channelName, config)
  141. c.Assert(err, IsNil)
  142. getCfg, err := s.bucket.GetLiveChannelInfo(channelName)
  143. c.Assert(err, IsNil)
  144. c.Assert("disabled", Equals, getCfg.Status)
  145. err = s.bucket.PutLiveChannelStatus(channelName, "enabled")
  146. c.Assert(err, IsNil)
  147. getCfg, err = s.bucket.GetLiveChannelInfo(channelName)
  148. c.Assert(err, IsNil)
  149. c.Assert("enabled", Equals, getCfg.Status)
  150. err = s.bucket.PutLiveChannelStatus(channelName, "disabled")
  151. c.Assert(err, IsNil)
  152. getCfg, err = s.bucket.GetLiveChannelInfo(channelName)
  153. c.Assert(err, IsNil)
  154. c.Assert("disabled", Equals, getCfg.Status)
  155. invalidStatus := RandLowStr(9)
  156. err = s.bucket.PutLiveChannelStatus(channelName, invalidStatus)
  157. c.Assert(err, NotNil)
  158. err = s.bucket.DeleteLiveChannel(channelName)
  159. c.Assert(err, IsNil)
  160. }
  161. // TestGetLiveChannelHistory
  162. func (s *OssBucketLiveChannelSuite) TestGetLiveChannelHistory(c *C) {
  163. channelName := "test-get-channel-history"
  164. _, err := s.bucket.GetLiveChannelHistory(channelName)
  165. c.Assert(err, NotNil)
  166. config := LiveChannelConfiguration{
  167. Target: LiveChannelTarget{
  168. Type: "HLS",
  169. },
  170. }
  171. _, err = s.bucket.CreateLiveChannel(channelName, config)
  172. c.Assert(err, IsNil)
  173. history, err := s.bucket.GetLiveChannelHistory(channelName)
  174. c.Assert(err, IsNil)
  175. c.Assert(len(history.Record), Equals, 0)
  176. err = s.bucket.DeleteLiveChannel(channelName)
  177. c.Assert(err, IsNil)
  178. }
  179. // TestGetLiveChannelStat
  180. func (s *OssBucketLiveChannelSuite) TestGetLiveChannelStat(c *C) {
  181. channelName := "test-get-channel-stat"
  182. _, err := s.bucket.GetLiveChannelStat(channelName)
  183. c.Assert(err, NotNil)
  184. config := LiveChannelConfiguration{
  185. Target: LiveChannelTarget{
  186. Type: "HLS",
  187. },
  188. }
  189. _, err = s.bucket.CreateLiveChannel(channelName, config)
  190. c.Assert(err, IsNil)
  191. stat, err := s.bucket.GetLiveChannelStat(channelName)
  192. c.Assert(err, IsNil)
  193. c.Assert(stat.Status, Equals, "Idle")
  194. err = s.bucket.DeleteLiveChannel(channelName)
  195. c.Assert(err, IsNil)
  196. }
  197. // TestPostVodPlaylist
  198. func (s *OssBucketLiveChannelSuite) TestPostVodPlaylist(c *C) {
  199. channelName := "test-post-vod-playlist"
  200. playlistName := "test-post-vod-playlist.m3u8"
  201. config := LiveChannelConfiguration{
  202. Target: LiveChannelTarget{
  203. Type: "HLS",
  204. },
  205. }
  206. _, err := s.bucket.CreateLiveChannel(channelName, config)
  207. c.Assert(err, IsNil)
  208. endTime := time.Now().Add(-1 * time.Minute)
  209. startTime := endTime.Add(-60 * time.Minute)
  210. err = s.bucket.PostVodPlaylist(channelName, playlistName, startTime, endTime)
  211. c.Assert(err, NotNil)
  212. err = s.bucket.DeleteLiveChannel(channelName)
  213. c.Assert(err, IsNil)
  214. }
  215. // TestPostVodPlaylist
  216. func (s *OssBucketLiveChannelSuite) TestGetVodPlaylist(c *C) {
  217. channelName := "test-get-vod-playlist"
  218. config := LiveChannelConfiguration{
  219. Target: LiveChannelTarget{
  220. Type: "HLS",
  221. },
  222. }
  223. _, err := s.bucket.CreateLiveChannel(channelName, config)
  224. c.Assert(err, IsNil)
  225. endTime := time.Now().Add(-1 * time.Minute)
  226. startTime := endTime.Add(-60 * time.Minute)
  227. _, err = s.bucket.GetVodPlaylist(channelName, startTime, endTime)
  228. c.Assert(err, NotNil)
  229. err = s.bucket.DeleteLiveChannel(channelName)
  230. c.Assert(err, IsNil)
  231. }
  232. // TestListLiveChannel
  233. func (s *OssBucketLiveChannelSuite) TestListLiveChannel(c *C) {
  234. result, err := s.bucket.ListLiveChannel()
  235. c.Assert(err, IsNil)
  236. ok := compareListResult(result, "", "", "", 100, false, 0)
  237. c.Assert(ok, Equals, true)
  238. prefix := "test-list-channel"
  239. for i := 0; i < 200; i++ {
  240. channelName := fmt.Sprintf("%s-%03d", prefix, i)
  241. config := LiveChannelConfiguration{
  242. Target: LiveChannelTarget{
  243. Type: "HLS",
  244. },
  245. }
  246. _, err := s.bucket.CreateLiveChannel(channelName, config)
  247. c.Assert(err, IsNil)
  248. }
  249. result, err = s.bucket.ListLiveChannel()
  250. c.Assert(err, IsNil)
  251. nextMarker := fmt.Sprintf("%s-099", prefix)
  252. ok = compareListResult(result, "", "", nextMarker, 100, true, 100)
  253. c.Assert(ok, Equals, true)
  254. randPrefix := RandStr(5)
  255. result, err = s.bucket.ListLiveChannel(Prefix(randPrefix))
  256. c.Assert(err, IsNil)
  257. ok = compareListResult(result, randPrefix, "", "", 100, false, 0)
  258. c.Assert(ok, Equals, true)
  259. marker := fmt.Sprintf("%s-100", prefix)
  260. result, err = s.bucket.ListLiveChannel(Prefix(prefix), Marker(marker))
  261. c.Assert(err, IsNil)
  262. ok = compareListResult(result, prefix, marker, "", 100, false, 99)
  263. c.Assert(ok, Equals, true)
  264. maxKeys := 1000
  265. result, err = s.bucket.ListLiveChannel(MaxKeys(maxKeys))
  266. c.Assert(err, IsNil)
  267. ok = compareListResult(result, "", "", "", maxKeys, false, 200)
  268. invalidMaxKeys := -1
  269. result, err = s.bucket.ListLiveChannel(MaxKeys(invalidMaxKeys))
  270. c.Assert(err, NotNil)
  271. for i := 0; i < 200; i++ {
  272. channelName := fmt.Sprintf("%s-%03d", prefix, i)
  273. err := s.bucket.DeleteLiveChannel(channelName)
  274. c.Assert(err, IsNil)
  275. }
  276. }
  277. // TestSignRtmpURL
  278. func (s *OssBucketLiveChannelSuite) TestSignRtmpURL(c *C) {
  279. channelName := "test-sign-rtmp-url"
  280. playlistName := "test-sign-rtmp-url.m3u8"
  281. config := LiveChannelConfiguration{
  282. Target: LiveChannelTarget{
  283. Type: "HLS",
  284. PlaylistName: playlistName,
  285. },
  286. }
  287. _, err := s.bucket.CreateLiveChannel(channelName, config)
  288. c.Assert(err, IsNil)
  289. expires := int64(3600)
  290. signedRtmpURL, err := s.bucket.SignRtmpURL(channelName, playlistName, expires)
  291. c.Assert(err, IsNil)
  292. playURL := getPublishURL(s.bucket.BucketName, channelName)
  293. hasPrefix := strings.HasPrefix(signedRtmpURL, playURL)
  294. c.Assert(hasPrefix, Equals, true)
  295. invalidExpires := int64(-1)
  296. signedRtmpURL, err = s.bucket.SignRtmpURL(channelName, playlistName, invalidExpires)
  297. c.Assert(err, NotNil)
  298. err = s.bucket.DeleteLiveChannel(channelName)
  299. c.Assert(err, IsNil)
  300. }
  301. // private
  302. // getPlayURL Get the play url of the live channel
  303. func getPlayURL(bucketName, channelName, playlistName string) string {
  304. host := ""
  305. useHTTPS := false
  306. if strings.Contains(endpoint, "https://") {
  307. host = endpoint[8:]
  308. useHTTPS = true
  309. } else if strings.Contains(endpoint, "http://") {
  310. host = endpoint[7:]
  311. } else {
  312. host = endpoint
  313. }
  314. if useHTTPS {
  315. return fmt.Sprintf("https://%s.%s/%s/%s", bucketName, host, channelName, playlistName)
  316. }
  317. return fmt.Sprintf("http://%s.%s/%s/%s", bucketName, host, channelName, playlistName)
  318. }
  319. // getPublistURL Get the push url of the live stream channel
  320. func getPublishURL(bucketName, channelName string) string {
  321. host := ""
  322. if strings.Contains(endpoint, "https://") {
  323. host = endpoint[8:]
  324. } else if strings.Contains(endpoint, "http://") {
  325. host = endpoint[7:]
  326. } else {
  327. host = endpoint
  328. }
  329. return fmt.Sprintf("rtmp://%s.%s/live/%s", bucketName, host, channelName)
  330. }
  331. func compareListResult(result ListLiveChannelResult, prefix, marker, nextMarker string, maxKey int, isTruncated bool, count int) bool {
  332. if result.Prefix != prefix || result.Marker != marker || result.NextMarker != nextMarker || result.MaxKeys != maxKey || result.IsTruncated != isTruncated || len(result.LiveChannel) != count {
  333. return false
  334. }
  335. return true
  336. }