setting_test.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. package setting
  2. import (
  3. "gopkg.in/ini.v1"
  4. "os"
  5. "path"
  6. "path/filepath"
  7. "runtime"
  8. "testing"
  9. . "github.com/smartystreets/goconvey/convey"
  10. )
  11. func TestLoadingSettings(t *testing.T) {
  12. Convey("Testing loading settings from ini file", t, func() {
  13. skipStaticRootValidation = true
  14. Convey("Given the default ini files", func() {
  15. cfg := NewCfg()
  16. err := cfg.Load(&CommandLineArgs{HomePath: "../../"})
  17. So(err, ShouldBeNil)
  18. So(AdminUser, ShouldEqual, "admin")
  19. So(cfg.RendererCallbackUrl, ShouldEqual, "http://localhost:3000/")
  20. })
  21. Convey("Should be able to override via environment variables", func() {
  22. os.Setenv("GF_SECURITY_ADMIN_USER", "superduper")
  23. cfg := NewCfg()
  24. cfg.Load(&CommandLineArgs{HomePath: "../../"})
  25. So(AdminUser, ShouldEqual, "superduper")
  26. So(cfg.DataPath, ShouldEqual, filepath.Join(HomePath, "data"))
  27. So(cfg.LogsPath, ShouldEqual, filepath.Join(cfg.DataPath, "log"))
  28. })
  29. Convey("Should replace password when defined in environment", func() {
  30. os.Setenv("GF_SECURITY_ADMIN_PASSWORD", "supersecret")
  31. cfg := NewCfg()
  32. cfg.Load(&CommandLineArgs{HomePath: "../../"})
  33. So(appliedEnvOverrides, ShouldContain, "GF_SECURITY_ADMIN_PASSWORD=*********")
  34. })
  35. Convey("Should return an error when url is invalid", func() {
  36. os.Setenv("GF_DATABASE_URL", "postgres.%31://grafana:secret@postgres:5432/grafana")
  37. cfg := NewCfg()
  38. err := cfg.Load(&CommandLineArgs{HomePath: "../../"})
  39. So(err, ShouldNotBeNil)
  40. })
  41. Convey("Should replace password in URL when url environment is defined", func() {
  42. os.Setenv("GF_DATABASE_URL", "mysql://user:secret@localhost:3306/database")
  43. cfg := NewCfg()
  44. cfg.Load(&CommandLineArgs{HomePath: "../../"})
  45. So(appliedEnvOverrides, ShouldContain, "GF_DATABASE_URL=mysql://user:-redacted-@localhost:3306/database")
  46. })
  47. Convey("Should get property map from command line args array", func() {
  48. props := getCommandLineProperties([]string{"cfg:test=value", "cfg:map.test=1"})
  49. So(len(props), ShouldEqual, 2)
  50. So(props["test"], ShouldEqual, "value")
  51. So(props["map.test"], ShouldEqual, "1")
  52. })
  53. Convey("Should be able to override via command line", func() {
  54. if runtime.GOOS == "windows" {
  55. cfg := NewCfg()
  56. cfg.Load(&CommandLineArgs{
  57. HomePath: "../../",
  58. Args: []string{`cfg:paths.data=c:\tmp\data`, `cfg:paths.logs=c:\tmp\logs`},
  59. })
  60. So(cfg.DataPath, ShouldEqual, `c:\tmp\data`)
  61. So(cfg.LogsPath, ShouldEqual, `c:\tmp\logs`)
  62. } else {
  63. cfg := NewCfg()
  64. cfg.Load(&CommandLineArgs{
  65. HomePath: "../../",
  66. Args: []string{"cfg:paths.data=/tmp/data", "cfg:paths.logs=/tmp/logs"},
  67. })
  68. So(cfg.DataPath, ShouldEqual, "/tmp/data")
  69. So(cfg.LogsPath, ShouldEqual, "/tmp/logs")
  70. }
  71. })
  72. Convey("Should be able to override defaults via command line", func() {
  73. cfg := NewCfg()
  74. cfg.Load(&CommandLineArgs{
  75. HomePath: "../../",
  76. Args: []string{
  77. "cfg:default.server.domain=test2",
  78. },
  79. Config: filepath.Join(HomePath, "pkg/setting/testdata/override.ini"),
  80. })
  81. So(Domain, ShouldEqual, "test2")
  82. })
  83. Convey("Defaults can be overridden in specified config file", func() {
  84. if runtime.GOOS == "windows" {
  85. cfg := NewCfg()
  86. cfg.Load(&CommandLineArgs{
  87. HomePath: "../../",
  88. Config: filepath.Join(HomePath, "pkg/setting/testdata/override_windows.ini"),
  89. Args: []string{`cfg:default.paths.data=c:\tmp\data`},
  90. })
  91. So(cfg.DataPath, ShouldEqual, `c:\tmp\override`)
  92. } else {
  93. cfg := NewCfg()
  94. cfg.Load(&CommandLineArgs{
  95. HomePath: "../../",
  96. Config: filepath.Join(HomePath, "pkg/setting/testdata/override.ini"),
  97. Args: []string{"cfg:default.paths.data=/tmp/data"},
  98. })
  99. So(cfg.DataPath, ShouldEqual, "/tmp/override")
  100. }
  101. })
  102. Convey("Command line overrides specified config file", func() {
  103. if runtime.GOOS == "windows" {
  104. cfg := NewCfg()
  105. cfg.Load(&CommandLineArgs{
  106. HomePath: "../../",
  107. Config: filepath.Join(HomePath, "pkg/setting/testdata/override_windows.ini"),
  108. Args: []string{`cfg:paths.data=c:\tmp\data`},
  109. })
  110. So(cfg.DataPath, ShouldEqual, `c:\tmp\data`)
  111. } else {
  112. cfg := NewCfg()
  113. cfg.Load(&CommandLineArgs{
  114. HomePath: "../../",
  115. Config: filepath.Join(HomePath, "pkg/setting/testdata/override.ini"),
  116. Args: []string{"cfg:paths.data=/tmp/data"},
  117. })
  118. So(cfg.DataPath, ShouldEqual, "/tmp/data")
  119. }
  120. })
  121. Convey("Can use environment variables in config values", func() {
  122. if runtime.GOOS == "windows" {
  123. os.Setenv("GF_DATA_PATH", `c:\tmp\env_override`)
  124. cfg := NewCfg()
  125. cfg.Load(&CommandLineArgs{
  126. HomePath: "../../",
  127. Args: []string{"cfg:paths.data=${GF_DATA_PATH}"},
  128. })
  129. So(cfg.DataPath, ShouldEqual, `c:\tmp\env_override`)
  130. } else {
  131. os.Setenv("GF_DATA_PATH", "/tmp/env_override")
  132. cfg := NewCfg()
  133. cfg.Load(&CommandLineArgs{
  134. HomePath: "../../",
  135. Args: []string{"cfg:paths.data=${GF_DATA_PATH}"},
  136. })
  137. So(cfg.DataPath, ShouldEqual, "/tmp/env_override")
  138. }
  139. })
  140. Convey("instance_name default to hostname even if hostname env is empty", func() {
  141. cfg := NewCfg()
  142. cfg.Load(&CommandLineArgs{
  143. HomePath: "../../",
  144. })
  145. hostname, _ := os.Hostname()
  146. So(InstanceName, ShouldEqual, hostname)
  147. })
  148. Convey("Reading callback_url should add trailing slash", func() {
  149. cfg := NewCfg()
  150. cfg.Load(&CommandLineArgs{
  151. HomePath: "../../",
  152. Args: []string{"cfg:rendering.callback_url=http://myserver/renderer"},
  153. })
  154. So(cfg.RendererCallbackUrl, ShouldEqual, "http://myserver/renderer/")
  155. })
  156. })
  157. Convey("Test reading string values from .ini file", t, func() {
  158. iniFile, err := ini.Load(path.Join(HomePath, "pkg/setting/testdata/invalid.ini"))
  159. So(err, ShouldBeNil)
  160. Convey("If key is found - should return value from ini file", func() {
  161. value, err := valueAsString(iniFile.Section("server"), "alt_url", "")
  162. So(err, ShouldBeNil)
  163. So(value, ShouldEqual, "https://grafana.com/")
  164. })
  165. Convey("If key is not found - should return default value", func() {
  166. value, err := valueAsString(iniFile.Section("server"), "extra_url", "default_url_val")
  167. So(err, ShouldBeNil)
  168. So(value, ShouldEqual, "default_url_val")
  169. })
  170. Convey("In case of panic - should return user-friendly error", func() {
  171. value, err := valueAsString(iniFile.Section("server"), "root_url", "")
  172. So(err.Error(), ShouldEqual, "Invalid value for key 'root_url' in configuration file")
  173. So(value, ShouldEqual, "")
  174. })
  175. })
  176. }