diff --git a/go.sum b/go.sum index 9bab81710b25d1b47a9c65371a711941915fe586..b0e85faf5b0738a5528a55fc002e3439797d93b6 100644 --- a/go.sum +++ b/go.sum @@ -661,6 +661,7 @@ github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jW github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/thanos-io/thanos v0.13.1-0.20200910143741-e0b7f7b32e9c/go.mod h1:1IzeMKiS+pvxbG2M6ZJyi8ZHaAQKXNjDbP2gjhPbSXE= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= @@ -795,6 +796,7 @@ gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= helm.sh/helm/v3 v3.3.0 h1:7BUpW5NI1pauKDnIh0ju53pNc3Ra/UyqqBr0b5OgBwY= helm.sh/helm/v3 v3.3.0/go.mod h1:cWRDbGk4EiIL0/+jN0GI8T7m96Cps81/ta1kcacl85g= diff --git a/pkg/simple/client/devops/jenkins/pipeline.go b/pkg/simple/client/devops/jenkins/pipeline.go index 0e68fa5450926eaec7de33f751f27ab567161c0b..7aeae2c03f7e198d7c2da651917fae7c743b7d65 100644 --- a/pkg/simple/client/devops/jenkins/pipeline.go +++ b/pkg/simple/client/devops/jenkins/pipeline.go @@ -25,6 +25,7 @@ import ( "kubesphere.io/kubesphere/pkg/simple/client/devops" "net/http" "net/url" + "strconv" "strings" "time" ) @@ -170,34 +171,88 @@ func (p *Pipeline) GetPipelineRun() (*devops.PipelineRun, error) { } func (p *Pipeline) ListPipelineRuns() (*devops.PipelineRunList, error) { - res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters) + // please don't remove below code lines until blueocen fixed + //res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters) + //if err != nil { + // klog.Error(err) + // return nil, err + //} + // + //var pipelineRunList devops.PipelineRunList + //err = json.Unmarshal(res, &pipelineRunList.Items) + //if err != nil { + // klog.Error(err) + // return nil, err + //} + //total, err := p.searchPipelineRunsCount() + //if err != nil { + // klog.Error(err) + // return nil, err + //} + //pipelineRunList.Total = total + //return &pipelineRunList, err + return p.listPipelineRunsByLocalPaging() +} + +// listPipelineRunsByLocalPaging should be a temporary solution +// see also https://github.com/kubesphere/kubesphere/issues/3507 +func (p *Pipeline) listPipelineRunsByLocalPaging() (runList *devops.PipelineRunList, err error) { + desiredStart, desiredLimit := p.parsePaging() + + var pageUrl *url.URL // get all Pipeline runs + if pageUrl, err = p.resetPaging(0, 10000); err != nil { + return + } + res, err := p.Jenkins.SendPureRequest(pageUrl.Path, p.HttpParameters) if err != nil { klog.Error(err) return nil, err } - var pipelineRunList devops.PipelineRunList - err = json.Unmarshal(res, &pipelineRunList.Items) - if err != nil { - klog.Error(err) - return nil, err + runList = &devops.PipelineRunList{ + Items: make([]devops.PipelineRun, 0), } - total, err := p.searchPipelineRunsCount() - if err != nil { + if err = json.Unmarshal(res, &runList.Items); err != nil { klog.Error(err) return nil, err } - pipelineRunList.Total = total - return &pipelineRunList, err + + // set the total count number + runList.Total = len(runList.Items) + + // keep the desired data/ + if desiredStart+1 >= runList.Total { + // beyond the boundary, return an empty + return + } + + endIndex := runList.Total + if desiredStart+desiredLimit < endIndex { + endIndex = desiredStart + desiredLimit + } + runList.Items = runList.Items[desiredStart:endIndex] + return } -func (p *Pipeline) searchPipelineRunsCount() (int, error) { +// resetPaging reset the paging setting from request, support start, limit +func (p *Pipeline) resetPaging(start, limit int) (path *url.URL, err error) { query, _ := ParseJenkinsQuery(p.HttpParameters.Url.RawQuery) - query.Set("start", "0") - query.Set("limit", "1000") - query.Set("depth", "-1") + query.Set("start", strconv.Itoa(start)) + query.Set("limit", strconv.Itoa(limit)) p.HttpParameters.Url.RawQuery = query.Encode() - u, err := url.Parse(p.Path) + path, err = url.Parse(p.Path) + return +} + +func (p *Pipeline) parsePaging() (start, limit int) { + query, _ := ParseJenkinsQuery(p.HttpParameters.Url.RawQuery) + start, _ = strconv.Atoi(query.Get("start")) + limit, _ = strconv.Atoi(query.Get("limit")) + return +} + +func (p *Pipeline) searchPipelineRunsCount() (int, error) { + u, err := p.resetPaging(0, 1000) if err != nil { return 0, err } diff --git a/pkg/simple/client/devops/jenkins/pipeline_test.go b/pkg/simple/client/devops/jenkins/pipeline_test.go new file mode 100644 index 0000000000000000000000000000000000000000..ca4bca6e39cb220d50b059a9d97bece0345e8904 --- /dev/null +++ b/pkg/simple/client/devops/jenkins/pipeline_test.go @@ -0,0 +1,106 @@ +package jenkins + +import ( + "fmt" + "github.com/stretchr/testify/assert" + "kubesphere.io/kubesphere/pkg/simple/client/devops" + "net/url" + "strconv" + "testing" +) + +func TestResetPaging(t *testing.T) { + table := []struct { + path string + rawQuery string + start int + limit int + hasErr bool + message string + }{{ + start: 0, + limit: 10, + hasErr: false, + message: "without query, should no errors", + }, { + path: "/fake/path", + rawQuery: "?start=1&limit1", + start: 0, + limit: 10, + hasErr: false, + message: "without a query", + }, { + path: "/fake/path", + rawQuery: "?start=1&limit1", + start: 3, + limit: 13, + hasErr: false, + message: "without a query", + }} + + for index, item := range table { + pip := &Pipeline{ + Path: item.path, + HttpParameters: &devops.HttpParameters{ + Url: &url.URL{ + Path: item.path, + RawQuery: item.rawQuery, + }, + }, + } + + resultPath, err := pip.resetPaging(item.start, item.limit) + if item.hasErr { + assert.NotNil(t, err, printTestMessage(index, item.message)) + } else { + assert.Nil(t, err, printTestMessage(index, item.message)) + + assert.Equal(t, item.path, resultPath.Path, printTestMessage(index, item.message)) + assert.Equal(t, strconv.Itoa(item.start), pip.HttpParameters.Url.Query().Get("start"), + printTestMessage(index, item.message)) + assert.Equal(t, strconv.Itoa(item.limit), pip.HttpParameters.Url.Query().Get("limit"), + printTestMessage(index, item.message)) + } + } +} + +func TestParsePaging(t *testing.T) { + table := []struct { + targetUrl string + start int + limit int + message string + }{{ + targetUrl: "http://localhost?start=0&limit=0", + start: 0, + limit: 0, + message: "should be success", + }, { + targetUrl: "http://localhost?start=1&limit=10", + start: 1, + limit: 10, + message: "should be success", + }, { + targetUrl: "http://localhost?start=5&limit=55", + start: 5, + limit: 55, + message: "should be success", + }} + + for index, item := range table { + pipUrl, _ := url.Parse(item.targetUrl) + pip := &Pipeline{ + HttpParameters: &devops.HttpParameters{ + Url: pipUrl, + }, + } + resultStart, resultLimit := pip.parsePaging() + + assert.Equal(t, item.start, resultStart, printTestMessage(index, item.message)) + assert.Equal(t, item.limit, resultLimit, printTestMessage(index, item.message)) + } +} + +func printTestMessage(index int, message string) string { + return fmt.Sprintf("index: %d, message: %s", index, message) +}