Skip to content

Commit

Permalink
add view (#8)
Browse files Browse the repository at this point in the history
* add view
  • Loading branch information
joelee2012 authored Feb 11, 2022
1 parent 0c2df71 commit b865ab1
Show file tree
Hide file tree
Showing 12 changed files with 343 additions and 70 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ build: ## build package
go build -v .

test: ## run test
env | sort
go test -race -coverprofile=coverage.out -covermode=atomic -v ./... | tee test.log
env | sort && \
go test -race -coverprofile=coverage.out -covermode=atomic -v ./... && \
go tool cover -html=coverage.out -o cover.html

fmt: ## format code
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ module github.com/joelee2012/go-jenkins
go 1.15

require (
github.com/imroc/req v0.3.0
github.com/imroc/req v0.3.2
github.com/stretchr/testify v1.7.0
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/imroc/req v0.3.0 h1:3EioagmlSG+z+KySToa+Ylo3pTFZs+jh3Brl7ngU12U=
github.com/imroc/req v0.3.0/go.mod h1:F+NZ+2EFSo6EFXdeIbpfE9hcC233id70kf0byW97Caw=
github.com/imroc/req v0.3.2 h1:M/JkeU6RPmX+WYvT2vaaOL0K+q8ufL5LxwvJc4xeB4o=
github.com/imroc/req v0.3.2/go.mod h1:F+NZ+2EFSo6EFXdeIbpfE9hcC233id70kf0byW97Caw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
25 changes: 18 additions & 7 deletions jenkins/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ func setupBuild(t *testing.T) *BuildItem {
return nil
})
assert.Nil(t, err)
assert.Nil(t, err)
assert.Contains(t, strings.Join(output, ""), os.Getenv("JENKINS_VERSION"))
return build
}
Expand Down Expand Up @@ -63,16 +62,16 @@ func TestBuildItemGetDescription(t *testing.T) {
}

func TestBuildItemDelete(t *testing.T) {
t.Skip()
build := setupBuild(t)
assert.NotNil(t, build)
assert.Nil(t, build.Delete())
build, err := pipeline.GetBuild(build.ID)
assert.Nil(t, err)
assert.Nil(t, build)
}

