/engine/api/workflow/workflow_run_event_test.go

https://github.com/ovh/cds · Go · 572 lines · 496 code · 56 blank · 20 comment · 13 complexity · 5417fe5b48586e7dce0109f38f91a374 MD5 · raw file

  1. package workflow_test
  2. import (
  3. "context"
  4. "github.com/go-gorp/gorp"
  5. "github.com/golang/mock/gomock"
  6. "github.com/ovh/cds/engine/api/services/mock_services"
  7. "net/http"
  8. "testing"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/ovh/cds/engine/api/application"
  11. "github.com/ovh/cds/engine/api/repositoriesmanager"
  12. "github.com/ovh/cds/engine/api/services"
  13. "github.com/ovh/cds/engine/api/test"
  14. "github.com/ovh/cds/engine/api/test/assets"
  15. "github.com/ovh/cds/engine/api/workflow"
  16. "github.com/ovh/cds/sdk"
  17. )
  18. // Test ResyncCommitStatus with a notification where all is disabled.
  19. // Must: no error returned, only list status is called
  20. func TestResyncCommitStatusNotifDisabled(t *testing.T) {
  21. db, cache := test.SetupPG(t)
  22. ctx := context.TODO()
  23. pkey := sdk.RandomString(10)
  24. proj := assets.InsertTestProject(t, db, cache, pkey, pkey)
  25. vcsServer := sdk.ProjectVCSServerLink{
  26. ProjectID: proj.ID,
  27. Name: "gerrit",
  28. }
  29. vcsServer.Set("token", "foo")
  30. vcsServer.Set("secret", "bar")
  31. assert.NoError(t, repositoriesmanager.InsertProjectVCSServerLink(context.TODO(), db, &vcsServer))
  32. // Create Application
  33. app := sdk.Application{
  34. Name: sdk.RandomString(10),
  35. ProjectID: proj.ID,
  36. RepositoryFullname: "foo/myrepo",
  37. VCSServer: "gerrit",
  38. RepositoryStrategy: sdk.RepositoryStrategy{
  39. ConnectionType: "ssh",
  40. },
  41. }
  42. assert.NoError(t, application.Insert(db, *proj, &app))
  43. assert.NoError(t, repositoriesmanager.InsertForApplication(db, &app))
  44. tr := true
  45. wr := &sdk.WorkflowRun{
  46. WorkflowNodeRuns: map[int64][]sdk.WorkflowNodeRun{
  47. 1: {
  48. {
  49. ID: 1,
  50. ApplicationID: app.ID,
  51. Status: sdk.StatusSuccess,
  52. WorkflowNodeID: 1,
  53. VCSHash: "6c3efde",
  54. },
  55. },
  56. },
  57. Workflow: sdk.Workflow{
  58. WorkflowData: sdk.WorkflowData{
  59. Node: sdk.Node{
  60. ID: 1,
  61. Context: &sdk.NodeContext{
  62. ApplicationID: app.ID,
  63. },
  64. },
  65. },
  66. Applications: map[int64]sdk.Application{
  67. app.ID: app,
  68. },
  69. Notifications: []sdk.WorkflowNotification{
  70. {
  71. Settings: sdk.UserNotificationSettings{
  72. Template: &sdk.UserNotificationTemplate{
  73. DisableComment: &tr,
  74. DisableStatus: &tr,
  75. },
  76. },
  77. Type: "vcs",
  78. },
  79. },
  80. },
  81. }
  82. allSrv, err := services.LoadAll(context.TODO(), db)
  83. for _, s := range allSrv {
  84. if err := services.Delete(db, &s); err != nil {
  85. t.Fatalf("unable to delete service: %v", err)
  86. }
  87. }
  88. // Setup a mock for all services called by the API
  89. ctrl := gomock.NewController(t)
  90. defer ctrl.Finish()
  91. servicesClients := mock_services.NewMockClient(ctrl)
  92. services.NewClient = func(_ gorp.SqlExecutor, _ []sdk.Service) services.Client {
  93. return servicesClients
  94. }
  95. defer func() {
  96. services.NewClient = services.NewDefaultClient
  97. }()
  98. servicesClients.EXPECT().
  99. DoJSONRequest(gomock.Any(), "GET", "/vcs/gerrit/repos/foo/myrepo/commits/6c3efde/statuses",
  100. gomock.Any(), gomock.Any(), gomock.Any()).
  101. Return(nil, 201, nil)
  102. err = workflow.ResyncCommitStatus(ctx, db.DbMap, cache, *proj, wr)
  103. assert.NoError(t, err)
  104. }
  105. // Test TestResyncCommitStatusSetStatus with a notification where all is disabled.
  106. // Must: no error returned, setStatus must be called
  107. func TestResyncCommitStatusSetStatus(t *testing.T) {
  108. db, cache := test.SetupPG(t)
  109. ctx := context.TODO()
  110. pkey := sdk.RandomString(10)
  111. proj := assets.InsertTestProject(t, db, cache, pkey, pkey)
  112. vcsServer := sdk.ProjectVCSServerLink{
  113. ProjectID: proj.ID,
  114. Name: "gerrit",
  115. }
  116. vcsServer.Set("token", "foo")
  117. vcsServer.Set("secret", "bar")
  118. assert.NoError(t, repositoriesmanager.InsertProjectVCSServerLink(context.TODO(), db, &vcsServer))
  119. // Create Application
  120. app := sdk.Application{
  121. Name: sdk.RandomString(10),
  122. ProjectID: proj.ID,
  123. RepositoryFullname: "foo/myrepo",
  124. VCSServer: "gerrit",
  125. RepositoryStrategy: sdk.RepositoryStrategy{
  126. ConnectionType: "ssh",
  127. },
  128. }
  129. assert.NoError(t, application.Insert(db, *proj, &app))
  130. assert.NoError(t, repositoriesmanager.InsertForApplication(db, &app))
  131. tr := true
  132. wr := &sdk.WorkflowRun{
  133. WorkflowNodeRuns: map[int64][]sdk.WorkflowNodeRun{
  134. 1: {
  135. {
  136. ID: 1,
  137. ApplicationID: app.ID,
  138. Status: sdk.StatusSuccess,
  139. WorkflowNodeID: 1,
  140. VCSHash: "6c3efde",
  141. },
  142. },
  143. },
  144. Workflow: sdk.Workflow{
  145. WorkflowData: sdk.WorkflowData{
  146. Node: sdk.Node{
  147. ID: 1,
  148. Context: &sdk.NodeContext{
  149. ApplicationID: app.ID,
  150. },
  151. },
  152. },
  153. Applications: map[int64]sdk.Application{
  154. app.ID: app,
  155. },
  156. Notifications: []sdk.WorkflowNotification{
  157. {
  158. Settings: sdk.UserNotificationSettings{
  159. Template: &sdk.UserNotificationTemplate{
  160. DisableComment: &tr,
  161. },
  162. },
  163. Type: "vcs",
  164. },
  165. },
  166. },
  167. }
  168. // Setup a mock for all services called by the API
  169. ctrl := gomock.NewController(t)
  170. defer ctrl.Finish()
  171. servicesClients := mock_services.NewMockClient(ctrl)
  172. services.NewClient = func(_ gorp.SqlExecutor, _ []sdk.Service) services.Client {
  173. return servicesClients
  174. }
  175. defer func() {
  176. services.NewClient = services.NewDefaultClient
  177. }()
  178. servicesClients.EXPECT().
  179. DoJSONRequest(gomock.Any(), "GET", "/vcs/gerrit/repos/foo/myrepo/commits/6c3efde/statuses",
  180. gomock.Any(), gomock.Any(), gomock.Any()).
  181. Return(nil, 201, nil).MaxTimes(1)
  182. servicesClients.EXPECT().
  183. DoJSONRequest(gomock.Any(), "GET", "/vcs/gerrit",
  184. gomock.Any(), gomock.Any()).
  185. DoAndReturn(func(ctx context.Context, method, path string, in interface{}, out interface{}) (http.Header, int, error) {
  186. vcs := sdk.VCSConfiguration{Type: "gerrit"}
  187. *(out.(*sdk.VCSConfiguration)) = vcs
  188. return nil, 200, nil
  189. }).MaxTimes(1)
  190. servicesClients.EXPECT().
  191. DoJSONRequest(gomock.Any(), "POST", "/vcs/gerrit/status",
  192. gomock.Any(), gomock.Any(), gomock.Any()).
  193. Return(nil, 201, nil)
  194. err := workflow.ResyncCommitStatus(ctx, db.DbMap, cache, *proj, wr)
  195. assert.NoError(t, err)
  196. }
  197. // Test TestResyncCommitStatusCommentPR with a notification where all is disabled.
  198. // Must: no error returned, postComment must be called
  199. func TestResyncCommitStatusCommentPR(t *testing.T) {
  200. db, cache := test.SetupPG(t)
  201. ctx := context.TODO()
  202. pkey := sdk.RandomString(10)
  203. proj := assets.InsertTestProject(t, db, cache, pkey, pkey)
  204. vcsServer := sdk.ProjectVCSServerLink{
  205. ProjectID: proj.ID,
  206. Name: "gerrit",
  207. }
  208. vcsServer.Set("token", "foo")
  209. vcsServer.Set("secret", "bar")
  210. assert.NoError(t, repositoriesmanager.InsertProjectVCSServerLink(context.TODO(), db, &vcsServer))
  211. // Create Application
  212. app := sdk.Application{
  213. Name: sdk.RandomString(10),
  214. ProjectID: proj.ID,
  215. RepositoryFullname: "foo/myrepo",
  216. VCSServer: "gerrit",
  217. RepositoryStrategy: sdk.RepositoryStrategy{
  218. ConnectionType: "ssh",
  219. },
  220. }
  221. assert.NoError(t, application.Insert(db, *proj, &app))
  222. assert.NoError(t, repositoriesmanager.InsertForApplication(db, &app))
  223. tr := true
  224. fls := false
  225. wr := &sdk.WorkflowRun{
  226. WorkflowNodeRuns: map[int64][]sdk.WorkflowNodeRun{
  227. 1: {
  228. {
  229. ID: 1,
  230. ApplicationID: app.ID,
  231. Status: sdk.StatusFail,
  232. WorkflowNodeID: 1,
  233. VCSHash: "6c3efde",
  234. BuildParameters: []sdk.Parameter{
  235. {
  236. Name: "gerrit.change.id",
  237. Type: "string",
  238. Value: "MyGerritChangeId",
  239. },
  240. },
  241. },
  242. },
  243. },
  244. Workflow: sdk.Workflow{
  245. WorkflowData: sdk.WorkflowData{
  246. Node: sdk.Node{
  247. ID: 1,
  248. Context: &sdk.NodeContext{
  249. ApplicationID: app.ID,
  250. },
  251. },
  252. },
  253. Applications: map[int64]sdk.Application{
  254. app.ID: app,
  255. },
  256. Notifications: []sdk.WorkflowNotification{
  257. {
  258. Settings: sdk.UserNotificationSettings{
  259. Template: &sdk.UserNotificationTemplate{
  260. DisableComment: &fls,
  261. DisableStatus: &tr,
  262. Body: "MyTemplate",
  263. },
  264. },
  265. Type: "vcs",
  266. },
  267. },
  268. },
  269. }
  270. // Setup a mock for all services called by the API
  271. ctrl := gomock.NewController(t)
  272. defer ctrl.Finish()
  273. servicesClients := mock_services.NewMockClient(ctrl)
  274. services.NewClient = func(_ gorp.SqlExecutor, _ []sdk.Service) services.Client {
  275. return servicesClients
  276. }
  277. defer func() {
  278. services.NewClient = services.NewDefaultClient
  279. }()
  280. servicesClients.EXPECT().
  281. DoJSONRequest(gomock.Any(), "GET", "/vcs/gerrit/repos/foo/myrepo/commits/6c3efde/statuses",
  282. gomock.Any(), gomock.Any(), gomock.Any()).
  283. Return(nil, 201, nil).MaxTimes(1)
  284. servicesClients.EXPECT().
  285. DoJSONRequest(gomock.Any(), "GET", "/vcs/gerrit",
  286. gomock.Any(), gomock.Any()).
  287. DoAndReturn(func(ctx context.Context, method, path string, in interface{}, out interface{}) (http.Header, int, error) {
  288. vcs := sdk.VCSConfiguration{Type: "gerrit"}
  289. *(out.(*sdk.VCSConfiguration)) = vcs
  290. return nil, 200, nil
  291. }).MaxTimes(1)
  292. servicesClients.EXPECT().
  293. DoJSONRequest(gomock.Any(), "POST", "/vcs/gerrit/repos/foo/myrepo/pullrequests/comments",
  294. gomock.Any(), gomock.Any(), gomock.Any()).
  295. DoAndReturn(func(ctx context.Context, method, path string, in interface{}, out interface{}, _ interface{}) (http.Header, int, error) {
  296. assert.Equal(t, in.(sdk.VCSPullRequestCommentRequest).ChangeID, "MyGerritChangeId")
  297. assert.Equal(t, in.(sdk.VCSPullRequestCommentRequest).Message, "MyTemplate")
  298. return nil, 200, nil
  299. }).MaxTimes(1)
  300. err := workflow.ResyncCommitStatus(ctx, db.DbMap, cache, *proj, wr)
  301. assert.NoError(t, err)
  302. }
  303. // Test TestResyncCommitStatusCommentPRNotTerminated with a notification where all is disabled.
  304. // Must: no error returned, postComment must be called
  305. func TestResyncCommitStatusCommentPRNotTerminated(t *testing.T) {
  306. db, cache := test.SetupPG(t)
  307. ctx := context.TODO()
  308. pkey := sdk.RandomString(10)
  309. proj := assets.InsertTestProject(t, db, cache, pkey, pkey)
  310. vcsServer := sdk.ProjectVCSServerLink{
  311. ProjectID: proj.ID,
  312. Name: "gerrit",
  313. }
  314. vcsServer.Set("token", "foo")
  315. vcsServer.Set("secret", "bar")
  316. assert.NoError(t, repositoriesmanager.InsertProjectVCSServerLink(context.TODO(), db, &vcsServer))
  317. // Create Application
  318. app := sdk.Application{
  319. Name: sdk.RandomString(10),
  320. ProjectID: proj.ID,
  321. RepositoryFullname: "foo/myrepo",
  322. VCSServer: "gerrit",
  323. RepositoryStrategy: sdk.RepositoryStrategy{
  324. ConnectionType: "ssh",
  325. },
  326. }
  327. assert.NoError(t, application.Insert(db, *proj, &app))
  328. assert.NoError(t, repositoriesmanager.InsertForApplication(db, &app))
  329. tr := true
  330. fls := false
  331. wr := &sdk.WorkflowRun{
  332. WorkflowNodeRuns: map[int64][]sdk.WorkflowNodeRun{
  333. 1: {
  334. {
  335. ID: 1,
  336. ApplicationID: app.ID,
  337. Status: sdk.StatusBuilding,
  338. WorkflowNodeID: 1,
  339. VCSHash: "6c3efde",
  340. BuildParameters: []sdk.Parameter{
  341. {
  342. Name: "gerrit.change.id",
  343. Type: "string",
  344. Value: "MyGerritChangeId",
  345. },
  346. },
  347. },
  348. },
  349. },
  350. Workflow: sdk.Workflow{
  351. WorkflowData: sdk.WorkflowData{
  352. Node: sdk.Node{
  353. ID: 1,
  354. Context: &sdk.NodeContext{
  355. ApplicationID: app.ID,
  356. },
  357. },
  358. },
  359. Applications: map[int64]sdk.Application{
  360. app.ID: app,
  361. },
  362. Notifications: []sdk.WorkflowNotification{
  363. {
  364. Settings: sdk.UserNotificationSettings{
  365. Template: &sdk.UserNotificationTemplate{
  366. DisableComment: &fls,
  367. DisableStatus: &tr,
  368. Body: "MyTemplate",
  369. },
  370. },
  371. Type: "vcs",
  372. },
  373. },
  374. },
  375. }
  376. // Setup a mock for all services called by the API
  377. ctrl := gomock.NewController(t)
  378. defer ctrl.Finish()
  379. servicesClients := mock_services.NewMockClient(ctrl)
  380. services.NewClient = func(_ gorp.SqlExecutor, _ []sdk.Service) services.Client {
  381. return servicesClients
  382. }
  383. defer func() {
  384. services.NewClient = services.NewDefaultClient
  385. }()
  386. servicesClients.EXPECT().
  387. DoJSONRequest(gomock.Any(), "GET", "/vcs/gerrit/repos/foo/myrepo/commits/6c3efde/statuses",
  388. gomock.Any(), gomock.Any(), gomock.Any()).
  389. Return(nil, 201, nil).MaxTimes(1)
  390. servicesClients.EXPECT().
  391. DoJSONRequest(gomock.Any(), "GET", "/vcs/gerrit",
  392. gomock.Any(), gomock.Any()).
  393. DoAndReturn(func(ctx context.Context, method, path string, in interface{}, out interface{}) (http.Header, int, error) {
  394. vcs := sdk.VCSConfiguration{Type: "gerrit"}
  395. *(out.(*sdk.VCSConfiguration)) = vcs
  396. return nil, 200, nil
  397. }).MaxTimes(1)
  398. err := workflow.ResyncCommitStatus(ctx, db.DbMap, cache, *proj, wr)
  399. assert.NoError(t, err)
  400. }
  401. // Test TestResyncCommitStatus with a notification where all is disabled.
  402. // Must: no error returned, postComment must be called
  403. func TestResyncCommitStatusCommitCache(t *testing.T) {
  404. db, cache := test.SetupPG(t)
  405. ctx := context.TODO()
  406. pkey := sdk.RandomString(10)
  407. proj := assets.InsertTestProject(t, db, cache, pkey, pkey)
  408. vcsServer := sdk.ProjectVCSServerLink{
  409. ProjectID: proj.ID,
  410. Name: "gerrit",
  411. }
  412. vcsServer.Set("token", "foo")
  413. vcsServer.Set("secret", "bar")
  414. assert.NoError(t, repositoriesmanager.InsertProjectVCSServerLink(context.TODO(), db, &vcsServer))
  415. // Create Application
  416. app := sdk.Application{
  417. Name: sdk.RandomString(10),
  418. ProjectID: proj.ID,
  419. RepositoryFullname: "foo/myrepo",
  420. VCSServer: "gerrit",
  421. RepositoryStrategy: sdk.RepositoryStrategy{
  422. ConnectionType: "ssh",
  423. },
  424. }
  425. assert.NoError(t, application.Insert(db, *proj, &app))
  426. assert.NoError(t, repositoriesmanager.InsertForApplication(db, &app))
  427. tr := true
  428. fls := false
  429. wr := &sdk.WorkflowRun{
  430. WorkflowNodeRuns: map[int64][]sdk.WorkflowNodeRun{
  431. 1: {
  432. {
  433. ID: 1,
  434. ApplicationID: app.ID,
  435. Status: sdk.StatusFail,
  436. WorkflowNodeID: 1,
  437. VCSHash: "6c3efde",
  438. BuildParameters: []sdk.Parameter{
  439. {
  440. Name: "gerrit.change.id",
  441. Type: "string",
  442. Value: "MyGerritChangeId",
  443. },
  444. },
  445. },
  446. },
  447. },
  448. Workflow: sdk.Workflow{
  449. WorkflowData: sdk.WorkflowData{
  450. Node: sdk.Node{
  451. ID: 1,
  452. Context: &sdk.NodeContext{
  453. ApplicationID: app.ID,
  454. },
  455. },
  456. },
  457. Applications: map[int64]sdk.Application{
  458. app.ID: app,
  459. },
  460. Notifications: []sdk.WorkflowNotification{
  461. {
  462. Settings: sdk.UserNotificationSettings{
  463. Template: &sdk.UserNotificationTemplate{
  464. DisableComment: &fls,
  465. DisableStatus: &tr,
  466. Body: "MyTemplate",
  467. },
  468. },
  469. Type: "vcs",
  470. },
  471. },
  472. },
  473. }
  474. // Setup a mock for all services called by the API
  475. ctrl := gomock.NewController(t)
  476. defer ctrl.Finish()
  477. servicesClients := mock_services.NewMockClient(ctrl)
  478. services.NewClient = func(_ gorp.SqlExecutor, _ []sdk.Service) services.Client {
  479. return servicesClients
  480. }
  481. defer func() {
  482. services.NewClient = services.NewDefaultClient
  483. }()
  484. servicesClients.EXPECT().
  485. DoJSONRequest(gomock.Any(), "GET", "/vcs/gerrit/repos/foo/myrepo/commits/6c3efde/statuses",
  486. gomock.Any(), gomock.Any(), gomock.Any()).
  487. DoAndReturn(func(ctx context.Context, method, path string, in interface{}, out interface{}, args ...interface{}) (http.Header, int, error) {
  488. ss := []sdk.VCSCommitStatus{
  489. {
  490. State: "Success",
  491. Ref: "6c3efde",
  492. },
  493. }
  494. *(out.(*[]sdk.VCSCommitStatus)) = ss
  495. return nil, 200, nil
  496. }).MaxTimes(1)
  497. servicesClients.EXPECT().
  498. DoJSONRequest(gomock.Any(), "GET", "/vcs/gerrit",
  499. gomock.Any(), gomock.Any()).
  500. DoAndReturn(func(ctx context.Context, method, path string, in interface{}, out interface{}) (http.Header, int, error) {
  501. vcs := sdk.VCSConfiguration{Type: "gerrit"}
  502. *(out.(*sdk.VCSConfiguration)) = vcs
  503. return nil, 200, nil
  504. }).MaxTimes(1)
  505. servicesClients.EXPECT().
  506. DoJSONRequest(gomock.Any(), "POST", "/vcs/gerrit/repos/foo/myrepo/pullrequests/comments",
  507. gomock.Any(), gomock.Any(), gomock.Any()).
  508. DoAndReturn(func(ctx context.Context, method, path string, in interface{}, out interface{}, _ interface{}) (http.Header, int, error) {
  509. assert.Equal(t, in.(sdk.VCSPullRequestCommentRequest).ChangeID, "MyGerritChangeId")
  510. assert.Equal(t, in.(sdk.VCSPullRequestCommentRequest).Message, "MyTemplate")
  511. return nil, 200, nil
  512. }).MaxTimes(1)
  513. e := workflow.VCSEventMessenger{}
  514. err := e.SendVCSEvent(ctx, db.DbMap, cache, *proj, *wr, wr.WorkflowNodeRuns[1][0])
  515. assert.NoError(t, err)
  516. }