config_test.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. * Public Domain Software
  3. *
  4. * I (Matthias Ladkau) am the author of the source code in this file.
  5. * I have placed the source code in this file in the public domain.
  6. *
  7. * For further information see: http://creativecommons.org/publicdomain/zero/1.0/
  8. */
  9. package fileutil
  10. import (
  11. "io/ioutil"
  12. "os"
  13. "strings"
  14. "testing"
  15. "time"
  16. )
  17. const InvalidFileName = "**" + string(0x0)
  18. var testDefaultConfig = map[string]interface{}{
  19. "MemoryOnlyStorage": false,
  20. "DatastoreLocation": "db",
  21. }
  22. func TestLoadingConfig(t *testing.T) {
  23. configFile := "test.config.json"
  24. if res, _ := PathExists(configFile); res {
  25. os.Remove(configFile)
  26. }
  27. // Test config creation
  28. config, err := LoadConfig(configFile, testDefaultConfig)
  29. if err != nil {
  30. t.Error(err)
  31. return
  32. }
  33. if res, _ := PathExists(configFile); !res {
  34. t.Error("Config should have been created")
  35. return
  36. }
  37. // We should have now created a default config file
  38. compareConfig(t, config, testDefaultConfig)
  39. // Test reload of config creation
  40. config, err = LoadConfig(configFile, testDefaultConfig)
  41. if err != nil {
  42. t.Error(err)
  43. return
  44. }
  45. compareConfig(t, config, testDefaultConfig)
  46. ioutil.WriteFile(configFile, []byte("{ \"wrong"), 0644)
  47. _, err = LoadConfig(configFile, testDefaultConfig)
  48. if err.Error() != "unexpected end of JSON input" {
  49. t.Error(err)
  50. return
  51. }
  52. // Write partial config - Make sure all is loaded
  53. ioutil.WriteFile(configFile, []byte(`{"MemoryOnlyStorage":false}`), 0644)
  54. config, err = LoadConfig(configFile, testDefaultConfig)
  55. if err != nil {
  56. t.Error(err)
  57. return
  58. }
  59. // Check that the default values have been added
  60. compareConfig(t, config, testDefaultConfig)
  61. // Test value retrival
  62. if res := ConfBool(config, "MemoryOnlyStorage"); res {
  63. t.Error("Unexpected result:", res)
  64. return
  65. }
  66. if res := ConfStr(config, "DatastoreLocation"); res != "db" {
  67. t.Error("Unexpected result:", res)
  68. return
  69. }
  70. if res, _ := PathExists(configFile); res {
  71. os.Remove(configFile)
  72. }
  73. // Check invalid config file
  74. configFile = "**" + string(0x0)
  75. _, err = LoadConfig(configFile, testDefaultConfig)
  76. if !strings.Contains(strings.ToLower(err.Error()), string(0)+": invalid argument") {
  77. t.Error(err)
  78. return
  79. }
  80. }
  81. func compareConfig(t *testing.T, config1 map[string]interface{}, config2 map[string]interface{}) {
  82. if len(config1) != len(config2) {
  83. t.Error("Given config has different elements to loaded config:",
  84. config1, config2)
  85. return
  86. }
  87. for k, v := range config1 {
  88. if v != config2[k] {
  89. t.Error("Different values for:", k, " -> ", v, "vs", config2[k])
  90. return
  91. }
  92. }
  93. }
  94. func TestPersistedConfig(t *testing.T) {
  95. testFile := "persist_tester.cfg"
  96. defer func() {
  97. os.Remove(testFile)
  98. }()
  99. // Test the most basic start and stop
  100. pt, err := NewWatchedConfig(testFile, testDefaultConfig, time.Millisecond)
  101. if err != nil {
  102. t.Error(err)
  103. return
  104. }
  105. v, ok, err := pt.GetValue("MemoryOnlyStorage")
  106. if !ok || err != nil || v != false {
  107. t.Error("Unexpected stored value:", v, ok, err)
  108. return
  109. }
  110. v, ok, err = pt.GetValue("foo")
  111. if ok || err != nil || v != nil {
  112. t.Error("Unexpected stored value:", v, ok, err)
  113. return
  114. }
  115. c, err := pt.GetConfig()
  116. if err != nil {
  117. t.Error("Unexpected result:", err)
  118. return
  119. }
  120. if len(c) != 2 {
  121. t.Error("Unexpected result:", c)
  122. return
  123. }
  124. ioutil.WriteFile(testFile, []byte(`{"MemoryOnlyStorage":true}`), 0644)
  125. time.Sleep(100 * time.Millisecond)
  126. v, ok, err = pt.GetValue("MemoryOnlyStorage")
  127. if !ok || err != nil || v != true {
  128. t.Error("Unexpected stored value:", v, ok, err)
  129. return
  130. }
  131. // Check error state
  132. pt.filename = InvalidFileName
  133. WatchedConfigErrRetries = 2
  134. time.Sleep(10 * time.Millisecond)
  135. _, _, err = pt.GetValue("MemoryOnlyStorage")
  136. if err == nil || err.Error() != "Could not sync config from disk: open **"+string(0)+": invalid argument" {
  137. t.Error("Unexpected stored value:", err)
  138. return
  139. }
  140. _, err = pt.GetConfig()
  141. if err == nil || err.Error() != "Could not sync config from disk: open **"+string(0)+": invalid argument" {
  142. t.Error("Unexpected stored value:", err)
  143. return
  144. }
  145. err = pt.Close()
  146. if err == nil || err.Error() != "Could not sync config from disk: open **"+string(0)+": invalid argument" {
  147. t.Error("Unexpected stored value:", err)
  148. return
  149. }
  150. pt, err = NewWatchedConfig(testFile, testDefaultConfig, time.Millisecond)
  151. if err != nil {
  152. t.Error(err)
  153. return
  154. }
  155. time.Sleep(100 * time.Millisecond)
  156. os.Remove(testFile)
  157. time.Sleep(100 * time.Millisecond)
  158. v, ok, err = pt.GetValue("MemoryOnlyStorage")
  159. if !ok || err != nil || v != true {
  160. t.Error("Unexpected stored value:", v, ok, err)
  161. return
  162. }
  163. err = pt.Close()
  164. if err != nil {
  165. t.Error("Unexpected stored value:", err)
  166. return
  167. }
  168. }