You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

361 lines
12KB

  1. package iris
  2. import (
  3. "io/ioutil"
  4. "os"
  5. "reflect"
  6. "testing"
  7. "time"
  8. "gopkg.in/yaml.v3"
  9. )
  10. // $ go test -v -run TestConfiguration*
  11. func TestConfigurationStatic(t *testing.T) {
  12. def := DefaultConfiguration()
  13. app := New()
  14. afterNew := *app.config
  15. if !reflect.DeepEqual(def, afterNew) {
  16. t.Fatalf("Default configuration is not the same after NewFromConfig expected:\n %#v \ngot:\n %#v", def, afterNew)
  17. }
  18. afterNew.Charset = "changed"
  19. if reflect.DeepEqual(def, afterNew) {
  20. t.Fatalf("Configuration should be not equal, got: %#v", afterNew)
  21. }
  22. app = New().Configure(WithConfiguration(Configuration{DisableBodyConsumptionOnUnmarshal: true}))
  23. afterNew = *app.config
  24. if !app.config.DisableBodyConsumptionOnUnmarshal {
  25. t.Fatalf("Passing a Configuration field as Option fails, expected DisableBodyConsumptionOnUnmarshal to be true but was false")
  26. }
  27. app = New() // empty , means defaults so
  28. if !reflect.DeepEqual(def, *app.config) {
  29. t.Fatalf("Default configuration is not the same after NewFromConfig expected:\n %#v \ngot:\n %#v", def, *app.config)
  30. }
  31. }
  32. func TestConfigurationOptions(t *testing.T) {
  33. charset := "MYCHARSET"
  34. disableBodyConsumptionOnUnmarshal := true
  35. disableBanner := true
  36. app := New().Configure(WithCharset(charset), WithoutBodyConsumptionOnUnmarshal, WithoutBanner)
  37. if got := app.config.Charset; got != charset {
  38. t.Fatalf("Expected configuration Charset to be: %s but got: %s", charset, got)
  39. }
  40. if got := app.config.DisableBodyConsumptionOnUnmarshal; got != disableBodyConsumptionOnUnmarshal {
  41. t.Fatalf("Expected configuration DisableBodyConsumptionOnUnmarshal to be: %#v but got: %#v", disableBodyConsumptionOnUnmarshal, got)
  42. }
  43. if got := app.config.DisableStartupLog; got != disableBanner {
  44. t.Fatalf("Expected configuration DisableStartupLog to be: %#v but got: %#v", disableBanner, got)
  45. }
  46. // now check if other default values are set (should be set automatically)
  47. expected := DefaultConfiguration()
  48. expected.Charset = charset
  49. expected.DisableBodyConsumptionOnUnmarshal = disableBodyConsumptionOnUnmarshal
  50. expected.DisableStartupLog = disableBanner
  51. has := *app.config
  52. if !reflect.DeepEqual(has, expected) {
  53. t.Fatalf("Default configuration is not the same after New expected:\n %#v \ngot:\n %#v", expected, has)
  54. }
  55. }
  56. func TestConfigurationOptionsDeep(t *testing.T) {
  57. charset := "MYCHARSET"
  58. app := New().Configure(WithCharset(charset), WithoutBodyConsumptionOnUnmarshal, WithoutBanner)
  59. expected := DefaultConfiguration()
  60. expected.Charset = charset
  61. expected.DisableBodyConsumptionOnUnmarshal = true
  62. expected.DisableStartupLog = true
  63. has := *app.config
  64. if !reflect.DeepEqual(has, expected) {
  65. t.Fatalf("DEEP configuration is not the same after New expected:\n %#v \ngot:\n %#v", expected, has)
  66. }
  67. }
  68. func createGlobalConfiguration(t *testing.T) {
  69. filename := homeConfigurationFilename(".yml")
  70. c, err := parseYAML(filename)
  71. if err != nil {
  72. // this error will be occurred the first time that the configuration
  73. // file doesn't exist.
  74. // Create the YAML-ONLY global configuration file now using the default configuration 'c'.
  75. // This is useful when we run multiple iris servers that share the same
  76. // configuration, even with custom values at its "Other" field.
  77. out, err := yaml.Marshal(&c)
  78. if err == nil {
  79. err = ioutil.WriteFile(filename, out, os.FileMode(0666))
  80. }
  81. if err != nil {
  82. t.Fatalf("error while writing the global configuration field at: %s. Trace: %v\n", filename, err)
  83. }
  84. }
  85. }
  86. func TestConfigurationGlobal(t *testing.T) {
  87. t.Cleanup(func() {
  88. os.Remove(homeConfigurationFilename(".yml"))
  89. })
  90. createGlobalConfiguration(t)
  91. testConfigurationGlobal(t, WithGlobalConfiguration)
  92. testConfigurationGlobal(t, WithConfiguration(YAML(globalConfigurationKeyword)))
  93. }
  94. func testConfigurationGlobal(t *testing.T, c Configurator) {
  95. app := New().Configure(c)
  96. if has, expected := *app.config, DefaultConfiguration(); !reflect.DeepEqual(has, expected) {
  97. t.Fatalf("global configuration (which should be defaulted) is not the same with the default one:\n %#v \ngot:\n %#v", has, expected)
  98. }
  99. }
  100. func TestConfigurationYAML(t *testing.T) {
  101. yamlFile, ferr := ioutil.TempFile("", "configuration.yml")
  102. if ferr != nil {
  103. t.Fatal(ferr)
  104. }
  105. defer func() {
  106. yamlFile.Close()
  107. time.Sleep(50 * time.Millisecond)
  108. os.Remove(yamlFile.Name())
  109. }()
  110. yamlConfigurationContents := `
  111. DisablePathCorrection: false
  112. DisablePathCorrectionRedirection: true
  113. EnablePathIntelligence: true
  114. EnablePathEscape: false
  115. FireMethodNotAllowed: true
  116. EnableOptimizations: true
  117. DisableBodyConsumptionOnUnmarshal: true
  118. TimeFormat: "Mon, 02 Jan 2006 15:04:05 GMT"
  119. Charset: "utf-8"
  120. RemoteAddrHeaders:
  121. - X-Real-Ip
  122. - X-Forwarded-For
  123. - CF-Connecting-IP
  124. HostProxyHeaders:
  125. X-Host: true
  126. SSLProxyHeaders:
  127. X-Forwarded-Proto: https
  128. Other:
  129. MyServerName: "Iris: https://github.com/kataras/iris"
  130. `
  131. yamlFile.WriteString(yamlConfigurationContents)
  132. filename := yamlFile.Name()
  133. app := New().Configure(WithConfiguration(YAML(filename)))
  134. c := app.config
  135. if expected := false; c.DisablePathCorrection != expected {
  136. t.Fatalf("error on TestConfigurationYAML: Expected DisablePathCorrection %v but got %v", expected, c.DisablePathCorrection)
  137. }
  138. if expected := true; c.DisablePathCorrectionRedirection != expected {
  139. t.Fatalf("error on TestConfigurationYAML: Expected DisablePathCorrectionRedirection %v but got %v", expected, c.DisablePathCorrectionRedirection)
  140. }
  141. if expected := true; c.EnablePathIntelligence != expected {
  142. t.Fatalf("error on TestConfigurationYAML: Expected EnablePathIntelligence %v but got %v", expected, c.EnablePathIntelligence)
  143. }
  144. if expected := false; c.EnablePathEscape != expected {
  145. t.Fatalf("error on TestConfigurationYAML: Expected EnablePathEscape %v but got %v", expected, c.EnablePathEscape)
  146. }
  147. if expected := true; c.EnableOptimizations != expected {
  148. t.Fatalf("error on TestConfigurationYAML: Expected EnableOptimizations %v but got %v", expected, c.EnablePathEscape)
  149. }
  150. if expected := true; c.FireMethodNotAllowed != expected {
  151. t.Fatalf("error on TestConfigurationYAML: Expected FireMethodNotAllowed %v but got %v", expected, c.FireMethodNotAllowed)
  152. }
  153. if expected := true; c.DisableBodyConsumptionOnUnmarshal != expected {
  154. t.Fatalf("error on TestConfigurationYAML: Expected DisableBodyConsumptionOnUnmarshal %v but got %v", expected, c.DisableBodyConsumptionOnUnmarshal)
  155. }
  156. if expected := "Mon, 02 Jan 2006 15:04:05 GMT"; c.TimeFormat != expected {
  157. t.Fatalf("error on TestConfigurationYAML: Expected TimeFormat %s but got %s", expected, c.TimeFormat)
  158. }
  159. if expected := "utf-8"; c.Charset != expected {
  160. t.Fatalf("error on TestConfigurationYAML: Expected Charset %s but got %s", expected, c.Charset)
  161. }
  162. if len(c.RemoteAddrHeaders) == 0 {
  163. t.Fatalf("error on TestConfigurationYAML: Expected RemoteAddrHeaders to be filled")
  164. }
  165. expectedRemoteAddrHeaders := []string{
  166. "X-Real-Ip",
  167. "X-Forwarded-For",
  168. "CF-Connecting-IP",
  169. }
  170. if expected, got := len(c.RemoteAddrHeaders), len(expectedRemoteAddrHeaders); expected != got {
  171. t.Fatalf("error on TestConfigurationYAML: Expected RemoteAddrHeaders' len(%d) and got(%d), len is not the same", expected, got)
  172. }
  173. for i, v := range c.RemoteAddrHeaders {
  174. if expected, got := expectedRemoteAddrHeaders[i], v; expected != got {
  175. t.Fatalf("error on TestConfigurationYAML: Expected RemoteAddrHeaders[%d] = %s but got %s", i, expected, got)
  176. }
  177. }
  178. expectedHostProxyHeaders := map[string]bool{
  179. "X-Host": true,
  180. }
  181. if expected, got := len(c.HostProxyHeaders), len(expectedHostProxyHeaders); expected != got {
  182. t.Fatalf("error on TestConfigurationYAML: Expected HostProxyHeaders' len(%d) and got(%d), len is not the same", expected, got)
  183. }
  184. for k, v := range c.HostProxyHeaders {
  185. if expected, got := expectedHostProxyHeaders[k], v; expected != got {
  186. t.Fatalf("error on TestConfigurationYAML: Expected HostProxyHeaders[%s] = %t but got %t", k, expected, got)
  187. }
  188. }
  189. expectedSSLProxyHeaders := map[string]string{
  190. "X-Forwarded-Proto": "https",
  191. }
  192. if expected, got := len(c.SSLProxyHeaders), len(c.SSLProxyHeaders); expected != got {
  193. t.Fatalf("error on TestConfigurationYAML: Expected SSLProxyHeaders' len(%d) and got(%d), len is not the same", expected, got)
  194. }
  195. for k, v := range c.SSLProxyHeaders {
  196. if expected, got := expectedSSLProxyHeaders[k], v; expected != got {
  197. t.Fatalf("error on TestConfigurationYAML: Expected SSLProxyHeaders[%s] = %s but got %s", k, expected, got)
  198. }
  199. }
  200. if len(c.Other) == 0 {
  201. t.Fatalf("error on TestConfigurationYAML: Expected Other to be filled")
  202. }
  203. if expected, got := "Iris: https://github.com/kataras/iris", c.Other["MyServerName"]; expected != got {
  204. t.Fatalf("error on TestConfigurationYAML: Expected Other['MyServerName'] %s but got %s", expected, got)
  205. }
  206. }
  207. func TestConfigurationTOML(t *testing.T) {
  208. tomlFile, ferr := ioutil.TempFile("", "configuration.toml")
  209. if ferr != nil {
  210. t.Fatal(ferr)
  211. }
  212. defer func() {
  213. tomlFile.Close()
  214. time.Sleep(50 * time.Millisecond)
  215. os.Remove(tomlFile.Name())
  216. }()
  217. tomlConfigurationContents := `
  218. DisablePathCorrectionRedirection = true
  219. EnablePathEscape = false
  220. FireMethodNotAllowed = true
  221. EnableOptimizations = true
  222. DisableBodyConsumptionOnUnmarshal = true
  223. TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
  224. Charset = "utf-8"
  225. RemoteAddrHeaders = ["X-Real-Ip", "X-Forwarded-For", "CF-Connecting-IP"]
  226. [Other]
  227. # Indentation (tabs and/or spaces) is allowed but not required
  228. MyServerName = "Iris: https://github.com/kataras/iris"
  229. `
  230. tomlFile.WriteString(tomlConfigurationContents)
  231. filename := tomlFile.Name()
  232. app := New().Configure(WithConfiguration(TOML(filename)))
  233. c := app.config
  234. if expected := false; c.DisablePathCorrection != expected {
  235. t.Fatalf("error on TestConfigurationTOML: Expected DisablePathCorrection %v but got %v", expected, c.DisablePathCorrection)
  236. }
  237. if expected := true; c.DisablePathCorrectionRedirection != expected {
  238. t.Fatalf("error on TestConfigurationTOML: Expected DisablePathCorrectionRedirection %v but got %v", expected, c.DisablePathCorrectionRedirection)
  239. }
  240. if expected := false; c.EnablePathEscape != expected {
  241. t.Fatalf("error on TestConfigurationTOML: Expected EnablePathEscape %v but got %v", expected, c.EnablePathEscape)
  242. }
  243. if expected := true; c.EnableOptimizations != expected {
  244. t.Fatalf("error on TestConfigurationTOML: Expected EnableOptimizations %v but got %v", expected, c.EnablePathEscape)
  245. }
  246. if expected := true; c.FireMethodNotAllowed != expected {
  247. t.Fatalf("error on TestConfigurationTOML: Expected FireMethodNotAllowed %v but got %v", expected, c.FireMethodNotAllowed)
  248. }
  249. if expected := true; c.DisableBodyConsumptionOnUnmarshal != expected {
  250. t.Fatalf("error on TestConfigurationTOML: Expected DisableBodyConsumptionOnUnmarshal %v but got %v", expected, c.DisableBodyConsumptionOnUnmarshal)
  251. }
  252. if expected := "Mon, 02 Jan 2006 15:04:05 GMT"; c.TimeFormat != expected {
  253. t.Fatalf("error on TestConfigurationTOML: Expected TimeFormat %s but got %s", expected, c.TimeFormat)
  254. }
  255. if expected := "utf-8"; c.Charset != expected {
  256. t.Fatalf("error on TestConfigurationTOML: Expected Charset %s but got %s", expected, c.Charset)
  257. }
  258. if len(c.RemoteAddrHeaders) == 0 {
  259. t.Fatalf("error on TestConfigurationTOML: Expected RemoteAddrHeaders to be filled")
  260. }
  261. expectedRemoteAddrHeaders := []string{
  262. "X-Real-Ip",
  263. "X-Forwarded-For",
  264. "CF-Connecting-IP",
  265. }
  266. if expected, got := len(c.RemoteAddrHeaders), len(expectedRemoteAddrHeaders); expected != got {
  267. t.Fatalf("error on TestConfigurationTOML: Expected RemoteAddrHeaders' len(%d) and got(%d), len is not the same", expected, got)
  268. }
  269. for i, got := range c.RemoteAddrHeaders {
  270. if expected := expectedRemoteAddrHeaders[i]; expected != got {
  271. t.Fatalf("error on TestConfigurationTOML: Expected RemoteAddrHeaders[%d] = %s but got %s", i, expected, got)
  272. }
  273. }
  274. if len(c.Other) == 0 {
  275. t.Fatalf("error on TestConfigurationTOML: Expected Other to be filled")
  276. }
  277. if expected, got := "Iris: https://github.com/kataras/iris", c.Other["MyServerName"]; expected != got {
  278. t.Fatalf("error on TestConfigurationTOML: Expected Other['MyServerName'] %s but got %s", expected, got)
  279. }
  280. }