func TestStopBuildItem(t *testing.T) {
t.Skip()
// change config
conf := `<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="workflow-job">
<definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps">
Expand All @@ -81,11 +80,15 @@ func TestStopBuildItem(t *testing.T) {
</definition>
<disabled>false</disabled>
</flow-definition>`
assert.Nil(t, pipeline.SetConfigure(conf))

assert.Nil(t, folder.Create("sleep-pipeline", conf))
qitem, err := client.BuildJob("folder/sleep-pipeline", ReqParams{})
var build *BuildItem
// start build to sleep 20s
qitem, err := pipeline.Build(ReqParams{})
assert.Nil(t, err)
job, err := qitem.GetJob()
assert.Nil(t, err)
assert.Equal(t, job.FullName, pipeline.FullName)
var build *BuildItem
for {
time.Sleep(1 * time.Second)
build, err = qitem.GetBuild()
Expand All @@ -98,5 +101,13 @@ func TestStopBuildItem(t *testing.T) {
assert.Nil(t, err)
assert.True(t, building)
assert.Nil(t, build.Stop())

building, err = build.IsBuilding()
assert.Nil(t, err)
assert.False(t, building)
result, err := build.GetResult()
assert.Nil(t, err)
assert.Equal(t, result, "ABORTED")
// delete build and revert configure
assert.Nil(t, build.Delete())
assert.Nil(t, pipeline.SetConfigure(jobConf))
}
2 changes: 2 additions & 0 deletions jenkins/jenkins.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type Client struct {
Credentials *CredentialService
Nodes *NodeService
Queue *QueueService
Views *ViewService
}

type Crumb struct {
Expand All @@ -48,6 +49,7 @@ func NewClient(url, user, password string) (*Client, error) {
c.Credentials = NewCredentialService(c)
c.Nodes = NewNodeService(c)
c.Queue = NewQueueService(c)
c.Views = NewViewService(c)
return c, nil
}

Expand Down
90 changes: 81 additions & 9 deletions jenkins/jenkins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,48 @@ import (
"os"
"strings"
"testing"
"time"

"github.com/stretchr/testify/assert"
)

var (
client *Client
folder *JobItem
pipeline *JobItem
jobConf = `<?xml version='1.1' encoding='UTF-8'?>
client *Client
folder *JobItem
pipeline *JobItem
pipeline2 *JobItem
jobConf = `<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="workflow-job">
<definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps">
<script>echo &quot;JENKINS_VERSION&quot;</script>
<sandbox>true</sandbox>
</definition>
<disabled>false</disabled>
</flow-definition>`
paramsJobConf = `<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="workflow-job">
<description></description>
<keepDependencies>false</keepDependencies>
<properties>
<hudson.model.ParametersDefinitionProperty>
<parameterDefinitions>
<hudson.model.StringParameterDefinition>
<name>ARG1</name>
<trim>false</trim>
</hudson.model.StringParameterDefinition>
</parameterDefinitions>
</hudson.model.ParametersDefinitionProperty>
</properties>
<definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps">
<script>echo params.ARG1</script>
<sandbox>true</sandbox>
</definition>
<triggers/>
<disabled>false</disabled>
</flow-definition>`
folderConf = `<?xml version='1.0' encoding='UTF-8'?>
<com.cloudbees.hudson.plugins.folder.Folder>
<actions/>
<description></description>
<properties/>
<folderViews/>
<healthMetrics/>
Expand All @@ -37,6 +59,29 @@ var (
<password>user-password</password>
<description>user id for testing</description>
</com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>`

viewConf = `<?xml version="1.1" encoding="UTF-8"?>
<hudson.model.ListView>
<description>test</description>
<filterExecutors>false</filterExecutors>
<filterQueue>false</filterQueue>
<properties class="hudson.model.View$PropertyList"/>
<jobNames>
<comparator class="hudson.util.CaseInsensitiveComparator"/>
</jobNames>
<jobFilters/>
<columns>
<hudson.views.StatusColumn/>
<hudson.views.WeatherColumn/>
<hudson.views.JobColumn/>
<hudson.views.LastSuccessColumn/>
<hudson.views.LastFailureColumn/>
<hudson.views.LastDurationColumn/>
<hudson.views.BuildButtonColumn/>
<hudson.plugins.favorite.column.FavoriteColumn plugin="favorite@2.3.2"/>
</columns>
<recurse>false</recurse>
</hudson.model.ListView>`
)

func setup() error {
Expand All @@ -48,7 +93,7 @@ func setup() error {
}

jobConf = strings.ReplaceAll(jobConf, "JENKINS_VERSION", os.Getenv("JENKINS_VERSION"))
confs := []string{folderConf, folderConf, jobConf, jobConf}
confs := []string{folderConf, folderConf, jobConf, paramsJobConf}
names := []string{"folder", "folder/folder1", "folder/pipeline", "folder/pipeline2"}

for index, name := range names {
Expand All @@ -67,6 +112,11 @@ func setup() error {
if err != nil {
return err
}

pipeline2, err = client.GetJob("folder/pipeline2")
if err != nil {
return err
}
return nil
}

Expand Down Expand Up @@ -128,7 +178,7 @@ func TestUrl2Name(t *testing.T) {

func TestGetJob(t *testing.T) {
// check job exist
job, err := client.GetJob("folder/pipeline2")
job, err := client.GetJob(pipeline.FullName)
assert.Nil(t, err)
assert.Equal(t, job.Class, "WorkflowJob")

Expand All @@ -137,7 +187,7 @@ func TestGetJob(t *testing.T) {
assert.Nil(t, err)
assert.Nil(t, job)
// wrong path
job, err = client.GetJob("folder/pipeline2/notexist")
job, err = client.GetJob(pipeline.FullName + "/notexist")
assert.Nil(t, err)
assert.Nil(t, job)
}
Expand Down Expand Up @@ -180,7 +230,7 @@ func TestBuildJob(t *testing.T) {
assert.Contains(t, output, os.Getenv("JENKINS_VERSION"))

// test job.GetBuild
build1, err := pipeline.GetBuild(1)
build1, err := pipeline.GetBuild(build.ID)
assert.Nil(t, err)
assert.Equal(t, build, build1)

Expand All @@ -195,6 +245,28 @@ func TestBuildJob(t *testing.T) {
assert.Equal(t, build, build1)
}

func TestBuildJobWithParameters(t *testing.T) {
qitem, err := client.BuildJob(pipeline2.FullName, ReqParams{"ARG1": "ARG1_VALUE"})
var build *BuildItem
assert.Nil(t, err)
for {
time.Sleep(1 * time.Second)
build, err = qitem.GetBuild()
assert.Nil(t, err)
if build != nil {
break
}
}
var output []string
err = build.LoopProgressiveLog("text", func(line string) error {
output = append(output, line)
time.Sleep(1 * time.Second)
return nil
})
assert.Nil(t, err)
assert.Contains(t, strings.Join(output, ""), "ARG1_VALUE")
}

func TestSystemCredentials(t *testing.T) {
cm := client.Credentials
creds, err := cm.List()
Expand Down
49 changes: 24 additions & 25 deletions jenkins/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,18 @@ import (

type JobItem struct {
*Item
Credentials *CredentialService
Credentials *CredentialService
Views *ViewService
Name string
FullName string
FullDisplayName string
}

func NewJobItem(url, class string, client *Client) *JobItem {
j := &JobItem{Item: NewItem(url, class, client)}
j.Credentials = NewCredentialService(j)
j.Views = NewViewService(j)
j.setName()
return j
}

Expand All @@ -27,6 +33,7 @@ func (j *JobItem) Rename(name string) error {
}
url, _ := resp.Response().Location()
j.URL = appendSlash(url.String())
j.setName()
return nil
}

Expand All @@ -38,6 +45,7 @@ func (j *JobItem) Move(path string) error {
}
url, _ := resp.Response().Location()
j.URL = appendSlash(url.String())
j.setName()
return nil
}

Expand All @@ -56,12 +64,12 @@ func (j *JobItem) GetParent() (*JobItem, error) {
}

func (j *JobItem) GetConfigure() (string, error) {
resp, err := j.Request("GET", "/config.xml")
resp, err := j.Request("GET", "config.xml")
return resp.String(), err
}

func (j *JobItem) SetConfigure(xml string) error {
_, err := j.Request("POST", "/config.xml", req.BodyXML(xml))
_, err := j.Request("POST", "config.xml", req.BodyXML(xml))
return err
}

Expand All @@ -84,19 +92,10 @@ func (j *JobItem) IsBuildable() (bool, error) {
return job.Buildable, err
}

func (j *JobItem) GetName() string {
_, name := path.Split(strings.Trim(j.URL, "/"))
return name
}

func (j *JobItem) GetFullName() string {
fullname, _ := j.client.URL2Name(j.URL)
return fullname
}

func (j *JobItem) GetFullDisplayName() string {
fullname, _ := j.client.URL2Name(j.URL)
return strings.ReplaceAll(fullname, "/", " » ")
func (j *JobItem) setName() {
j.FullName, _ = j.client.URL2Name(j.URL)
_, j.Name = path.Split(j.FullName)
j.FullDisplayName = strings.ReplaceAll(j.FullName, "/", " » ")
}

func (j *JobItem) GetDescription() (string, error) {
Expand Down Expand Up @@ -202,31 +201,31 @@ func (j *JobItem) List(depth int) ([]*JobItem, error) {
}

func (j *JobItem) GetFirstBuild() (*BuildItem, error) {
return j.getBuildByName("firstBuild")
return j.GetBuildByName("firstBuild")
}
func (j *JobItem) GetLastBuild() (*BuildItem, error) {
return j.getBuildByName("lastBuild")
return j.GetBuildByName("lastBuild")
}
func (j *JobItem) GetLastCompleteBuild() (*BuildItem, error) {
return j.getBuildByName("lastCompletedBuild")
return j.GetBuildByName("lastCompletedBuild")
}
func (j *JobItem) GetLastFailedBuild() (*BuildItem, error) {
return j.getBuildByName("lastFailedBuild")
return j.GetBuildByName("lastFailedBuild")
}
func (j *JobItem) GetLastStableBuild() (*BuildItem, error) {
return j.getBuildByName("lastStableBuild")
return j.GetBuildByName("lastStableBuild")
}
func (j *JobItem) GetLastUnstableBuild() (*BuildItem, error) {
return j.getBuildByName("lastUnstableBuild")
return j.GetBuildByName("lastUnstableBuild")
}
func (j *JobItem) GetLastSuccessfulBuild() (*BuildItem, error) {
return j.getBuildByName("lastSuccessfulBuild")
return j.GetBuildByName("lastSuccessfulBuild")
}
func (j *JobItem) GetLastUnsucessfulBuild() (*BuildItem, error) {
return j.getBuildByName("lastUnsuccessfulBuild")
return j.GetBuildByName("lastUnsuccessfulBuild")
}

func (j *JobItem) getBuildByName(name string) (*BuildItem, error) {
func (j *JobItem) GetBuildByName(name string) (*BuildItem, error) {
if j.Class == "Folder" || j.Class == "WorkflowMultiBranchProject" {
return nil, fmt.Errorf("%s have no builds", j)
}
Expand Down
Loading

0 comments on commit b865ab1

Please sign in to comment.