agent_test.go 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. package helm_test
  2. import (
  3. "testing"
  4. "helm.sh/helm/v3/pkg/storage/driver"
  5. "github.com/porter-dev/porter/internal/helm"
  6. "github.com/porter-dev/porter/internal/logger"
  7. "helm.sh/helm/v3/pkg/chart"
  8. "helm.sh/helm/v3/pkg/release"
  9. )
  10. func newAgentFixture(t *testing.T, namespace string) *helm.Agent {
  11. t.Helper()
  12. l := logger.NewConsole(true)
  13. form := &helm.Form{
  14. Namespace: namespace,
  15. }
  16. return helm.GetAgentTesting(form, nil, l)
  17. }
  18. type releaseStub struct {
  19. name string
  20. namespace string
  21. version int
  22. chartVersion string
  23. status release.Status
  24. }
  25. // makeReleases adds a slice of releases to the configured storage.
  26. func makeReleases(t *testing.T, agent *helm.Agent, rels []releaseStub) {
  27. t.Helper()
  28. storage := agent.ActionConfig.Releases
  29. for _, r := range rels {
  30. rel := &release.Release{
  31. Name: r.name,
  32. Namespace: r.namespace,
  33. Version: r.version,
  34. Info: &release.Info{
  35. Status: r.status,
  36. },
  37. Chart: &chart.Chart{
  38. Metadata: &chart.Metadata{
  39. Version: r.chartVersion,
  40. Icon: "https://example.com/icon.png",
  41. },
  42. },
  43. }
  44. err := storage.Create(rel)
  45. if err != nil {
  46. t.Fatal(err)
  47. }
  48. }
  49. }
  50. func compareReleaseToStubs(t *testing.T, releases []*release.Release, stubs []releaseStub) {
  51. t.Helper()
  52. if len(releases) != len(stubs) {
  53. t.Fatalf("length of release %v doesn't match length of stub %v\n",
  54. len(releases), len(stubs))
  55. }
  56. for i, r := range releases {
  57. if r.Name != stubs[i].name {
  58. t.Errorf("Release name %v doesn't match stub name %v\n",
  59. r.Name, stubs[i].name)
  60. }
  61. if r.Namespace != stubs[i].namespace {
  62. t.Errorf("Release namespace %v doesn't match stub namespace %v\n",
  63. r.Namespace, stubs[i].namespace)
  64. }
  65. if r.Info.Status != stubs[i].status {
  66. t.Errorf("Release namespace %v doesn't match stub namespace %v\n",
  67. r.Info.Status, stubs[i].status)
  68. }
  69. if r.Version != stubs[i].version {
  70. t.Errorf("Release version %v doesn't match stub version %v\n",
  71. r.Version, stubs[i].version)
  72. }
  73. if r.Chart.Metadata.Version != stubs[i].chartVersion {
  74. t.Errorf("Release metadata version %v doesn't match stub chart version %v\n",
  75. r.Chart.Metadata.Version, stubs[i].chartVersion)
  76. }
  77. }
  78. return
  79. }
  80. type listReleaseTest struct {
  81. name string
  82. namespace string
  83. filter *helm.ListFilter
  84. releases []releaseStub
  85. expRes []releaseStub
  86. }
  87. var listReleaseTests = []listReleaseTest{
  88. listReleaseTest{
  89. name: "simple test across namespaces, should sort by name",
  90. namespace: "",
  91. filter: &helm.ListFilter{
  92. Namespace: "",
  93. Limit: 20,
  94. Skip: 0,
  95. ByDate: false,
  96. StatusFilter: []string{"deployed"},
  97. },
  98. releases: []releaseStub{
  99. releaseStub{"airwatch", "default", 1, "1.0.0", release.StatusDeployed},
  100. releaseStub{"wordpress", "default", 1, "1.0.1", release.StatusDeployed},
  101. releaseStub{"not-in-default-namespace", "other", 1, "1.0.2", release.StatusDeployed},
  102. },
  103. expRes: []releaseStub{
  104. releaseStub{"airwatch", "default", 1, "1.0.0", release.StatusDeployed},
  105. releaseStub{"not-in-default-namespace", "other", 1, "1.0.2", release.StatusDeployed},
  106. releaseStub{"wordpress", "default", 1, "1.0.1", release.StatusDeployed},
  107. },
  108. },
  109. listReleaseTest{
  110. name: "simple test only default namespace",
  111. namespace: "default",
  112. filter: &helm.ListFilter{
  113. Namespace: "",
  114. Limit: 20,
  115. Skip: 0,
  116. ByDate: false,
  117. StatusFilter: []string{"deployed"},
  118. },
  119. releases: []releaseStub{
  120. releaseStub{"airwatch", "default", 1, "1.0.0", release.StatusDeployed},
  121. releaseStub{"wordpress", "default", 1, "1.0.1", release.StatusDeployed},
  122. releaseStub{"not-in-default-namespace", "other", 1, "1.0.2", release.StatusDeployed},
  123. },
  124. expRes: []releaseStub{
  125. releaseStub{"airwatch", "default", 1, "1.0.0", release.StatusDeployed},
  126. releaseStub{"wordpress", "default", 1, "1.0.1", release.StatusDeployed},
  127. },
  128. },
  129. listReleaseTest{
  130. name: "simple test limit",
  131. namespace: "",
  132. filter: &helm.ListFilter{
  133. Namespace: "",
  134. Limit: 2,
  135. Skip: 0,
  136. ByDate: false,
  137. StatusFilter: []string{"deployed"},
  138. },
  139. releases: []releaseStub{
  140. releaseStub{"airwatch", "default", 1, "1.0.0", release.StatusDeployed},
  141. releaseStub{"not-in-default-namespace", "other", 1, "1.0.1", release.StatusDeployed},
  142. releaseStub{"wordpress", "default", 1, "1.0.2", release.StatusDeployed},
  143. },
  144. expRes: []releaseStub{
  145. releaseStub{"airwatch", "default", 1, "1.0.0", release.StatusDeployed},
  146. releaseStub{"not-in-default-namespace", "other", 1, "1.0.1", release.StatusDeployed},
  147. },
  148. },
  149. }
  150. func TestListReleases(t *testing.T) {
  151. for _, tc := range listReleaseTests {
  152. agent := newAgentFixture(t, tc.namespace)
  153. makeReleases(t, agent, tc.releases)
  154. // calling agent.ActionConfig.Releases.Create in makeReleases will automatically set the
  155. // namespace, so we have to reset the namespace of the storage driver
  156. agent.ActionConfig.Releases.Driver.(*driver.Memory).SetNamespace(tc.namespace)
  157. releases, err := agent.ListReleases(tc.namespace, tc.filter)
  158. if err != nil {
  159. t.Errorf("%v", err)
  160. }
  161. compareReleaseToStubs(t, releases, tc.expRes)
  162. }
  163. }
  164. type getReleaseTest struct {
  165. name string
  166. namespace string
  167. releases []releaseStub
  168. getName string
  169. getVersion int
  170. expRes releaseStub
  171. }
  172. var getReleaseTests = []getReleaseTest{
  173. getReleaseTest{
  174. name: "simple get with revision 0 (latest)",
  175. namespace: "default",
  176. releases: []releaseStub{
  177. releaseStub{"airwatch", "default", 1, "1.0.0", release.StatusDeployed},
  178. releaseStub{"wordpress", "default", 1, "1.0.1", release.StatusDeployed},
  179. releaseStub{"not-in-default-namespace", "other", 1, "1.0.2", release.StatusDeployed},
  180. },
  181. getName: "airwatch",
  182. getVersion: 1,
  183. expRes: releaseStub{"airwatch", "default", 1, "1.0.0", release.StatusDeployed},
  184. },
  185. }
  186. func TestGetReleases(t *testing.T) {
  187. for _, tc := range getReleaseTests {
  188. agent := newAgentFixture(t, tc.namespace)
  189. makeReleases(t, agent, tc.releases)
  190. // calling agent.ActionConfig.Releases.Create in makeReleases will automatically set the
  191. // namespace, so we have to reset the namespace of the storage driver
  192. agent.ActionConfig.Releases.Driver.(*driver.Memory).SetNamespace(tc.namespace)
  193. rel, err := agent.GetRelease(tc.getName, tc.getVersion)
  194. if err != nil {
  195. t.Errorf("%v", err)
  196. }
  197. compareReleaseToStubs(t, []*release.Release{rel}, []releaseStub{tc.expRes})
  198. }
  199. }
  200. var listReleaseHistoryTests = []listReleaseTest{
  201. listReleaseTest{
  202. name: "simple history test",
  203. namespace: "default",
  204. releases: []releaseStub{
  205. releaseStub{"wordpress", "default", 2, "1.0.2", release.StatusDeployed},
  206. releaseStub{"wordpress", "default", 1, "1.0.1", release.StatusSuperseded},
  207. },
  208. expRes: []releaseStub{
  209. releaseStub{"wordpress", "default", 1, "1.0.1", release.StatusSuperseded},
  210. releaseStub{"wordpress", "default", 2, "1.0.2", release.StatusDeployed},
  211. },
  212. },
  213. }
  214. func TestListReleaseHistory(t *testing.T) {
  215. for _, tc := range listReleaseHistoryTests {
  216. agent := newAgentFixture(t, tc.namespace)
  217. makeReleases(t, agent, tc.releases)
  218. // calling agent.ActionConfig.Releases.Create in makeReleases will automatically set the
  219. // namespace, so we have to reset the namespace of the storage driver
  220. agent.ActionConfig.Releases.Driver.(*driver.Memory).SetNamespace(tc.namespace)
  221. releases, err := agent.GetReleaseHistory("wordpress")
  222. if err != nil {
  223. t.Errorf("%v", err)
  224. }
  225. compareReleaseToStubs(t, releases, tc.expRes)
  226. }
  227. }
  228. var upgradeTests = []listReleaseTest{
  229. listReleaseTest{
  230. name: "simple history test",
  231. namespace: "default",
  232. releases: []releaseStub{
  233. releaseStub{"wordpress", "default", 2, "1.0.2", release.StatusDeployed},
  234. releaseStub{"wordpress", "default", 1, "1.0.1", release.StatusSuperseded},
  235. },
  236. expRes: []releaseStub{
  237. releaseStub{"wordpress", "default", 1, "1.0.1", release.StatusSuperseded},
  238. releaseStub{"wordpress", "default", 2, "1.0.2", release.StatusSuperseded},
  239. releaseStub{"wordpress", "default", 3, "1.0.2", release.StatusDeployed},
  240. },
  241. },
  242. }
  243. func TestUpgradeRelease(t *testing.T) {
  244. for _, tc := range upgradeTests {
  245. agent := newAgentFixture(t, tc.namespace)
  246. makeReleases(t, agent, tc.releases)
  247. // calling agent.ActionConfig.Releases.Create in makeReleases will automatically set the
  248. // namespace, so we have to reset the namespace of the storage driver
  249. agent.ActionConfig.Releases.Driver.(*driver.Memory).SetNamespace(tc.namespace)
  250. agent.UpgradeRelease("wordpress", "")
  251. releases, err := agent.GetReleaseHistory("wordpress")
  252. if err != nil {
  253. t.Errorf("%v", err)
  254. }
  255. compareReleaseToStubs(t, releases, tc.expRes)
  256. }
  257. }
  258. var rollbackReleaseTests = []getReleaseTest{
  259. getReleaseTest{
  260. name: "simple rollback test",
  261. namespace: "default",
  262. releases: []releaseStub{
  263. releaseStub{"wordpress", "default", 2, "1.0.2", release.StatusDeployed},
  264. releaseStub{"wordpress", "default", 1, "1.0.1", release.StatusSuperseded},
  265. },
  266. getName: "wordpress",
  267. getVersion: 3,
  268. expRes: releaseStub{"wordpress", "default", 3, "1.0.1", release.StatusDeployed},
  269. },
  270. }
  271. func TestRollbackRelease(t *testing.T) {
  272. for _, tc := range rollbackReleaseTests {
  273. agent := newAgentFixture(t, tc.namespace)
  274. makeReleases(t, agent, tc.releases)
  275. // calling agent.ActionConfig.Releases.Create in makeReleases will automatically set the
  276. // namespace, so we have to reset the namespace of the storage driver
  277. agent.ActionConfig.Releases.Driver.(*driver.Memory).SetNamespace(tc.namespace)
  278. err := agent.RollbackRelease("wordpress", 1)
  279. if err != nil {
  280. t.Errorf("%v", err)
  281. }
  282. rel, err := agent.GetRelease(tc.getName, tc.getVersion)
  283. if err != nil {
  284. t.Errorf("%v", err)
  285. }
  286. compareReleaseToStubs(t, []*release.Release{rel}, []releaseStub{tc.expRes})
  287. }
  288. }