|
| 1 | +/* |
| 2 | +Licensed to the Apache Software Foundation (ASF) under one or more |
| 3 | +contributor license agreements. See the NOTICE file distributed with |
| 4 | +this work for additional information regarding copyright ownership. |
| 5 | +The ASF licenses this file to You under the Apache License, Version 2.0 |
| 6 | +(the "License"); you may not use this file except in compliance with |
| 7 | +the License. You may obtain a copy of the License at |
| 8 | +
|
| 9 | + http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | +
|
| 11 | +Unless required by applicable law or agreed to in writing, software |
| 12 | +distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | +See the License for the specific language governing permissions and |
| 15 | +limitations under the License. |
| 16 | +*/ |
| 17 | + |
| 18 | +package e2e |
| 19 | + |
| 20 | +import ( |
| 21 | + "reflect" |
| 22 | + "sort" |
| 23 | + "testing" |
| 24 | + |
| 25 | + "github.com/apache/incubator-devlake/helpers/e2ehelper" |
| 26 | + "github.com/apache/incubator-devlake/helpers/pluginhelper/api" |
| 27 | + "github.com/apache/incubator-devlake/plugins/circleci/impl" |
| 28 | + "github.com/apache/incubator-devlake/plugins/circleci/models" |
| 29 | + "github.com/apache/incubator-devlake/plugins/circleci/tasks" |
| 30 | + "github.com/stretchr/testify/assert" |
| 31 | +) |
| 32 | + |
| 33 | +// TestCircleciUnfinishedJobsInputIterator is a regression test for |
| 34 | +// https://github.com/apache/devlake/issues/8907. The "collect unfinished job |
| 35 | +// details" collector builds its URL from "/v2/workflow/{{ .Input.Id }}/job" while |
| 36 | +// scanning rows into a models.CircleciJob. Its input query must therefore expose the |
| 37 | +// workflow id in the row's Id field; a bare "DISTINCT workflow_id" left Id empty and |
| 38 | +// produced "/v2/workflow//job" (HTTP 500). This test runs the production query |
| 39 | +// (tasks.UnfinishedJobsInputClauses) through the real iterator and asserts each |
| 40 | +// yielded row's Id is the workflow id, that results are DISTINCT, and that the |
| 41 | +// status/connection filters hold. |
| 42 | +func TestCircleciUnfinishedJobsInputIterator(t *testing.T) { |
| 43 | + var circleci impl.Circleci |
| 44 | + dataflowTester := e2ehelper.NewDataFlowTester(t, "circleci", circleci) |
| 45 | + |
| 46 | + const projectSlug = "github/test/repo" |
| 47 | + dataflowTester.FlushTabler(&models.CircleciJob{}) |
| 48 | + |
| 49 | + seed := []models.CircleciJob{ |
| 50 | + {ConnectionId: 1, WorkflowId: "wf-onhold", Id: "job-1", ProjectSlug: projectSlug, Status: "on_hold"}, |
| 51 | + {ConnectionId: 1, WorkflowId: "wf-onhold", Id: "job-2", ProjectSlug: projectSlug, Status: "running"}, // same workflow -> DISTINCT |
| 52 | + {ConnectionId: 1, WorkflowId: "wf-queued", Id: "job-3", ProjectSlug: projectSlug, Status: "queued"}, |
| 53 | + {ConnectionId: 1, WorkflowId: "wf-success", Id: "job-4", ProjectSlug: projectSlug, Status: "success"}, // terminal -> excluded |
| 54 | + {ConnectionId: 2, WorkflowId: "wf-otherconn", Id: "job-5", ProjectSlug: projectSlug, Status: "on_hold"}, // other connection -> excluded |
| 55 | + } |
| 56 | + for i := range seed { |
| 57 | + assert.Nil(t, dataflowTester.Dal.Create(&seed[i])) |
| 58 | + } |
| 59 | + |
| 60 | + cursor, err := dataflowTester.Dal.Cursor(tasks.UnfinishedJobsInputClauses(1, projectSlug)...) |
| 61 | + assert.Nil(t, err) |
| 62 | + iter, err := api.NewDalCursorIterator(dataflowTester.Dal, cursor, reflect.TypeOf(models.CircleciJob{})) |
| 63 | + assert.Nil(t, err) |
| 64 | + defer iter.Close() |
| 65 | + |
| 66 | + var ids []string |
| 67 | + for iter.HasNext() { |
| 68 | + item, err := iter.Fetch() |
| 69 | + assert.Nil(t, err) |
| 70 | + job := item.(*models.CircleciJob) |
| 71 | + ids = append(ids, job.Id) |
| 72 | + } |
| 73 | + sort.Strings(ids) |
| 74 | + |
| 75 | + // Distinct workflow ids for connection 1's non-terminal jobs, with Id populated |
| 76 | + // (the URL template reads .Input.Id). wf-success (terminal) and wf-otherconn |
| 77 | + // (connection 2) are excluded. |
| 78 | + assert.Equal(t, []string{"wf-onhold", "wf-queued"}, ids) |
| 79 | + for _, id := range ids { |
| 80 | + assert.NotEmpty(t, id, "Input.Id must be the workflow id, not empty (#8907)") |
| 81 | + } |
| 82 | +} |
0 commit comments