dir_test.go 6.1 KB

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