livechannel_test.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  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. 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) //默认值为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. // TestListLiveChannel
  216. func (s *OssBucketLiveChannelSuite) TestListLiveChannel(c *C) {
  217. result, err := s.bucket.ListLiveChannel()
  218. c.Assert(err, IsNil)
  219. ok := compareListResult(result, "", "", "", 100, false, 0)
  220. c.Assert(ok, Equals, true)
  221. prefix := "test-list-channel"
  222. for i := 0; i < 200; i++ {
  223. channelName := fmt.Sprintf("%s-%03d", prefix, i)
  224. config := LiveChannelConfiguration{
  225. Target: LiveChannelTarget{
  226. Type: "HLS",
  227. },
  228. }
  229. _, err := s.bucket.CreateLiveChannel(channelName, config)
  230. c.Assert(err, IsNil)
  231. }
  232. result, err = s.bucket.ListLiveChannel()
  233. c.Assert(err, IsNil)
  234. nextMarker := fmt.Sprintf("%s-099", prefix)
  235. ok = compareListResult(result, "", "", nextMarker, 100, true, 100)
  236. c.Assert(ok, Equals, true)
  237. randPrefix := randStr(5)
  238. result, err = s.bucket.ListLiveChannel(Prefix(randPrefix))
  239. c.Assert(err, IsNil)
  240. ok = compareListResult(result, randPrefix, "", "", 100, false, 0)
  241. c.Assert(ok, Equals, true)
  242. marker := fmt.Sprintf("%s-100", prefix)
  243. result, err = s.bucket.ListLiveChannel(Prefix(prefix), Marker(marker))
  244. c.Assert(err, IsNil)
  245. ok = compareListResult(result, prefix, marker, "", 100, false, 99)
  246. c.Assert(ok, Equals, true)
  247. maxKeys := 1000
  248. result, err = s.bucket.ListLiveChannel(MaxKeys(maxKeys))
  249. c.Assert(err, IsNil)
  250. ok = compareListResult(result, "", "", "", maxKeys, false, 200)
  251. invalidMaxKeys := -1
  252. result, err = s.bucket.ListLiveChannel(MaxKeys(invalidMaxKeys))
  253. c.Assert(err, NotNil)
  254. for i := 0; i < 200; i++ {
  255. channelName := fmt.Sprintf("%s-%03d", prefix, i)
  256. err := s.bucket.DeleteLiveChannel(channelName)
  257. c.Assert(err, IsNil)
  258. }
  259. }
  260. // TestPostVodPlaylist
  261. func (s *OssBucketLiveChannelSuite) TestSignRtmpURL(c *C) {
  262. channelName := "test-sign-rtmp-url"
  263. playlistName := "test-sign-rtmp-url.m3u8"
  264. config := LiveChannelConfiguration{
  265. Target: LiveChannelTarget{
  266. Type: "HLS",
  267. PlaylistName: playlistName,
  268. },
  269. }
  270. _, err := s.bucket.CreateLiveChannel(channelName, config)
  271. c.Assert(err, IsNil)
  272. expires := int64(3600)
  273. signedRtmpURL, err := s.bucket.SignRtmpURL(channelName, playlistName, expires)
  274. c.Assert(err, IsNil)
  275. playURL := getPublishURL(s.bucket.BucketName, channelName)
  276. hasPrefix := strings.HasPrefix(signedRtmpURL, playURL)
  277. c.Assert(hasPrefix, Equals, true)
  278. invalidExpires := int64(-1)
  279. signedRtmpURL, err = s.bucket.SignRtmpURL(channelName, playlistName, invalidExpires)
  280. c.Assert(err, NotNil)
  281. err = s.bucket.DeleteLiveChannel(channelName)
  282. c.Assert(err, IsNil)
  283. }
  284. // private
  285. // getPlayURL - 获取直播流频道的播放地址
  286. func getPlayURL(bucketName, channelName, playlistName string) string {
  287. host := ""
  288. useHTTPS := false
  289. if strings.Contains(endpoint, "https://") {
  290. host = endpoint[8:]
  291. useHTTPS = true
  292. } else if strings.Contains(endpoint, "http://") {
  293. host = endpoint[7:]
  294. } else {
  295. host = endpoint
  296. }
  297. if useHTTPS {
  298. return fmt.Sprintf("https://%s.%s/%s/%s", bucketName, host, channelName, playlistName)
  299. }
  300. return fmt.Sprintf("http://%s.%s/%s/%s", bucketName, host, channelName, playlistName)
  301. }
  302. // getPublistURL - 获取直播流频道的推流地址
  303. func getPublishURL(bucketName, channelName string) string {
  304. host := ""
  305. if strings.Contains(endpoint, "https://") {
  306. host = endpoint[8:]
  307. } else if strings.Contains(endpoint, "http://") {
  308. host = endpoint[7:]
  309. } else {
  310. host = endpoint
  311. }
  312. return fmt.Sprintf("rtmp://%s.%s/live/%s", bucketName, host, channelName)
  313. }
  314. func compareListResult(result ListLiveChannelResult, prefix, marker, nextMarker string, maxKey int, isTruncated bool, count int) bool {
  315. if result.Prefix != prefix || result.Marker != marker || result.NextMarker != nextMarker || result.MaxKeys != maxKey || result.IsTruncated != isTruncated || len(result.LiveChannel) != count {
  316. return false
  317. }
  318. return true
  319. }