Skip to content

Commit

Permalink
extended tests for jenkins openshift V3 plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
gabemontero committed Jan 7, 2016
1 parent e883f1b commit d23a24f
Show file tree
Hide file tree
Showing 4 changed files with 252 additions and 1 deletion.
1 change: 1 addition & 0 deletions test/extended/extended_test.go
Expand Up @@ -6,6 +6,7 @@ import (
_ "github.com/openshift/origin/test/extended/builds"
_ "github.com/openshift/origin/test/extended/cli"
_ "github.com/openshift/origin/test/extended/images"
_ "github.com/openshift/origin/test/extended/jenkins"
_ "github.com/openshift/origin/test/extended/job"
_ "github.com/openshift/origin/test/extended/router"
_ "github.com/openshift/origin/test/extended/security"
Expand Down
88 changes: 88 additions & 0 deletions test/extended/fixtures/testjob-plugin.xml
@@ -0,0 +1,88 @@
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<scm class="hudson.scm.NullSCM"/>
<canRoam>true</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders>

<com.openshift.jenkins.plugins.pipeline.OpenShiftScaler>
<apiURL>https://openshift.default.svc.cluster.local</apiURL>
<depCfg>frontend</depCfg>
<namespace>PROJECT_NAME</namespace>
<replicaCount>0</replicaCount>
<authToken></authToken>
</com.openshift.jenkins.plugins.pipeline.OpenShiftScaler>

<com.openshift.jenkins.plugins.pipeline.OpenShiftDeploymentVerifier>
<apiURL>https://openshift.default.svc.cluster.local</apiURL>
<depCfg>frontend</depCfg>
<namespace>PROJECT_NAME</namespace>
<replicaCount>0</replicaCount>
<authToken></authToken>
</com.openshift.jenkins.plugins.pipeline.OpenShiftDeploymentVerifier>

<com.openshift.jenkins.plugins.pipeline.OpenShiftBuilder>
<apiURL>https://openshift.default.svc.cluster.local</apiURL>
<bldCfg>frontend</bldCfg>
<namespace>PROJECT_NAME</namespace>
<authToken></authToken>
<followLog>true</followLog>
</com.openshift.jenkins.plugins.pipeline.OpenShiftBuilder>

<com.openshift.jenkins.plugins.pipeline.OpenShiftDeploymentVerifier>
<apiURL>https://openshift.default.svc.cluster.local</apiURL>
<depCfg>frontend</depCfg>
<namespace>PROJECT_NAME</namespace>
<replicaCount>1</replicaCount>
<authToken></authToken>
</com.openshift.jenkins.plugins.pipeline.OpenShiftDeploymentVerifier>

<com.openshift.jenkins.plugins.pipeline.OpenShiftScaler>
<apiURL>https://openshift.default.svc.cluster.local</apiURL>
<depCfg>frontend</depCfg>
<namespace>PROJECT_NAME</namespace>
<replicaCount>1</replicaCount>
<authToken></authToken>
</com.openshift.jenkins.plugins.pipeline.OpenShiftScaler>
<com.openshift.jenkins.plugins.pipeline.OpenShiftDeploymentVerifier>
<apiURL>https://openshift.default.svc.cluster.local</apiURL>
<depCfg>frontend</depCfg>
<namespace>PROJECT_NAME</namespace>
<replicaCount>1</replicaCount>
<authToken></authToken>
</com.openshift.jenkins.plugins.pipeline.OpenShiftDeploymentVerifier>

<com.openshift.jenkins.plugins.pipeline.OpenShiftServiceVerifier>
<apiURL>https://openshift.default.svc.cluster.local</apiURL>
<svcName>frontend</svcName>
<namespace>PROJECT_NAME</namespace>
<authToken></authToken>
</com.openshift.jenkins.plugins.pipeline.OpenShiftServiceVerifier>

<com.openshift.jenkins.plugins.pipeline.OpenShiftImageTagger>
<apiURL>https://openshift.default.svc.cluster.local</apiURL>
<namespace>PROJECT_NAME</namespace>
<testTag>origin-nodejs-sample:latest</testTag>
<prodTag>origin-nodejs-sample:prod</prodTag>
<authToken></authToken>
</com.openshift.jenkins.plugins.pipeline.OpenShiftImageTagger>

<com.openshift.jenkins.plugins.pipeline.OpenShiftDeploymentVerifier>
<apiURL>https://openshift.default.svc.cluster.local</apiURL>
<depCfg>frontend-prod</depCfg>
<namespace>PROJECT_NAME</namespace>
<replicaCount>1</replicaCount>
<authToken></authToken>
</com.openshift.jenkins.plugins.pipeline.OpenShiftDeploymentVerifier>

</builders>
<publishers/>
<buildWrappers/>
</project>
159 changes: 159 additions & 0 deletions test/extended/jenkins/jenkins_plugin.go
@@ -0,0 +1,159 @@
package jenkins

import (
g "github.com/onsi/ginkgo"
o "github.com/onsi/gomega"

"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"strings"
"time"

"k8s.io/kubernetes/pkg/util/wait"

exutil "github.com/openshift/origin/test/extended/util"
)

func immediateInteractionWithJenkins(uri, method string, body io.Reader, status int) {
req, err := http.NewRequest(method, uri, body)
o.Expect(err).NotTo(o.HaveOccurred())

if body != nil {
req.Header.Set("Content-Type", "application/xml")
// jenkins will return 417 if we have an expect hdr
req.Header.Del("Expect")
}
req.SetBasicAuth("admin", "password")

client := &http.Client{}
resp, err := client.Do(req)
defer resp.Body.Close()

o.Expect(err).NotTo(o.HaveOccurred())
o.Expect(resp.StatusCode).To(o.BeEquivalentTo(status))

}

func waitForJenkinsActivity(uri, verificationString string, status int) error {
consoleLogs := ""

err := wait.Poll(1*time.Second, 3*time.Minute, func() (bool, error) {
req, err := http.NewRequest("GET", uri, nil)
if err != nil {
return false, err
}
req.SetBasicAuth("admin", "password")
client := &http.Client{}
resp, _ := client.Do(req)
// the http req failing here (which we see occassionally in the ci.jenkins runs) could stem
// from simply hitting our test jenkins server too soon ... so rather than returning false,err
// and aborting the poll, we return false, nil to try again
if resp == nil {
return false, nil
}
defer resp.Body.Close()
if resp.StatusCode == status {
if len(verificationString) > 0 {
contents, err := ioutil.ReadAll(resp.Body)
if err != nil {
return false, err
}
consoleLogs = string(contents)
if strings.Contains(consoleLogs, verificationString) {
return true, nil
} else {
return false, nil
}
} else {
return true, nil
}
}
return false, nil
})

if err != nil {
return fmt.Errorf("got error %v waiting on uri %s with verificationString %s and last set of console logs %s", err, uri, verificationString, consoleLogs)
} else {
return nil
}
}

// as g.It's are added conceivably will be with new jenkins job def's
func jenkinsJobBytes(filename, namespace string) []byte {
pre := exutil.FixturePath("fixtures", filename)
post := exutil.ArtifactPath(filename)
err := exutil.VarSubOnFile(pre, post, "PROJECT_NAME", namespace)
o.Expect(err).NotTo(o.HaveOccurred())
data, err := ioutil.ReadFile(post)
o.Expect(err).NotTo(o.HaveOccurred())
return data
}

var _ = g.Describe("jenkins: plugin: run job leveraging openshift pipeline plugin", func() {
defer g.GinkgoRecover()
var oc = exutil.NewCLI("jenkins-plugin", exutil.KubeConfigPath())
var hostPort string

g.BeforeEach(func() {

g.By("set up policy for jenkins jobs")
err := oc.Run("policy").Args("add-role-to-user", "edit", "system:serviceaccount:"+oc.Namespace()+":default").Execute()
o.Expect(err).NotTo(o.HaveOccurred())

g.By("kick off the build for the jenkins ephermeral and application templates")
jenkinsEphemeralPath := exutil.FixturePath("..", "..", "examples", "jenkins", "jenkins-ephemeral-template.json")
err = oc.Run("new-app").Args(jenkinsEphemeralPath).Execute()
o.Expect(err).NotTo(o.HaveOccurred())
jenkinsApplicationPath := exutil.FixturePath("..", "..", "examples", "jenkins", "application-template.json")
err = oc.Run("new-app").Args(jenkinsApplicationPath).Execute()
o.Expect(err).NotTo(o.HaveOccurred())

g.By("waiting for jenkins deployment")
err = exutil.WaitForADeployment(oc.KubeREST().ReplicationControllers(oc.Namespace()), "jenkins", exutil.CheckDeploymentCompletedFn, exutil.CheckDeploymentFailedFn)
o.Expect(err).NotTo(o.HaveOccurred())

g.By("get ip and port for jenkins service")
serviceIP, err := oc.Run("get").Args("svc", "jenkins", "--config", exutil.KubeConfigPath()).Template("{{.spec.clusterIP}}").Output()
o.Expect(err).NotTo(o.HaveOccurred())
port, err := oc.Run("get").Args("svc", "jenkins", "--config", exutil.KubeConfigPath()).Template("{{ $x := index .spec.ports 0}}{{$x.port}}").Output()
o.Expect(err).NotTo(o.HaveOccurred())
hostPort = fmt.Sprintf("%s:%s", serviceIP, port)

g.By("wait for jenkins to come up")
err = waitForJenkinsActivity(fmt.Sprintf("http://%s", hostPort), "", 200)
o.Expect(err).NotTo(o.HaveOccurred())

})

g.Context("jenkins-plugin test context ", func() {

g.It("jenkins-plugin test case execution", func() {

g.By("create jenkins job config xml file, convert to bytes for http post")
data := jenkinsJobBytes("testjob-plugin.xml", oc.Namespace())

g.By("make http request to create job")
immediateInteractionWithJenkins(fmt.Sprintf("http://%s/createItem?name=test-plugin-job", hostPort), "POST", bytes.NewBuffer(data), 200)

g.By("make http request to kick off build")
immediateInteractionWithJenkins(fmt.Sprintf("http://%s/job/test-plugin-job/build?delay=0sec", hostPort), "POST", nil, 201)

// the build and deployment is by far the most time consuming portion of the test jenkins job;
// we leverage some of the openshift utilities for waiting for the deployment before we poll
// jenkins for the sucessful job completion
g.By("waiting for frontend deployment as sign that the build has finished")
err := exutil.WaitForADeployment(oc.KubeREST().ReplicationControllers(oc.Namespace()), "frontend", exutil.CheckDeploymentCompletedFn, exutil.CheckDeploymentFailedFn)
o.Expect(err).NotTo(o.HaveOccurred())

g.By("get build console logs and see if succeeded")
err = waitForJenkinsActivity(fmt.Sprintf("http://%s/job/test-plugin-job/1/console", hostPort), "SUCCESS", 200)
o.Expect(err).NotTo(o.HaveOccurred())

})

})

})
5 changes: 4 additions & 1 deletion test/extended/util/framework.go
Expand Up @@ -189,7 +189,9 @@ var CheckImageStreamTagNotFoundFn = func(i *imageapi.ImageStream) bool {
func WaitForADeployment(client kclient.ReplicationControllerInterface,
name string,
isOK, isFailed func(*kapi.ReplicationController) bool) error {
for {
startTime := time.Now()
endTime := startTime.Add(15 * time.Minute)
for time.Now().Before(endTime) {
requirement, err := labels.NewRequirement(deployapi.DeploymentConfigAnnotation, labels.EqualsOperator, sets.NewString(name))
if err != nil {
return fmt.Errorf("unexpected error generating label selector: %v", err)
Expand Down Expand Up @@ -233,6 +235,7 @@ func WaitForADeployment(client kclient.ReplicationControllerInterface,
}
}
}
return fmt.Errorf("the deploy did not finish within 3 minutes")
}

// CheckDeploymentCompletedFn returns true if the deployment completed
Expand Down

0 comments on commit d23a24f

Please sign in to comment.