dir_test.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /*
  2. * Rufs - Remote Union File System
  3. *
  4. * Copyright 2017 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 rumble
  11. import (
  12. "crypto/tls"
  13. "flag"
  14. "fmt"
  15. "io/ioutil"
  16. "log"
  17. "os"
  18. "path"
  19. "path/filepath"
  20. "testing"
  21. "time"
  22. "devt.de/krotik/common/cryptutil"
  23. "devt.de/krotik/common/defs/rumble"
  24. "devt.de/krotik/common/errorutil"
  25. "devt.de/krotik/common/fileutil"
  26. "devt.de/krotik/rufs"
  27. "devt.de/krotik/rufs/api"
  28. "devt.de/krotik/rufs/config"
  29. )
  30. type mockRuntime struct {
  31. }
  32. func (mr *mockRuntime) NewRuntimeError(t error, d string) rumble.RuntimeError {
  33. return fmt.Errorf("%v %v", t, d)
  34. }
  35. func TestDir(t *testing.T) {
  36. // Setup a tree
  37. defer func() {
  38. // Make sure all trees are removed
  39. api.ResetTrees()
  40. }()
  41. tree, err := rufs.NewTree(api.TreeConfigTemplate, api.TreeCertTemplate)
  42. errorutil.AssertOk(err)
  43. api.AddTree("Hans1", tree)
  44. fooRPC := fmt.Sprintf("%v:%v", branchConfigs["footest"][config.RPCHost], branchConfigs["footest"][config.RPCPort])
  45. fooFP := footest.SSLFingerprint()
  46. err = tree.AddBranch("footest", fooRPC, fooFP)
  47. errorutil.AssertOk(err)
  48. err = tree.AddMapping("/", "footest", false)
  49. errorutil.AssertOk(err)
  50. paths, infos, err := tree.Dir("/", "", true, true)
  51. if res := rufs.DirResultToString(paths, infos); err != nil || res != `
  52. /
  53. drwxrwx--- 4.0 KiB sub1
  54. -rwxrwx--- 10 B test1 [73b8af47]
  55. -rwxrwx--- 10 B test2 [b0c1fadd]
  56. /sub1
  57. -rwxrwx--- 17 B test3 [f89782b1]
  58. `[1:] && res != `
  59. /
  60. drwxr-x--- 4.0 KiB sub1
  61. -rwxr-x--- 10 B test1 [73b8af47]
  62. -rwxr-x--- 10 B test2 [b0c1fadd]
  63. /sub1
  64. -rwxr-x--- 17 B test3 [f89782b1]
  65. `[1:] {
  66. t.Error("Unexpected result:", res, err)
  67. return
  68. }
  69. df := &DirFunc{}
  70. mr := &mockRuntime{}
  71. if df.Name() != "fs.dir" {
  72. t.Error("Unexpected result:", df.Name())
  73. return
  74. }
  75. if err := df.Validate(1, mr); err == nil || err.Error() !=
  76. "Invalid construct Function dir requires 3 or 4 parameters: tree, a path, a glob expression and optionally a recursive flag" {
  77. t.Error(err)
  78. return
  79. }
  80. if err := df.Validate(3, mr); err != nil {
  81. t.Error(err)
  82. return
  83. }
  84. if err := df.Validate(4, mr); err != nil {
  85. t.Error(err)
  86. return
  87. }
  88. _, err = df.Execute([]interface{}{"Hans1", "/", "*.mp3", true}, nil, mr)
  89. if err != nil {
  90. t.Error(err)
  91. return
  92. }
  93. res, err := df.Execute([]interface{}{"Hans1", "/", "", true}, nil, mr)
  94. if err != nil {
  95. t.Error(err)
  96. return
  97. }
  98. if fmt.Sprint(res.([]interface{})[0].([]interface{})[0]) != "/" {
  99. t.Error("Unexpected result:", fmt.Sprint(res.([]interface{})[0].([]interface{})[0]))
  100. return
  101. }
  102. if fmt.Sprint(res.([]interface{})[0].([]interface{})[1]) != "/sub1" {
  103. t.Error("Unexpected result:", fmt.Sprint(res.([]interface{})[0].([]interface{})[1]))
  104. return
  105. }
  106. // Test error messages
  107. _, err = df.Execute([]interface{}{"Hans2", "/", "", true}, nil, mr)
  108. if err == nil || err.Error() != "Invalid state Cannot list files: Unknown tree: Hans2" {
  109. t.Error(err)
  110. return
  111. }
  112. }
  113. // Main function for all tests in this package
  114. func TestMain(m *testing.M) {
  115. flag.Parse()
  116. // Create a ssl certificate directory
  117. if res, _ := fileutil.PathExists(certdir); res {
  118. os.RemoveAll(certdir)
  119. }
  120. err := os.Mkdir(certdir, 0770)
  121. if err != nil {
  122. fmt.Print("Could not create test directory:", err.Error())
  123. os.Exit(1)
  124. }
  125. // Create client certificate
  126. certFile := fmt.Sprintf("cert-client.pem")
  127. keyFile := fmt.Sprintf("key-client.pem")
  128. host := "localhost"
  129. err = cryptutil.GenCert(certdir, certFile, keyFile, host, "", 365*24*time.Hour, true, 2048, "")
  130. if err != nil {
  131. panic(err)
  132. }
  133. cert, err := tls.LoadX509KeyPair(path.Join(certdir, certFile), path.Join(certdir, keyFile))
  134. if err != nil {
  135. panic(err)
  136. }
  137. // Set the default client certificate and configuration for the REST API
  138. api.TreeConfigTemplate = map[string]interface{}{
  139. config.TreeSecret: "123",
  140. }
  141. api.TreeCertTemplate = &cert
  142. // Ensure logging is discarded
  143. log.SetOutput(ioutil.Discard)
  144. // Set up test branches
  145. b1, err := createBranch("footest", "foo")
  146. errorutil.AssertOk(err)
  147. b2, err := createBranch("bartest", "bar")
  148. errorutil.AssertOk(err)
  149. footest = b1
  150. bartest = b2
  151. // Create some test files
  152. ioutil.WriteFile("foo/test1", []byte("Test1 file"), 0770)
  153. ioutil.WriteFile("foo/test2", []byte("Test2 file"), 0770)
  154. os.Mkdir("foo/sub1", 0770)
  155. ioutil.WriteFile("foo/sub1/test3", []byte("Sub dir test file"), 0770)
  156. ioutil.WriteFile("bar/test1", []byte("Test3 file"), 0770)
  157. // Run the tests
  158. res := m.Run()
  159. // Shutdown the branches
  160. errorutil.AssertOk(b1.Shutdown())
  161. errorutil.AssertOk(b2.Shutdown())
  162. // Remove all directories again
  163. if err = os.RemoveAll(certdir); err != nil {
  164. fmt.Print("Could not remove test directory:", err.Error())
  165. }
  166. if err = os.RemoveAll("foo"); err != nil {
  167. fmt.Print("Could not remove test directory:", err.Error())
  168. }
  169. if err = os.RemoveAll("bar"); err != nil {
  170. fmt.Print("Could not remove test directory:", err.Error())
  171. }
  172. os.Exit(res)
  173. }
  174. const certdir = "certs" // Directory for certificates
  175. var portCount = 0 // Port assignment counter for Branch ports
  176. var footest, bartest *rufs.Branch // Branches
  177. var branchConfigs = map[string]map[string]interface{}{} // All branch configs
  178. /*
  179. createBranch creates a new branch.
  180. */
  181. func createBranch(name, dir string) (*rufs.Branch, error) {
  182. // Create the path directory
  183. if res, _ := fileutil.PathExists(dir); res {
  184. os.RemoveAll(dir)
  185. }
  186. err := os.Mkdir(dir, 0770)
  187. if err != nil {
  188. fmt.Print("Could not create test directory:", err.Error())
  189. os.Exit(1)
  190. }
  191. // Create the certificate
  192. portCount++
  193. host := fmt.Sprintf("localhost:%v", 9020+portCount)
  194. // Generate a certificate and private key
  195. certFile := fmt.Sprintf("cert-%v.pem", portCount)
  196. keyFile := fmt.Sprintf("key-%v.pem", portCount)
  197. err = cryptutil.GenCert(certdir, certFile, keyFile, host, "", 365*24*time.Hour, true, 2048, "")
  198. if err != nil {
  199. panic(err)
  200. }
  201. cert, err := tls.LoadX509KeyPair(filepath.Join(certdir, certFile), filepath.Join(certdir, keyFile))
  202. if err != nil {
  203. panic(err)
  204. }
  205. // Create the Branch
  206. config := map[string]interface{}{
  207. config.BranchName: name,
  208. config.BranchSecret: "123",
  209. config.EnableReadOnly: false,
  210. config.RPCHost: "localhost",
  211. config.RPCPort: fmt.Sprint(9020 + portCount),
  212. config.LocalFolder: dir,
  213. }
  214. branchConfigs[name] = config
  215. return rufs.NewBranch(config, &cert)
  216. }