fileplaylist_test.go 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. /*
  2. * DudelDu
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the MIT
  7. * License, If a copy of the MIT License was not distributed with this
  8. * file, You can obtain one at https://opensource.org/licenses/MIT.
  9. */
  10. package playlist
  11. import (
  12. "flag"
  13. "fmt"
  14. "io/ioutil"
  15. "os"
  16. "sync"
  17. "testing"
  18. "devt.de/krotik/common/fileutil"
  19. "devt.de/krotik/dudeldu"
  20. )
  21. const pdir = "playlisttest"
  22. const testPlaylist = `
  23. /*
  24. Test comment
  25. */
  26. {
  27. "/testpath" : [
  28. {
  29. "artist" : "artist1", // 1234
  30. "title" : "test1",
  31. "path" : "playlisttest/test1.mp3"
  32. },
  33. {
  34. "artist" : "artist2",
  35. "title" : "test2",
  36. "path" : "playlisttest/test2.nsv"
  37. },
  38. {
  39. "artist" : "artist3",
  40. "title" : "test3",
  41. "path" : "playlisttest/test3.xyz"
  42. }
  43. ]
  44. }`
  45. const testPlaylist2 = `{
  46. "/testpath" : [
  47. {
  48. "artist" : "artist1",
  49. "title" : "test1",
  50. "path" : "playlisttest/test1.mp3"
  51. },
  52. {
  53. "artist" : "artist2",
  54. "title" : "test2",
  55. "path" : "playlisttest/test2.nsv"
  56. },
  57. {
  58. "artist" : "artist2",
  59. "title" : "test2",
  60. "path" : "playlisttest/nonexist"
  61. },
  62. {
  63. "artist" : "artist3",
  64. "title" : "test3",
  65. "path" : "playlisttest/test3.xyz"
  66. }
  67. ]
  68. }`
  69. const invalidFileName = "**" + string(0x0)
  70. func TestMain(m *testing.M) {
  71. flag.Parse()
  72. // Setup
  73. if res, _ := fileutil.PathExists(pdir); res {
  74. os.RemoveAll(pdir)
  75. }
  76. err := os.Mkdir(pdir, 0770)
  77. if err != nil {
  78. fmt.Print("Could not create test directory:", err.Error())
  79. os.Exit(1)
  80. }
  81. // Run the tests
  82. res := m.Run()
  83. // Teardown
  84. err = os.RemoveAll(pdir)
  85. if err != nil {
  86. fmt.Print("Could not remove test directory:", err.Error())
  87. }
  88. os.Exit(res)
  89. }
  90. func TestFilePlaylist(t *testing.T) {
  91. // Set up
  92. err := ioutil.WriteFile(pdir+"/test1.json", []byte(testPlaylist), 0644)
  93. if err != nil {
  94. t.Error(err)
  95. return
  96. }
  97. err = ioutil.WriteFile(pdir+"/test2.json", []byte(testPlaylist2), 0644)
  98. if err != nil {
  99. t.Error(err)
  100. return
  101. }
  102. err = ioutil.WriteFile(pdir+"/test1invalid.json", []byte(testPlaylist[2:]), 0644)
  103. if err != nil {
  104. t.Error(err)
  105. return
  106. }
  107. err = ioutil.WriteFile(pdir+"/test1.mp3", []byte("123"), 0644)
  108. if err != nil {
  109. t.Error(err)
  110. return
  111. }
  112. err = ioutil.WriteFile(pdir+"/test2.nsv", []byte("456789"), 0644)
  113. if err != nil {
  114. t.Error(err)
  115. return
  116. }
  117. err = ioutil.WriteFile(pdir+"/test3.xyz", []byte("AB"), 0644)
  118. if err != nil {
  119. t.Error(err)
  120. return
  121. }
  122. // Load invalid factory
  123. _, err = NewFilePlaylistFactory(invalidFileName)
  124. if err == nil {
  125. t.Error(err)
  126. return
  127. }
  128. _, err = NewFilePlaylistFactory(pdir + "/test1invalid.json")
  129. if err.Error() != "invalid character '*' looking for beginning of value" {
  130. t.Error(err)
  131. return
  132. }
  133. // Create playlist factory
  134. plf, err := NewFilePlaylistFactory(pdir + "/test1.json")
  135. if err != nil {
  136. t.Error(err)
  137. return
  138. }
  139. // Request non-existing path
  140. res := plf.Playlist("/nonexist", false)
  141. if res != nil {
  142. t.Error("Non existing path should return nil")
  143. return
  144. }
  145. // Get existing playlist
  146. pl := plf.Playlist("/testpath", false)
  147. defer pl.Close()
  148. if pl == nil {
  149. t.Error("Playlist should exist")
  150. return
  151. }
  152. if pl.Name() != "/testpath" {
  153. t.Error("Unexpected playlist name:", pl.Name())
  154. return
  155. }
  156. FrameSize = 2
  157. if pl.ContentType() != "audio/mpeg" {
  158. t.Error("Unexpected content type:", pl.ContentType())
  159. return
  160. }
  161. if pl.Artist() != "artist1" {
  162. t.Error("Unexpected artist:", pl.ContentType())
  163. return
  164. }
  165. if pl.Title() != "test1" {
  166. t.Error("Unexpected title:", pl.ContentType())
  167. return
  168. }
  169. // Test close call
  170. frame, err := pl.Frame()
  171. if err != nil {
  172. t.Error(err)
  173. return
  174. } else if string(frame) != "12" {
  175. t.Error("Unexpected frame:", string(frame))
  176. return
  177. }
  178. pl.Close()
  179. // Make the frame pool run dry if more than one byte array is used
  180. pl.(*FilePlaylist).framePool = &sync.Pool{}
  181. pl.(*FilePlaylist).framePool.Put(make([]byte, 2, 2))
  182. // Check that the right frames are returned
  183. frame, err = pl.Frame()
  184. if err != nil {
  185. t.Error(err)
  186. return
  187. } else if string(frame) != "12" {
  188. t.Error("Unexpected frame:", string(frame))
  189. return
  190. }
  191. pl.ReleaseFrame(frame)
  192. if pl.Title() != "test1" || pl.Artist() != "artist1" {
  193. t.Error("Unexpected title/artist:", pl.Title(), pl.Artist())
  194. return
  195. }
  196. frame, err = pl.Frame()
  197. if err != nil {
  198. t.Error(err)
  199. return
  200. } else if string(frame) != "34" {
  201. t.Error("Unexpected frame:", string(frame))
  202. return
  203. }
  204. pl.ReleaseFrame(frame)
  205. if pl.Title() != "test2" || pl.Artist() != "artist2" {
  206. t.Error("Unexpected title/artist:", pl.Title(), pl.Artist())
  207. return
  208. }
  209. frame, err = pl.Frame()
  210. if err != nil {
  211. t.Error(err)
  212. return
  213. } else if string(frame) != "56" {
  214. t.Error("Unexpected frame:", string(frame))
  215. return
  216. }
  217. pl.ReleaseFrame(frame)
  218. if pl.Title() != "test2" || pl.Artist() != "artist2" {
  219. t.Error("Unexpected title/artist:", pl.Title(), pl.Artist())
  220. return
  221. }
  222. frame, err = pl.Frame()
  223. if err != nil {
  224. t.Error(err)
  225. return
  226. } else if string(frame) != "78" {
  227. t.Error("Unexpected frame:", string(frame))
  228. return
  229. }
  230. pl.ReleaseFrame(frame)
  231. frame, err = pl.Frame()
  232. if err != nil {
  233. t.Error(err)
  234. return
  235. } else if string(frame) != "9A" {
  236. t.Error("Unexpected frame:", string(frame))
  237. return
  238. }
  239. pl.ReleaseFrame(frame)
  240. if pl.Title() != "test3" || pl.Artist() != "artist3" {
  241. t.Error("Unexpected title/artist:", pl.Title(), pl.Artist())
  242. return
  243. }
  244. // Check frame pool
  245. if pl.(*FilePlaylist).framePool.Get() == nil {
  246. t.Error("Frame pool should have an entry")
  247. return
  248. }
  249. if pl.(*FilePlaylist).framePool.Get() != nil {
  250. t.Error("Frame pool should have no entry")
  251. return
  252. }
  253. // Put again one byte array back
  254. pl.(*FilePlaylist).framePool.Put(make([]byte, 2, 2))
  255. frame, err = pl.Frame()
  256. if err != dudeldu.ErrPlaylistEnd {
  257. t.Error(err)
  258. return
  259. } else if string(frame) != "B" {
  260. t.Error("Unexpected frame:", string(frame), frame)
  261. return
  262. }
  263. pl.ReleaseFrame(frame)
  264. // Check that the byte array was NOT put back into the pool
  265. if pl.(*FilePlaylist).framePool.Get() != nil {
  266. t.Error("Frame pool should have no entry")
  267. return
  268. }
  269. if !pl.Finished() {
  270. t.Error("Playlist should be finished")
  271. return
  272. }
  273. // Change the last file
  274. err = ioutil.WriteFile(pdir+"/test3.xyz", []byte("A"), 0644)
  275. if err != nil {
  276. t.Error(err)
  277. return
  278. }
  279. // Make the frame pool normal again
  280. pl.(*FilePlaylist).framePool = &sync.Pool{New: func() interface{} { return make([]byte, FrameSize, FrameSize) }}
  281. // Increase the framesize
  282. FrameSize = 5
  283. pl.Close()
  284. frame, err = pl.Frame()
  285. if err != nil {
  286. t.Error(err)
  287. return
  288. } else if string(frame) != "12345" {
  289. t.Error("Unexpected frame:", string(frame), frame)
  290. return
  291. }
  292. // Check that the content type is unknown
  293. if pl.ContentType() != "video/nsv" {
  294. t.Error("Content type should be nsv not:", pl.ContentType())
  295. return
  296. }
  297. frame, err = pl.Frame()
  298. if err != nil {
  299. t.Error(err)
  300. return
  301. } else if string(frame) != "6789A" {
  302. t.Error("Unexpected frame:", string(frame), frame)
  303. return
  304. }
  305. if pl.ContentType() != "audio" {
  306. t.Error("Content type should be generic not:", pl.ContentType())
  307. return
  308. }
  309. frame, err = pl.Frame()
  310. if err != dudeldu.ErrPlaylistEnd {
  311. t.Error(err)
  312. return
  313. } else if string(frame) != "" {
  314. t.Error("Unexpected frame:", string(frame), frame)
  315. return
  316. }
  317. if !pl.Finished() {
  318. t.Error("Playlist should be finished")
  319. return
  320. }
  321. // Increase the framesize
  322. FrameSize = 10
  323. pl.Close()
  324. frame, err = pl.Frame()
  325. if err != nil {
  326. t.Error(err)
  327. return
  328. } else if string(frame) != "123456789A" {
  329. t.Error("Unexpected frame:", string(frame), frame)
  330. return
  331. }
  332. frame, err = pl.Frame()
  333. if err != dudeldu.ErrPlaylistEnd {
  334. t.Error(err)
  335. return
  336. } else if string(frame) != "" {
  337. t.Error("Unexpected frame:", string(frame), frame)
  338. return
  339. }
  340. if !pl.Finished() {
  341. t.Error("Playlist should be finished")
  342. return
  343. }
  344. // Increase the framesize
  345. FrameSize = 11
  346. pl.Close()
  347. frame, err = pl.Frame()
  348. if err != dudeldu.ErrPlaylistEnd {
  349. t.Error(err)
  350. return
  351. } else if string(frame) != "123456789A" {
  352. t.Error("Unexpected frame:", string(frame), frame)
  353. return
  354. }
  355. if !pl.Finished() {
  356. t.Error("Playlist should be finished")
  357. return
  358. }
  359. // Check that the playlist has finished indeed
  360. if _, err := pl.Frame(); err != dudeldu.ErrPlaylistEnd {
  361. t.Error("Playlist end error expected")
  362. return
  363. }
  364. // Create playlist factory
  365. plf, err = NewFilePlaylistFactory(pdir + "/test2.json")
  366. if err != nil {
  367. t.Error(err)
  368. return
  369. }
  370. // Test error
  371. pl2 := plf.Playlist("/testpath", false)
  372. defer pl2.Close()
  373. FrameSize = 6
  374. frame, err = pl2.Frame()
  375. if err != nil {
  376. t.Error(err)
  377. return
  378. } else if string(frame) != "123456" {
  379. t.Error("Unexpected frame:", string(frame), frame)
  380. return
  381. }
  382. frame, err = pl2.Frame()
  383. if err.Error() != "open playlisttest/nonexist: The system cannot find the file specified." &&
  384. err.Error() != "open playlisttest/nonexist: no such file or directory" {
  385. t.Error(err)
  386. return
  387. } else if string(frame) != "789" {
  388. t.Error("Unexpected frame:", string(frame), frame)
  389. return
  390. }
  391. frame, err = pl2.Frame()
  392. if err != dudeldu.ErrPlaylistEnd {
  393. t.Error(err)
  394. return
  395. } else if string(frame) != "A" {
  396. t.Error("Unexpected frame:", string(frame), frame)
  397. return
  398. }
  399. // Make sure currentItem does not blow up
  400. if pl2.Title() != "test3" {
  401. t.Error("Unexpected result:", pl2.Title())
  402. return
  403. }
  404. // Test shuffling
  405. pl3 := plf.Playlist("/testpath", true)
  406. if len(pl3.(*FilePlaylist).data) != len(pl2.(*FilePlaylist).data) {
  407. t.Error("Length of playlists differ")
  408. return
  409. }
  410. }