No Description
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.

variant_test.go 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. package config_test
  2. import (
  3. "strings"
  4. "testing"
  5. "github.com/stretchr/testify/assert"
  6. "gerrit.wikimedia.org/r/blubber/build"
  7. "gerrit.wikimedia.org/r/blubber/config"
  8. )
  9. func TestVariantConfigYAML(t *testing.T) {
  10. cfg, err := config.ReadConfig([]byte(`---
  11. version: v3
  12. base: foo
  13. variants:
  14. build: {}
  15. production:
  16. copies: build
  17. artifacts:
  18. - from: build
  19. source: /foo/src
  20. destination: /foo/dst
  21. - from: build
  22. source: /bar/src
  23. destination: /bar/dst`))
  24. assert.Nil(t, err)
  25. variant, err := config.ExpandVariant(cfg, "production")
  26. assert.Nil(t, err)
  27. assert.Equal(t, "build", variant.Copies)
  28. assert.Len(t, variant.Artifacts, 2)
  29. }
  30. func TestVariantDependencies(t *testing.T) {
  31. cfg := config.VariantConfig{
  32. Copies: "foo",
  33. Artifacts: []config.ArtifactsConfig{
  34. {From: "build", Source: "/foo/src", Destination: "/foo/dst"},
  35. },
  36. }
  37. assert.Equal(t, []string{"foo", "build"}, cfg.VariantDependencies())
  38. }
  39. func TestVariantLoops(t *testing.T) {
  40. cfg := config.Config{
  41. Variants: map[string]config.VariantConfig{
  42. "foo": config.VariantConfig{Includes: []string{"bar"}},
  43. "bar": config.VariantConfig{Includes: []string{"foo"}}}}
  44. cfgTwo := config.Config{
  45. Variants: map[string]config.VariantConfig{
  46. "foo": config.VariantConfig{},
  47. "bar": config.VariantConfig{Includes: []string{"foo"}}}}
  48. // Configuration that contains a loop in "Includes" should error
  49. _, err := config.ExpandVariant(&cfg, "bar")
  50. assert.NotNil(t, err)
  51. _, errTwo := config.ExpandVariant(&cfgTwo, "bar")
  52. assert.Nil(t, errTwo)
  53. }
  54. func TestVariantConfigInstructions(t *testing.T) {
  55. t.Run("PhaseInstall", func(t *testing.T) {
  56. t.Run("standard source copy", func(t *testing.T) {
  57. cfg := config.VariantConfig{}
  58. cfg.Lives.UID = 123
  59. cfg.Lives.GID = 223
  60. assert.Equal(t,
  61. []build.Instruction{
  62. build.CopyAs{123, 223, build.Copy{[]string{"."}, "."}},
  63. },
  64. cfg.InstructionsForPhase(build.PhaseInstall),
  65. )
  66. })
  67. t.Run("for copies and artifacts", func(t *testing.T) {
  68. cfg := config.VariantConfig{
  69. Copies: "foo",
  70. Artifacts: []config.ArtifactsConfig{
  71. {From: "build", Source: "/foo/src", Destination: "/foo/dst"},
  72. },
  73. CommonConfig: config.CommonConfig{Lives: config.LivesConfig{In: "/srv/service"}},
  74. }
  75. assert.Equal(t,
  76. []build.Instruction{
  77. build.CopyFrom{"foo", build.Copy{[]string{"/srv/service"}, "/srv/service"}},
  78. build.CopyFrom{"foo", build.Copy{[]string{config.LocalLibPrefix}, config.LocalLibPrefix}},
  79. build.CopyFrom{"build", build.Copy{[]string{"/foo/src"}, "/foo/dst"}},
  80. },
  81. cfg.InstructionsForPhase(build.PhaseInstall),
  82. )
  83. })
  84. t.Run("for just artifacts", func(t *testing.T) {
  85. cfg := config.VariantConfig{
  86. Artifacts: []config.ArtifactsConfig{
  87. {From: "build", Source: "/foo/src", Destination: "/foo/dst"},
  88. },
  89. CommonConfig: config.CommonConfig{
  90. Lives: config.LivesConfig{
  91. In: "/srv/service",
  92. UserConfig: config.UserConfig{
  93. UID: 123,
  94. GID: 223,
  95. },
  96. },
  97. },
  98. }
  99. assert.Equal(t,
  100. []build.Instruction{
  101. build.CopyAs{123, 223, build.Copy{[]string{"."}, "."}},
  102. build.CopyAs{123, 223, build.CopyFrom{"build", build.Copy{[]string{"/foo/src"}, "/foo/dst"}}},
  103. },
  104. cfg.InstructionsForPhase(build.PhaseInstall),
  105. )
  106. })
  107. })
  108. t.Run("PhasePostInstall", func(t *testing.T) {
  109. t.Run("with entrypoint", func(t *testing.T) {
  110. cfg := config.VariantConfig{
  111. CommonConfig: config.CommonConfig{
  112. EntryPoint: []string{"/foo", "bar"},
  113. },
  114. }
  115. assert.Equal(t,
  116. []build.Instruction{
  117. build.EntryPoint{[]string{"/foo", "bar"}},
  118. },
  119. cfg.InstructionsForPhase(build.PhasePostInstall),
  120. )
  121. })
  122. t.Run("without Runs.Insecurely", func(t *testing.T) {
  123. cfg := config.VariantConfig{
  124. CommonConfig: config.CommonConfig{
  125. Lives: config.LivesConfig{
  126. UserConfig: config.UserConfig{
  127. As: "foouser",
  128. },
  129. },
  130. Runs: config.RunsConfig{
  131. Insecurely: config.Flag{True: false},
  132. UserConfig: config.UserConfig{
  133. As: "baruser",
  134. },
  135. },
  136. EntryPoint: []string{"/foo", "bar"},
  137. },
  138. }
  139. assert.Equal(t,
  140. []build.Instruction{
  141. build.User{"baruser"},
  142. build.Env{map[string]string{"HOME": "/home/baruser"}},
  143. build.EntryPoint{[]string{"/foo", "bar"}},
  144. },
  145. cfg.InstructionsForPhase(build.PhasePostInstall),
  146. )
  147. })
  148. t.Run("with Runs.Insecurely", func(t *testing.T) {
  149. cfg := config.VariantConfig{
  150. CommonConfig: config.CommonConfig{
  151. Lives: config.LivesConfig{
  152. UserConfig: config.UserConfig{
  153. As: "foouser",
  154. },
  155. },
  156. Runs: config.RunsConfig{
  157. Insecurely: config.Flag{True: true},
  158. UserConfig: config.UserConfig{
  159. As: "baruser",
  160. },
  161. },
  162. EntryPoint: []string{"/foo", "bar"},
  163. },
  164. }
  165. assert.Equal(t,
  166. []build.Instruction{
  167. build.EntryPoint{[]string{"/foo", "bar"}},
  168. },
  169. cfg.InstructionsForPhase(build.PhasePostInstall),
  170. )
  171. })
  172. })
  173. }
  174. func TestVariantConfigValidation(t *testing.T) {
  175. t.Run("includes", func(t *testing.T) {
  176. t.Run("ok", func(t *testing.T) {
  177. _, err := config.ReadConfig([]byte(`---
  178. version: v3
  179. variants:
  180. build: {}
  181. foo: { includes: [build] }`))
  182. assert.False(t, config.IsValidationError(err))
  183. })
  184. t.Run("optional", func(t *testing.T) {
  185. _, err := config.ReadConfig([]byte(`---
  186. version: v3
  187. variants:
  188. build: {}
  189. foo: {}`))
  190. assert.False(t, config.IsValidationError(err))
  191. })
  192. t.Run("bad", func(t *testing.T) {
  193. _, err := config.ReadConfig([]byte(`---
  194. version: v3
  195. variants:
  196. build: {}
  197. foo: { includes: [build, foobuild, foo_build] }`))
  198. if assert.True(t, config.IsValidationError(err)) {
  199. msg := config.HumanizeValidationError(err)
  200. assert.Equal(t, strings.Join([]string{
  201. `includes[1]: references an unknown variant "foobuild"`,
  202. `includes[2]: references an unknown variant "foo_build"`,
  203. }, "\n"), msg)
  204. }
  205. })
  206. })
  207. t.Run("copies", func(t *testing.T) {
  208. t.Run("ok", func(t *testing.T) {
  209. _, err := config.ReadConfig([]byte(`---
  210. version: v3
  211. variants:
  212. build: {}
  213. foo: { copies: build }`))
  214. assert.False(t, config.IsValidationError(err))
  215. })
  216. t.Run("optional", func(t *testing.T) {
  217. _, err := config.ReadConfig([]byte(`---
  218. version: v3
  219. variants:
  220. build: {}
  221. foo: {}`))
  222. assert.False(t, config.IsValidationError(err))
  223. })
  224. t.Run("bad", func(t *testing.T) {
  225. _, err := config.ReadConfig([]byte(`---
  226. version: v3
  227. variants:
  228. build: {}
  229. foo: { copies: foobuild }`))
  230. if assert.True(t, config.IsValidationError(err)) {
  231. msg := config.HumanizeValidationError(err)
  232. assert.Equal(t, `copies: references an unknown variant "foobuild"`, msg)
  233. }
  234. })
  235. })
  236. }