livechannel_test.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  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. // 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. // Run once after all tests or benckmarks have finished running
  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. // Run after each test or benchmark runs
  45. func (s *OssBucketLiveChannelSuite) SetUpTest(c *C) {
  46. }
  47. // Run once after all tests or benchmarks have finished running
  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. config, err = s.bucket.GetLiveChannelInfo(channelName)
  98. c.Assert(err, NotNil)
  99. }
  100. // TestGetLiveChannelInfo
  101. func (s *OssBucketLiveChannelSuite) TestGetLiveChannelInfo(c *C) {
  102. channelName := "test-get-channel-status"
  103. _, err := s.bucket.GetLiveChannelInfo(channelName)
  104. c.Assert(err, NotNil)
  105. createCfg := LiveChannelConfiguration{
  106. Target: LiveChannelTarget{
  107. Type: "HLS",
  108. FragDuration: 10,
  109. FragCount: 4,
  110. PlaylistName: "test-get-channel-status.m3u8",
  111. },
  112. }
  113. _, err = s.bucket.CreateLiveChannel(channelName, createCfg)
  114. c.Assert(err, IsNil)
  115. getCfg, err := s.bucket.GetLiveChannelInfo(channelName)
  116. c.Assert(err, IsNil)
  117. c.Assert("enabled", Equals, getCfg.Status) //默认值为enabled
  118. c.Assert("HLS", Equals, getCfg.Target.Type)
  119. c.Assert(10, Equals, getCfg.Target.FragDuration)
  120. c.Assert(4, Equals, getCfg.Target.FragCount)
  121. c.Assert("test-get-channel-status.m3u8", Equals, getCfg.Target.PlaylistName)
  122. err = s.bucket.DeleteLiveChannel(channelName)
  123. c.Assert(err, IsNil)
  124. }
  125. // TestPutLiveChannelStatus
  126. func (s *OssBucketLiveChannelSuite) TestPutLiveChannelStatus(c *C) {
  127. channelName := "test-put-channel-status"
  128. config := LiveChannelConfiguration{
  129. Status: "disabled",
  130. Target: LiveChannelTarget{
  131. Type: "HLS",
  132. },
  133. }
  134. _, err := s.bucket.CreateLiveChannel(channelName, config)
  135. c.Assert(err, IsNil)
  136. getCfg, err := s.bucket.GetLiveChannelInfo(channelName)
  137. c.Assert(err, IsNil)
  138. c.Assert("disabled", Equals, getCfg.Status)
  139. err = s.bucket.PutLiveChannelStatus(channelName, "enabled")
  140. c.Assert(err, IsNil)
  141. getCfg, err = s.bucket.GetLiveChannelInfo(channelName)
  142. c.Assert(err, IsNil)
  143. c.Assert("enabled", Equals, getCfg.Status)
  144. err = s.bucket.PutLiveChannelStatus(channelName, "disabled")
  145. c.Assert(err, IsNil)
  146. getCfg, err = s.bucket.GetLiveChannelInfo(channelName)
  147. c.Assert(err, IsNil)
  148. c.Assert("disabled", Equals, getCfg.Status)
  149. invalidStatus := randLowStr(9)
  150. err = s.bucket.PutLiveChannelStatus(channelName, invalidStatus)
  151. c.Assert(err, NotNil)
  152. err = s.bucket.DeleteLiveChannel(channelName)
  153. c.Assert(err, IsNil)
  154. }
  155. // TestGetLiveChannelHistory()
  156. func (s *OssBucketLiveChannelSuite) TestGetLiveChannelHistory(c *C) {
  157. channelName := "test-get-channel-history"
  158. _, err := s.bucket.GetLiveChannelHistory(channelName)
  159. c.Assert(err, NotNil)
  160. config := LiveChannelConfiguration{
  161. Target: LiveChannelTarget{
  162. Type: "HLS",
  163. },
  164. }
  165. _, err = s.bucket.CreateLiveChannel(channelName, config)
  166. c.Assert(err, IsNil)
  167. history, err := s.bucket.GetLiveChannelHistory(channelName)
  168. c.Assert(err, IsNil)
  169. c.Assert(len(history.Record), Equals, 0)
  170. err = s.bucket.DeleteLiveChannel(channelName)
  171. c.Assert(err, IsNil)
  172. }
  173. // TestGetLiveChannelStat
  174. func (s *OssBucketLiveChannelSuite) TestGetLiveChannelStat(c *C) {
  175. channelName := "test-get-channel-stat"
  176. _, err := s.bucket.GetLiveChannelStat(channelName)
  177. c.Assert(err, NotNil)
  178. config := LiveChannelConfiguration{
  179. Target: LiveChannelTarget{
  180. Type: "HLS",
  181. },
  182. }
  183. _, err = s.bucket.CreateLiveChannel(channelName, config)
  184. c.Assert(err, IsNil)
  185. stat, err := s.bucket.GetLiveChannelStat(channelName)
  186. c.Assert(err, IsNil)
  187. c.Assert(stat.Status, Equals, "Idle")
  188. err = s.bucket.DeleteLiveChannel(channelName)
  189. c.Assert(err, IsNil)
  190. }
  191. // TestPostVodPlaylist
  192. func (s *OssBucketLiveChannelSuite) TestPostVodPlaylist(c *C) {
  193. channelName := "test-post-vod-playlist"
  194. playlistName := "test-post-vod-playlist.m3u8"
  195. config := LiveChannelConfiguration{
  196. Target: LiveChannelTarget{
  197. Type: "HLS",
  198. },
  199. }
  200. _, err := s.bucket.CreateLiveChannel(channelName, config)
  201. c.Assert(err, IsNil)
  202. endTime := time.Now().Add(-1 * time.Minute)
  203. startTime := endTime.Add(-60 * time.Minute)
  204. err = s.bucket.PostVodPlaylist(channelName, playlistName, startTime, endTime)
  205. c.Assert(err, NotNil)
  206. err = s.bucket.DeleteLiveChannel(channelName)
  207. c.Assert(err, IsNil)
  208. }
  209. // TestListLiveChannel
  210. func (s *OssBucketLiveChannelSuite) TestListLiveChannel(c *C) {
  211. result, err := s.bucket.ListLiveChannel()
  212. c.Assert(err, IsNil)
  213. ok := compareListResult(result, "", "", "", 100, false, 0)
  214. c.Assert(ok, Equals, true)
  215. prefix := "test-list-channel"
  216. for i := 0; i < 200; i++ {
  217. channelName := fmt.Sprintf("%s-%03d", prefix, i)
  218. config := LiveChannelConfiguration{
  219. Target: LiveChannelTarget{
  220. Type: "HLS",
  221. },
  222. }
  223. _, err := s.bucket.CreateLiveChannel(channelName, config)
  224. c.Assert(err, IsNil)
  225. }
  226. result, err = s.bucket.ListLiveChannel()
  227. c.Assert(err, IsNil)
  228. nextMarker := fmt.Sprintf("%s-099", prefix)
  229. ok = compareListResult(result, "", "", nextMarker, 100, true, 100)
  230. c.Assert(ok, Equals, true)
  231. randPrefix := randStr(5)
  232. result, err = s.bucket.ListLiveChannel(Prefix(randPrefix))
  233. c.Assert(err, IsNil)
  234. ok = compareListResult(result, randPrefix, "", "", 100, false, 0)
  235. c.Assert(ok, Equals, true)
  236. marker := fmt.Sprintf("%s-100", prefix)
  237. result, err = s.bucket.ListLiveChannel(Prefix(prefix), Marker(marker))
  238. c.Assert(err, IsNil)
  239. ok = compareListResult(result, prefix, marker, "", 100, false, 99)
  240. c.Assert(ok, Equals, true)
  241. maxKeys := 1000
  242. result, err = s.bucket.ListLiveChannel(MaxKeys(maxKeys))
  243. c.Assert(err, IsNil)
  244. ok = compareListResult(result, "", "", "", maxKeys, false, 200)
  245. for i := 0; i < 200; i++ {
  246. channelName := fmt.Sprintf("%s-%03d", prefix, i)
  247. err := s.bucket.DeleteLiveChannel(channelName)
  248. c.Assert(err, IsNil)
  249. }
  250. }
  251. // TestPostVodPlaylist
  252. func (s *OssBucketLiveChannelSuite) TestSignRtmpURL(c *C) {
  253. channelName := "test-sign-rtmp-url"
  254. playlistName := "test-sign-rtmp-url.m3u8"
  255. config := LiveChannelConfiguration{
  256. Target: LiveChannelTarget{
  257. Type: "HLS",
  258. PlaylistName: playlistName,
  259. },
  260. }
  261. _, err := s.bucket.CreateLiveChannel(channelName, config)
  262. c.Assert(err, IsNil)
  263. expires := int64(3600)
  264. signedRtmpURL, err := s.bucket.SignRtmpURL(channelName, playlistName, expires)
  265. c.Assert(err, IsNil)
  266. playURL := getPublishURL(s.bucket.BucketName, channelName)
  267. hasPrefix := strings.HasPrefix(signedRtmpURL, playURL)
  268. c.Assert(hasPrefix, Equals, true)
  269. invalidExpires := int64(-1)
  270. signedRtmpURL, err = s.bucket.SignRtmpURL(channelName, playlistName, invalidExpires)
  271. c.Assert(err, NotNil)
  272. err = s.bucket.DeleteLiveChannel(channelName)
  273. c.Assert(err, IsNil)
  274. }
  275. // private
  276. // getPlayURL - 获取直播流频道的播放地址
  277. func getPlayURL(bucketName, channelName, playlistName string) string {
  278. host := ""
  279. useHTTPS := false
  280. if strings.Contains(endpoint, "https://") {
  281. host = endpoint[8:]
  282. useHTTPS = true
  283. } else if strings.Contains(endpoint, "http://") {
  284. host = endpoint[7:]
  285. } else {
  286. host = endpoint
  287. }
  288. if useHTTPS {
  289. return fmt.Sprintf("https://%s.%s/%s/%s", bucketName, host, channelName, playlistName)
  290. }
  291. return fmt.Sprintf("http://%s.%s/%s/%s", bucketName, host, channelName, playlistName)
  292. }
  293. // getPublistURL - 获取直播流频道的推流地址
  294. func getPublishURL(bucketName, channelName string) string {
  295. host := ""
  296. if strings.Contains(endpoint, "https://") {
  297. host = endpoint[8:]
  298. } else if strings.Contains(endpoint, "http://") {
  299. host = endpoint[7:]
  300. } else {
  301. host = endpoint
  302. }
  303. return fmt.Sprintf("rtmp://%s.%s/live/%s", bucketName, host, channelName)
  304. }
  305. func compareListResult(result ListLiveChannelResult, prefix, marker, nextMarker string, maxKey int, isTruncated bool, count int) bool {
  306. if result.Prefix != prefix || result.Marker != marker || result.NextMarker != nextMarker || result.MaxKeys != maxKey || result.IsTruncated != isTruncated || len(result.LiveChannel) != count {
  307. return false
  308. }
  309. return true
  310. }