files_test.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package read_test
  2. import (
  3. "os"
  4. "path"
  5. . "github.com/onsi/ginkgo"
  6. . "github.com/onsi/gomega"
  7. "github.com/felamaslen/gmus-backend/pkg/database"
  8. "github.com/felamaslen/gmus-backend/pkg/read"
  9. setup "github.com/felamaslen/gmus-backend/pkg/testing"
  10. "github.com/felamaslen/gmus-backend/pkg/types"
  11. )
  12. var _ = Describe("reading files", func() {
  13. db := database.GetConnection()
  14. BeforeEach(func() {
  15. setup.PrepareDatabaseForTesting()
  16. })
  17. Describe("reading file info", func() {
  18. var results []*types.Song
  19. var files chan *types.File
  20. BeforeEach(func() {
  21. results = nil
  22. files = make(chan *types.File, 1)
  23. })
  24. Context("when all the files are readable", func() {
  25. BeforeEach(func() {
  26. go func() {
  27. defer close(files)
  28. files <- &types.File{
  29. RelativePath: read.TestSong.RelativePath,
  30. ModifiedDate: 100123,
  31. }
  32. }()
  33. outputChan := read.ReadMultipleFiles(read.TestDirectory, files)
  34. outputDone := false
  35. for !outputDone {
  36. select {
  37. case result, more := <-outputChan:
  38. if more {
  39. results = append(results, result)
  40. }
  41. outputDone = !more
  42. }
  43. }
  44. })
  45. It("should return the correct number of results", func() {
  46. Expect(results).To(HaveLen(1))
  47. })
  48. It("should get the correct info from the file", func() {
  49. var expectedResult = read.TestSong
  50. expectedResult.ModifiedDate = 100123
  51. Expect(*results[0]).To(Equal(expectedResult))
  52. })
  53. })
  54. Context("when an error occurs reading a file", func() {
  55. BeforeEach(func() {
  56. go func() {
  57. defer close(files)
  58. files <- &types.File{
  59. RelativePath: "test/file/does/not/exist.ogg",
  60. ModifiedDate: 123,
  61. }
  62. }()
  63. outputChan := read.ReadMultipleFiles(read.TestDirectory, files)
  64. outputDone := false
  65. for !outputDone {
  66. select {
  67. case _, more := <-outputChan:
  68. outputDone = !more
  69. }
  70. }
  71. })
  72. It("should add the file to the scan_errors table", func() {
  73. var scanError []*types.ScanError
  74. db.Select(&scanError, "select relative_path, base_path, error from scan_errors")
  75. Expect(scanError).To(HaveLen(1))
  76. Expect(scanError[0]).To(Equal(&types.ScanError{
  77. RelativePath: "test/file/does/not/exist.ogg",
  78. BasePath: read.TestDirectory,
  79. Error: "open pkg/read/testdata/test/file/does/not/exist.ogg: no such file or directory",
  80. }))
  81. })
  82. })
  83. })
  84. Describe("scanning a directory recursively", func() {
  85. var results []*types.File
  86. var testScanDirectory = func() {
  87. results = nil
  88. files := read.ScanDirectory(read.TestDirectory)
  89. done := false
  90. for !done {
  91. select {
  92. case result, more := <-files:
  93. if more {
  94. results = append(results, result)
  95. }
  96. done = !more
  97. }
  98. }
  99. }
  100. Context("when the database is empty", func() {
  101. BeforeEach(testScanDirectory)
  102. It("should return a channel with all the files in the directory", func() {
  103. Expect(results).To(HaveLen(2))
  104. if results[0].RelativePath == read.TestSong.RelativePath {
  105. Expect(results[0].RelativePath).To(Equal(read.TestSong.RelativePath))
  106. Expect(results[1].RelativePath).To(Equal(read.TestSongNested.RelativePath))
  107. } else {
  108. Expect(results[1].RelativePath).To(Equal(read.TestSong.RelativePath))
  109. Expect(results[0].RelativePath).To(Equal(read.TestSongNested.RelativePath))
  110. }
  111. })
  112. })
  113. Context("when the database already contains one of the files", func() {
  114. BeforeEach(func() {
  115. info, _ := os.Stat(path.Join(read.TestSong.BasePath, read.TestSong.RelativePath))
  116. db.MustExec(
  117. `
  118. insert into songs (title, artist, album, base_path, relative_path, modified_date)
  119. values ($1, $2, $3, $4, $5, $6)
  120. `,
  121. "old title",
  122. "old artist",
  123. "old album",
  124. read.TestSong.BasePath,
  125. read.TestSong.RelativePath,
  126. info.ModTime().Unix(),
  127. )
  128. testScanDirectory()
  129. })
  130. It("should only return those files which do not exist in the database", func() {
  131. Expect(results).To(HaveLen(1))
  132. Expect(results[0].RelativePath).To(Equal(read.TestSongNested.RelativePath))
  133. })
  134. })
  135. Context("when an error previously occurred scanning one of the files", func() {
  136. BeforeEach(func() {
  137. db.MustExec(`
  138. insert into scan_errors (base_path, relative_path, error)
  139. values ($1, $2, $3)
  140. `, read.TestSong.BasePath, read.TestSong.RelativePath, "A bad thing happened")
  141. testScanDirectory()
  142. })
  143. It("should only return those files which did not have errors marked against them", func() {
  144. Expect(results).To(HaveLen(1))
  145. Expect(results[0].RelativePath).To(Equal(read.TestSongNested.RelativePath))
  146. })
  147. })
  148. })
  149. })