/engine/api/pipeline/pipeline_importer_test.go

https://github.com/ovh/cds · Go · 659 lines · 601 code · 56 blank · 2 comment · 18 complexity · cfb732c4833998b2789ca2543bdff933 MD5 · raw file

  1. package pipeline_test
  2. import (
  3. "context"
  4. "testing"
  5. "github.com/go-gorp/gorp"
  6. "github.com/stretchr/testify/assert"
  7. "github.com/ovh/cds/engine/api/bootstrap"
  8. "github.com/ovh/cds/engine/cache"
  9. "github.com/ovh/cds/engine/api/event"
  10. "github.com/ovh/cds/engine/api/pipeline"
  11. "github.com/ovh/cds/engine/api/project"
  12. "github.com/ovh/cds/engine/api/test"
  13. "github.com/ovh/cds/engine/api/test/assets"
  14. "github.com/ovh/cds/sdk"
  15. "github.com/ovh/cds/sdk/log"
  16. )
  17. type args struct {
  18. pkey string
  19. pip *sdk.Pipeline
  20. u *sdk.AuthentifiedUser
  21. }
  22. type testcase struct {
  23. name string
  24. args args
  25. wantErr bool
  26. setup func(t *testing.T, args args)
  27. asserts func(t *testing.T, pip sdk.Pipeline)
  28. tearDown func(t *testing.T, args args)
  29. }
  30. func testImportUpdate(t *testing.T, db gorp.SqlExecutor, store cache.Store, tt testcase) {
  31. msgChan := make(chan sdk.Message, 1)
  32. done := make(chan bool)
  33. go func() {
  34. for {
  35. msg, ok := <-msgChan
  36. if !ok {
  37. done <- true
  38. return
  39. }
  40. log.Debug("[TEST] %s >>> %s", tt.name, msg.String("en"))
  41. }
  42. }()
  43. if tt.setup != nil {
  44. tt.setup(t, tt.args)
  45. }
  46. proj, err := project.Load(context.TODO(), db, tt.args.pip.ProjectKey, nil)
  47. test.NoError(t, err)
  48. if err := pipeline.ImportUpdate(context.TODO(), db, *proj, tt.args.pip, msgChan); (err != nil) != tt.wantErr {
  49. t.Errorf("%q. ImportUpdate() error = %v, wantErr %v", tt.name, err, tt.wantErr)
  50. }
  51. close(msgChan)
  52. <-done
  53. pip, err := pipeline.LoadPipeline(context.TODO(), db, tt.args.pip.ProjectKey, tt.args.pip.Name, true)
  54. test.NoError(t, err)
  55. if tt.asserts != nil {
  56. tt.asserts(t, *pip)
  57. }
  58. if tt.tearDown != nil {
  59. tt.setup(t, tt.args)
  60. }
  61. }
  62. func TestImportUpdate(t *testing.T) {
  63. db, cache := test.SetupPG(t, bootstrap.InitiliazeDB)
  64. _ = event.Initialize(context.Background(), db.DbMap, cache)
  65. if db == nil {
  66. t.FailNow()
  67. }
  68. u, _ := assets.InsertAdminUser(t, db)
  69. //Define the testscases
  70. var test1 = testcase{
  71. name: "import a new stage with one job on a empty pipeline",
  72. wantErr: false,
  73. args: args{
  74. u: u,
  75. pkey: sdk.RandomString(7),
  76. pip: &sdk.Pipeline{},
  77. },
  78. setup: func(t *testing.T, args args) {
  79. proj := assets.InsertTestProject(t, db, cache, args.pkey, args.pkey)
  80. args.pip.Name = proj.Key + "_PIP"
  81. args.pip.ProjectID = proj.ID
  82. args.pip.ProjectKey = proj.Key
  83. test.NoError(t, pipeline.InsertPipeline(db, args.pip))
  84. args.pip.Stages = []sdk.Stage{
  85. {
  86. BuildOrder: 1,
  87. Enabled: true,
  88. Jobs: []sdk.Job{
  89. {
  90. Enabled: false,
  91. Action: sdk.Action{
  92. Name: "Job 1",
  93. Description: "This is the first job",
  94. },
  95. },
  96. },
  97. Name: "This is the first stage",
  98. },
  99. }
  100. },
  101. asserts: func(t *testing.T, pip sdk.Pipeline) {
  102. assert.Equal(t, 1, len(pip.Stages))
  103. assert.Equal(t, 1, len(pip.Stages[0].Jobs))
  104. },
  105. }
  106. var test2 = testcase{
  107. name: "import a new stage with one job on a pipeline with no job",
  108. wantErr: false,
  109. args: args{
  110. u: u,
  111. pkey: sdk.RandomString(7),
  112. pip: &sdk.Pipeline{},
  113. },
  114. setup: func(t *testing.T, args args) {
  115. proj := assets.InsertTestProject(t, db, cache, args.pkey, args.pkey)
  116. args.pip.Name = proj.Key + "_PIP"
  117. args.pip.ProjectID = proj.ID
  118. args.pip.ProjectKey = proj.Key
  119. test.NoError(t, pipeline.InsertPipeline(db, args.pip))
  120. args.pip.Stages = []sdk.Stage{
  121. {
  122. BuildOrder: 1,
  123. Enabled: true,
  124. PipelineID: args.pip.ID,
  125. Name: "This is the first stage. It has no jobs",
  126. },
  127. }
  128. test.NoError(t, pipeline.InsertStage(db, &args.pip.Stages[0]))
  129. for _, j := range args.pip.Stages[0].Jobs {
  130. test.NoError(t, pipeline.InsertJob(db, &j, args.pip.Stages[0].ID, args.pip))
  131. }
  132. args.pip.Stages = append(args.pip.Stages,
  133. sdk.Stage{
  134. BuildOrder: 2,
  135. Enabled: true,
  136. Jobs: []sdk.Job{
  137. {
  138. Enabled: false,
  139. Action: sdk.Action{
  140. Name: "Job 1",
  141. Description: "This is the first job",
  142. },
  143. },
  144. },
  145. Name: "This is the second stage",
  146. },
  147. )
  148. },
  149. asserts: func(t *testing.T, pip sdk.Pipeline) {
  150. t.Logf("Asserts on %+v", pip)
  151. assert.Equal(t, 2, len(pip.Stages))
  152. assert.Equal(t, 0, len(pip.Stages[0].Jobs))
  153. assert.Equal(t, 1, len(pip.Stages[1].Jobs))
  154. },
  155. }
  156. var test3 = testcase{
  157. name: "remove stage on a pipeline with two stages",
  158. wantErr: false,
  159. args: args{
  160. u: u,
  161. pkey: sdk.RandomString(7),
  162. pip: &sdk.Pipeline{},
  163. },
  164. setup: func(t *testing.T, args args) {
  165. proj := assets.InsertTestProject(t, db, cache, args.pkey, args.pkey)
  166. args.pip.Name = proj.Key + "_PIP"
  167. args.pip.ProjectID = proj.ID
  168. args.pip.ProjectKey = proj.Key
  169. test.NoError(t, pipeline.InsertPipeline(db, args.pip))
  170. args.pip.Stages = []sdk.Stage{
  171. {
  172. BuildOrder: 1,
  173. Enabled: true,
  174. PipelineID: args.pip.ID,
  175. Name: "This is the first stage. It has no jobs",
  176. },
  177. {
  178. BuildOrder: 2,
  179. Enabled: true,
  180. PipelineID: args.pip.ID,
  181. Name: "This is the second stage. It has no jobs",
  182. },
  183. }
  184. test.NoError(t, pipeline.InsertStage(db, &args.pip.Stages[0]))
  185. test.NoError(t, pipeline.InsertStage(db, &args.pip.Stages[1]))
  186. args.pip.Stages = args.pip.Stages[:1]
  187. },
  188. asserts: func(t *testing.T, pip sdk.Pipeline) {
  189. t.Logf("Asserts on %+v", pip)
  190. assert.Equal(t, 1, len(pip.Stages))
  191. assert.Equal(t, 0, len(pip.Stages[0].Jobs))
  192. },
  193. }
  194. var test4 = testcase{
  195. name: "remove all the stages",
  196. wantErr: false,
  197. args: args{
  198. u: u,
  199. pkey: sdk.RandomString(7),
  200. pip: &sdk.Pipeline{},
  201. },
  202. setup: func(t *testing.T, args args) {
  203. proj := assets.InsertTestProject(t, db, cache, args.pkey, args.pkey)
  204. args.pip.Name = proj.Key + "_PIP"
  205. args.pip.ProjectID = proj.ID
  206. args.pip.ProjectKey = proj.Key
  207. test.NoError(t, pipeline.InsertPipeline(db, args.pip))
  208. args.pip.Stages = []sdk.Stage{
  209. {
  210. BuildOrder: 1,
  211. Enabled: true,
  212. PipelineID: args.pip.ID,
  213. Name: "This is the first stage. It has no jobs",
  214. },
  215. {
  216. BuildOrder: 2,
  217. Enabled: true,
  218. PipelineID: args.pip.ID,
  219. Name: "This is the second stage. It has no jobs",
  220. },
  221. }
  222. test.NoError(t, pipeline.InsertStage(db, &args.pip.Stages[0]))
  223. test.NoError(t, pipeline.InsertStage(db, &args.pip.Stages[1]))
  224. args.pip.Stages = nil
  225. },
  226. asserts: func(t *testing.T, pip sdk.Pipeline) {
  227. t.Logf("Asserts on %+v", pip)
  228. assert.Equal(t, 0, len(pip.Stages))
  229. },
  230. }
  231. var test5 = testcase{
  232. name: "Add a job on a stage",
  233. wantErr: false,
  234. args: args{
  235. u: u,
  236. pkey: sdk.RandomString(7),
  237. pip: &sdk.Pipeline{},
  238. },
  239. setup: func(t *testing.T, args args) {
  240. proj := assets.InsertTestProject(t, db, cache, args.pkey, args.pkey)
  241. args.pip.Name = proj.Key + "_PIP"
  242. args.pip.ProjectID = proj.ID
  243. args.pip.ProjectKey = proj.Key
  244. test.NoError(t, pipeline.InsertPipeline(db, args.pip))
  245. args.pip.Stages = []sdk.Stage{
  246. {
  247. BuildOrder: 1,
  248. Enabled: true,
  249. PipelineID: args.pip.ID,
  250. Name: "This is the first stage. It has 2 jobs",
  251. Jobs: []sdk.Job{
  252. {
  253. Enabled: true,
  254. Action: sdk.Action{
  255. Name: "Job n°1",
  256. },
  257. },
  258. {
  259. Enabled: true,
  260. Action: sdk.Action{
  261. Name: "Job n°2",
  262. },
  263. },
  264. },
  265. },
  266. {
  267. BuildOrder: 2,
  268. Enabled: true,
  269. PipelineID: args.pip.ID,
  270. Name: "This is the second stage. It has 2 jobs",
  271. Jobs: []sdk.Job{
  272. {
  273. Enabled: true,
  274. Action: sdk.Action{
  275. Name: "Job n°1",
  276. },
  277. },
  278. {
  279. Enabled: true,
  280. Action: sdk.Action{
  281. Name: "Job n°2",
  282. },
  283. },
  284. },
  285. },
  286. }
  287. test.NoError(t, pipeline.InsertStage(db, &args.pip.Stages[0]))
  288. test.NoError(t, pipeline.InsertStage(db, &args.pip.Stages[1]))
  289. for _, j := range args.pip.Stages[0].Jobs {
  290. test.NoError(t, pipeline.InsertJob(db, &j, args.pip.Stages[0].ID, args.pip))
  291. }
  292. for _, j := range args.pip.Stages[1].Jobs {
  293. test.NoError(t, pipeline.InsertJob(db, &j, args.pip.Stages[1].ID, args.pip))
  294. }
  295. args.pip.Stages[1].Jobs = append(args.pip.Stages[1].Jobs, sdk.Job{
  296. Enabled: true,
  297. Action: sdk.Action{
  298. Name: "Job n°3",
  299. },
  300. })
  301. },
  302. asserts: func(t *testing.T, pip sdk.Pipeline) {
  303. t.Logf("Asserts on %+v", pip)
  304. assert.Equal(t, 2, len(pip.Stages))
  305. assert.Equal(t, 2, len(pip.Stages[0].Jobs))
  306. assert.Equal(t, 3, len(pip.Stages[1].Jobs))
  307. },
  308. }
  309. var test6 = testcase{
  310. name: "Update a job on a stage",
  311. wantErr: false,
  312. args: args{
  313. u: u,
  314. pkey: sdk.RandomString(7),
  315. pip: &sdk.Pipeline{},
  316. },
  317. setup: func(t *testing.T, args args) {
  318. proj := assets.InsertTestProject(t, db, cache, args.pkey, args.pkey)
  319. args.pip.Name = proj.Key + "_PIP"
  320. args.pip.ProjectID = proj.ID
  321. args.pip.ProjectKey = proj.Key
  322. args.pip.Parameter = []sdk.Parameter{
  323. {Name: "test", Value: "test_value", Type: sdk.StringParameter, Description: "test_description"},
  324. }
  325. test.NoError(t, pipeline.InsertPipeline(db, args.pip))
  326. args.pip.Parameter = []sdk.Parameter{
  327. {Name: "test", Value: "test_value_bis", Type: sdk.StringParameter, Description: "test_description_bis"},
  328. }
  329. args.pip.Stages = []sdk.Stage{
  330. {
  331. BuildOrder: 1,
  332. Enabled: true,
  333. PipelineID: args.pip.ID,
  334. Name: "This is the first stage. It has 2 jobs",
  335. Jobs: []sdk.Job{
  336. {
  337. Enabled: true,
  338. Action: sdk.Action{
  339. Name: "Job n°1",
  340. },
  341. },
  342. {
  343. Enabled: true,
  344. Action: sdk.Action{
  345. Name: "Job n°2",
  346. },
  347. },
  348. },
  349. },
  350. {
  351. BuildOrder: 2,
  352. Enabled: true,
  353. PipelineID: args.pip.ID,
  354. Name: "This is the second stage. It has 2 jobs",
  355. Jobs: []sdk.Job{
  356. {
  357. Enabled: true,
  358. Action: sdk.Action{
  359. Name: "Job n°1",
  360. },
  361. },
  362. {
  363. Enabled: true,
  364. Action: sdk.Action{
  365. Name: "Job n°2",
  366. },
  367. },
  368. },
  369. },
  370. }
  371. test.NoError(t, pipeline.InsertStage(db, &args.pip.Stages[0]))
  372. test.NoError(t, pipeline.InsertStage(db, &args.pip.Stages[1]))
  373. args.pip.Stages[1].Jobs[1] = sdk.Job{
  374. Enabled: true,
  375. Action: sdk.Action{
  376. Name: "Job n°2bis",
  377. },
  378. }
  379. },
  380. asserts: func(t *testing.T, pip sdk.Pipeline) {
  381. t.Logf("Asserts on %+v", pip)
  382. assert.Equal(t, 2, len(pip.Stages))
  383. assert.Equal(t, 2, len(pip.Stages[0].Jobs))
  384. assert.Equal(t, 2, len(pip.Stages[1].Jobs))
  385. assert.Equal(t, 1, len(pip.Parameter))
  386. assert.Equal(t, "test_value_bis", pip.Parameter[0].Value)
  387. assert.Equal(t, "test_description_bis", pip.Parameter[0].Description)
  388. assert.Equal(t, "Job n°2bis", pip.Stages[1].Jobs[1].Action.Name)
  389. },
  390. }
  391. var test7 = testcase{
  392. name: "Remove a job on a stage and add parameter",
  393. wantErr: false,
  394. args: args{
  395. u: u,
  396. pkey: sdk.RandomString(7),
  397. pip: &sdk.Pipeline{},
  398. },
  399. setup: func(t *testing.T, args args) {
  400. proj := assets.InsertTestProject(t, db, cache, args.pkey, args.pkey)
  401. args.pip.Name = proj.Key + "_PIP"
  402. args.pip.ProjectID = proj.ID
  403. args.pip.ProjectKey = proj.Key
  404. test.NoError(t, pipeline.InsertPipeline(db, args.pip))
  405. args.pip.Parameter = []sdk.Parameter{
  406. {Name: "test", Value: "test_value", Type: sdk.StringParameter, Description: "test_description"},
  407. }
  408. args.pip.Stages = []sdk.Stage{
  409. {
  410. BuildOrder: 1,
  411. Enabled: true,
  412. PipelineID: args.pip.ID,
  413. Name: "This is the first stage. It has 2 jobs",
  414. Jobs: []sdk.Job{
  415. {
  416. Enabled: true,
  417. Action: sdk.Action{
  418. Name: "Job n°1",
  419. },
  420. },
  421. {
  422. Enabled: true,
  423. Action: sdk.Action{
  424. Name: "Job n°2",
  425. },
  426. },
  427. },
  428. },
  429. {
  430. BuildOrder: 2,
  431. Enabled: true,
  432. PipelineID: args.pip.ID,
  433. Name: "This is the second stage. It has 2 jobs",
  434. Jobs: []sdk.Job{
  435. {
  436. Enabled: true,
  437. Action: sdk.Action{
  438. Name: "Job n°1",
  439. },
  440. },
  441. {
  442. Enabled: true,
  443. Action: sdk.Action{
  444. Name: "Job n°2",
  445. },
  446. },
  447. },
  448. },
  449. }
  450. test.NoError(t, pipeline.InsertStage(db, &args.pip.Stages[0]))
  451. test.NoError(t, pipeline.InsertStage(db, &args.pip.Stages[1]))
  452. test.NoError(t, pipeline.InsertParameterInPipeline(db, args.pip.ID, &sdk.Parameter{Name: "oldparam", Type: string(sdk.ParameterTypeString), Value: "foo"}))
  453. args.pip.Stages[1].Jobs = args.pip.Stages[1].Jobs[1:]
  454. },
  455. asserts: func(t *testing.T, pip sdk.Pipeline) {
  456. t.Logf("Asserts on %+v", pip)
  457. assert.Equal(t, 2, len(pip.Stages))
  458. assert.Equal(t, 2, len(pip.Stages[0].Jobs))
  459. assert.Equal(t, 1, len(pip.Stages[1].Jobs))
  460. assert.Equal(t, 1, len(pip.Parameter))
  461. assert.Equal(t, "Job n°2", pip.Stages[1].Jobs[0].Action.Name)
  462. },
  463. }
  464. var test8 = testcase{
  465. name: "Change stage order",
  466. wantErr: false,
  467. args: args{
  468. u: u,
  469. pkey: sdk.RandomString(7),
  470. pip: &sdk.Pipeline{},
  471. },
  472. setup: func(t *testing.T, args args) {
  473. proj := assets.InsertTestProject(t, db, cache, args.pkey, args.pkey)
  474. args.pip.Name = proj.Key + "_PIP"
  475. args.pip.ProjectID = proj.ID
  476. args.pip.ProjectKey = proj.Key
  477. test.NoError(t, pipeline.InsertPipeline(db, args.pip))
  478. args.pip.Parameter = []sdk.Parameter{
  479. {Name: "test", Value: "test_value", Type: sdk.StringParameter, Description: "test_description"},
  480. }
  481. args.pip.Stages = []sdk.Stage{
  482. {
  483. BuildOrder: 1,
  484. Enabled: true,
  485. PipelineID: args.pip.ID,
  486. Name: "This is the first stage. It has 2 jobs",
  487. Jobs: []sdk.Job{
  488. {
  489. Enabled: true,
  490. Action: sdk.Action{
  491. Name: "Job n°1",
  492. },
  493. },
  494. {
  495. Enabled: true,
  496. Action: sdk.Action{
  497. Name: "Job n°2",
  498. },
  499. },
  500. },
  501. },
  502. {
  503. BuildOrder: 2,
  504. Enabled: true,
  505. PipelineID: args.pip.ID,
  506. Name: "This is the second stage. It has 2 jobs",
  507. Jobs: []sdk.Job{
  508. {
  509. Enabled: true,
  510. Action: sdk.Action{
  511. Name: "Job n°1",
  512. },
  513. },
  514. {
  515. Enabled: true,
  516. Action: sdk.Action{
  517. Name: "Job n°2",
  518. },
  519. },
  520. },
  521. },
  522. }
  523. test.NoError(t, pipeline.InsertStage(db, &args.pip.Stages[0]))
  524. test.NoError(t, pipeline.InsertStage(db, &args.pip.Stages[1]))
  525. args.pip.Stages[0].BuildOrder = 2
  526. args.pip.Stages[1].BuildOrder = 1
  527. },
  528. asserts: func(t *testing.T, pip sdk.Pipeline) {
  529. t.Logf("Asserts on %+v", pip)
  530. assert.Equal(t, 2, len(pip.Stages))
  531. assert.Equal(t, 1, pip.Stages[0].BuildOrder)
  532. assert.Equal(t, 2, pip.Stages[1].BuildOrder)
  533. assert.Equal(t, "This is the second stage. It has 2 jobs", pip.Stages[0].Name)
  534. assert.Equal(t, "This is the first stage. It has 2 jobs", pip.Stages[1].Name)
  535. },
  536. }
  537. var test9 = testcase{
  538. name: "Invalid stage",
  539. wantErr: true,
  540. args: args{
  541. u: u,
  542. pkey: sdk.RandomString(7),
  543. pip: &sdk.Pipeline{},
  544. },
  545. setup: func(t *testing.T, args args) {
  546. proj := assets.InsertTestProject(t, db, cache, args.pkey, args.pkey)
  547. args.pip.Name = proj.Key + "_PIP"
  548. args.pip.ProjectID = proj.ID
  549. args.pip.ProjectKey = proj.Key
  550. test.NoError(t, pipeline.InsertPipeline(db, args.pip))
  551. args.pip.Parameter = []sdk.Parameter{
  552. {Name: "test", Value: "test_value", Type: sdk.StringParameter, Description: "test_description"},
  553. }
  554. args.pip.Stages = []sdk.Stage{
  555. {
  556. BuildOrder: 1,
  557. Enabled: true,
  558. PipelineID: args.pip.ID,
  559. Name: "",
  560. Jobs: []sdk.Job{
  561. {
  562. Enabled: true,
  563. Action: sdk.Action{
  564. Name: "Job n°1",
  565. },
  566. },
  567. },
  568. },
  569. {
  570. BuildOrder: 2,
  571. Enabled: true,
  572. PipelineID: args.pip.ID,
  573. Name: "This is the second stage. It has 2 jobs",
  574. Jobs: []sdk.Job{
  575. {
  576. Enabled: true,
  577. Action: sdk.Action{
  578. Name: "Job n°1",
  579. },
  580. },
  581. {
  582. Enabled: true,
  583. Action: sdk.Action{
  584. Name: "Job n°2",
  585. },
  586. },
  587. },
  588. },
  589. }
  590. test.NoError(t, pipeline.InsertStage(db, &args.pip.Stages[0]))
  591. args.pip.Stages[0].BuildOrder = 1
  592. },
  593. asserts: func(t *testing.T, pip sdk.Pipeline) {
  594. t.Logf("Asserts on %+v", pip)
  595. assert.Equal(t, 0, len(pip.Stages))
  596. },
  597. }
  598. //Run the tests
  599. var tests = []testcase{test1, test2, test3, test4, test5, test6, test7, test8, test9}
  600. for _, tt := range tests {
  601. testImportUpdate(t, db, cache, tt)
  602. }
  603. }