dir_test.go 6.0 KB

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