-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Initial support for extended integration test #1230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| #!/bin/bash | ||
|
|
||
| set -o nounset | ||
| set -o pipefail | ||
|
|
||
| OS_ROOT=$(dirname "${BASH_SOURCE}")/.. | ||
|
|
||
| source ${OS_ROOT}/hack/util.sh | ||
| source ${OS_ROOT}/hack/common.sh | ||
|
|
||
| TIME_SEC=1000 | ||
| TIME_MIN=$((60 * $TIME_SEC)) | ||
|
|
||
| # TODO: Randomize these ports | ||
| export OS_MASTER_PORT=$(go run ${OS_ROOT}/test/util/random_port/generate.go) | ||
| export OS_ASSETS_PORT=$(go run ${OS_ROOT}/test/util/random_port/generate.go) | ||
| export OS_DNS_PORT=$(go run ${OS_ROOT}/test/util/random_port/generate.go) | ||
| export ETCD_PORT=$(go run ${OS_ROOT}/test/util/random_port/generate.go) | ||
|
|
||
| DEFAULT_SERVER_IP=$(ifconfig | grep -Ev "(127.0.0.1|172.17.42.1)" | grep "inet " | head -n 1 | awk '{print $2}') | ||
|
|
||
| export OS_MASTER_ADDR=${DEFAULT_SERVER_IP}:${OS_MASTER_PORT} | ||
| export OS_ASSETS_ADDR=${DEFAULT_SERVER_IP}:${OS_ASSETS_PORT} | ||
| export OS_DNS_ADDR=${DEFAULT_SERVER_IP}:${OS_DNS_PORT} | ||
| export KUBERNETES_MASTER="https://${OS_MASTER_ADDR}" | ||
|
|
||
| export TMPDIR=${TMPDIR:-/tmp} | ||
| export BASETMPDIR="${TMPDIR}/openshift-extended-tests" | ||
|
|
||
| # Remove all test artifacts from the previous run | ||
| rm -rf ${BASETMPDIR} && mkdir -p ${BASETMPDIR} | ||
|
|
||
| # Setup directories and certificates for 'curl' | ||
| export CERT_DIR="${BASETMPDIR}/cert" | ||
| export CURL_CA_BUNDLE="${CERT_DIR}/ca/cert.crt" | ||
| export CURL_CERT="${CERT_DIR}/admin/cert.crt" | ||
| export CURL_KEY="${CERT_DIR}/admin/key.key" | ||
| export KUBECONFIG="${CERT_DIR}/admin/.kubeconfig" | ||
| export OPENSHIFT_ON_PANIC=crash | ||
|
|
||
| cleanup() { | ||
| set +e | ||
| server_pids=$(pgrep -P $(cat ${BASETMPDIR}/server.pid)) | ||
| kill $server_pids $(cat ${BASETMPDIR}/server.pid) ${ETCD_PID} | ||
| rm -rf ${ETCD_DIR} | ||
| echo "[INFO] Cleanup complete" | ||
| } | ||
|
|
||
| # TODO: There is a lot of code shared between this test launcher and e2e test | ||
| # launcher. | ||
| start_server() { | ||
| mkdir -p ${BASETMPDIR}/volumes | ||
| ALL_IP_ADDRESSES=`ifconfig | grep "inet " | awk '{print $2}'` | ||
| SERVER_HOSTNAME_LIST="${DEFAULT_SERVER_IP},localhost" | ||
| while read -r IP_ADDRESS; do | ||
| SERVER_HOSTNAME_LIST="${SERVER_HOSTNAME_LIST},${IP_ADDRESS}" | ||
| done <<< "${ALL_IP_ADDRESSES}" | ||
|
|
||
| echo "[INFO] Create certificates for the OpenShift server" | ||
| sudo env "PATH=${PATH}" openshift admin create-all-certs \ | ||
| --overwrite=false \ | ||
| --cert-dir="${CERT_DIR}" \ | ||
| --hostnames="${SERVER_HOSTNAME_LIST}" \ | ||
| --nodes="127.0.0.1" \ | ||
| --master="https://${OS_MASTER_ADDR}" \ | ||
| --public-master="https://${OS_MASTER_ADDR}" | ||
|
|
||
| echo "[INFO] Starting OpenShift server" | ||
| sudo env "PATH=${PATH}" openshift start \ | ||
| --listen="https://0.0.0.0:${OS_MASTER_PORT}" \ | ||
| --public-master="https://${OS_MASTER_ADDR}" \ | ||
| --etcd="http://127.0.0.1:${ETCD_PORT}" \ | ||
| --hostname="127.0.0.1" \ | ||
| --create-certs=false \ | ||
| --cert-dir="${CERT_DIR}" \ | ||
| --volume-dir="${BASETMPDIR}/volumes" \ | ||
| --master="https://${OS_MASTER_ADDR}" \ | ||
| --latest-images \ | ||
| --loglevel=${VERBOSE:-3} &> ${BASETMPDIR}/server.log & | ||
| echo -n $! > ${BASETMPDIR}/server.pid | ||
| } | ||
|
|
||
| start_docker_registry() { | ||
| mkdir -p ${BASETMPDIR}/.registry | ||
| echo "[INFO] Creating default Router" | ||
| openshift ex router --create --credentials="${KUBECONFIG}" \ | ||
| --images='openshift/origin-${component}:latest' &>/dev/null | ||
|
|
||
| echo "[INFO] Creating Docker Registry" | ||
| openshift ex registry --create --credentials="${KUBECONFIG}" \ | ||
| --mount-host="${BASETMPDIR}/.registry" \ | ||
| --images='openshift/origin-${component}:latest' &>/dev/null | ||
| } | ||
|
|
||
| # Go to the top of the tree. | ||
| cd "${OS_ROOT}" | ||
|
|
||
| trap cleanup EXIT SIGINT | ||
|
|
||
| # Start the Etcd server | ||
| echo "[INFO] Starting etcd server (127.0.0.1:${ETCD_PORT})" | ||
| start_etcd | ||
| export ETCD_STARTED="1" | ||
|
|
||
| # Start OpenShift sever that will be common for all extended test cases | ||
| start_server | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It'd also be useful to instantiate the docker registry after starting the server.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 does the registry creation command offer 'watch' ?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It completes when it has created the artifacts, but I don't think it ensures that they are running
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it does not, borrow the loop from test-end-to-end.sh. |
||
|
|
||
| # Wait for the API server to come up | ||
| wait_for_url_timed "https://${OS_MASTER_ADDR}/healthz" "" 90*TIME_SEC >/dev/null | ||
| wait_for_url_timed "https://${OS_MASTER_ADDR}/osapi" "" 90*TIME_SEC >/dev/null | ||
| wait_for_url "https://${OS_MASTER_ADDR}/api/v1beta1/minions/127.0.0.1" "" 0.25 80 >/dev/null | ||
|
|
||
| # Start the Docker registry (172.30.17.101:5000) | ||
| start_docker_registry | ||
|
|
||
| wait_for_command '[[ "$(osc get endpoints docker-registry -t "{{ if .endpoints}}{{ len .endpoints }}{{ else }}0{{ end }}" 2>/dev/null || echo "0")" != "0" ]]' $((5*TIME_MIN)) | ||
|
|
||
| REGISTRY_ADDR=$(osc get --output-version=v1beta1 --template="{{ .portalIP }}:{{.port }}" \ | ||
| service docker-registry) | ||
| echo "[INFO] Verifying the docker-registry is up at ${REGISTRY_ADDR}" | ||
| wait_for_url_timed "http://${REGISTRY_ADDR}" "" $((2*TIME_MIN)) | ||
|
|
||
| # Run all extended tests cases | ||
| echo "[INFO] Starting extended tests" | ||
| OS_TEST_PACKAGE="test/extended" OS_TEST_TAGS="extended" OS_TEST_NAMESPACE="extended" ${OS_ROOT}/hack/test-integration.sh $@ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| // +build extended | ||
|
|
||
| package extended | ||
|
|
||
| // This extended tests excercise the scenario of having the 'contextDir' set to | ||
| // directory where the application sources resides inside the repository. | ||
| // The STI strategy is used for this build and this test succeed when the Build | ||
| // completes and the resulting image is used for a Pod that replies to HTTP | ||
| // request. | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "io/ioutil" | ||
| "net/http" | ||
| "strings" | ||
| "testing" | ||
|
|
||
| "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" | ||
| buildapi "github.com/openshift/origin/pkg/build/api" | ||
| "github.com/openshift/origin/test/util" | ||
| ) | ||
|
|
||
| func init() { | ||
| util.RequireServer() | ||
| } | ||
|
|
||
| func TestSTIContextDirBuild(t *testing.T) { | ||
| namespace := util.RandomNamespace("contextdir") | ||
| fmt.Printf("Using '%s' namespace\n", namespace) | ||
|
|
||
| build := util.GetBuildFixture("fixtures/contextdir-build.json") | ||
| client, _ := util.GetClusterAdminClient(util.KubeConfigPath()) | ||
|
|
||
| repo := util.CreateSampleImageRepository(namespace) | ||
| if repo == nil { | ||
| t.Fatal("Failed to create ImageRepository") | ||
| } | ||
| defer util.DeleteSampleImageRepository(repo, namespace) | ||
|
|
||
| // TODO: Tweak the selector to match the build name | ||
| watcher, err := client.Builds(namespace).Watch(labels.Everything(), labels.Everything(), "0") | ||
| if err != nil { | ||
| t.Fatalf("Failed to create watcher: %v", err) | ||
| } | ||
| defer watcher.Stop() | ||
|
|
||
| newBuild, err := client.Builds(namespace).Create(build) | ||
| if err != nil { | ||
| t.Fatalf("Unexpected error: %v", err) | ||
| } | ||
|
|
||
| for event := range watcher.ResultChan() { | ||
| build, ok := event.Object.(*buildapi.Build) | ||
| if !ok { | ||
| t.Fatalf("cannot convert input to Build") | ||
| } | ||
|
|
||
| // Iterate over watcher's results and search for | ||
| // the build we just started. Also make sure that | ||
| // the build is running, complete, or has failed | ||
| if build.Name == newBuild.Name { | ||
| switch build.Status { | ||
| case buildapi.BuildStatusFailed, buildapi.BuildStatusError: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd add
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @soltysh unlikely in the test run (I mean you have to Cancel the build by manual intervention) |
||
| t.Fatalf("Unexpected build status: ", buildapi.BuildStatusFailed) | ||
| case buildapi.BuildStatusComplete: | ||
| err := util.VerifyImage(repo, namespace, func(addr string) error { | ||
| resp, err := http.Get("http://" + addr) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| defer resp.Body.Close() | ||
| body, err := ioutil.ReadAll(resp.Body) | ||
| if strings.TrimSpace(string(body)) != "success" { | ||
| return fmt.Errorf("Expected 'success' got '%v'", body) | ||
| } | ||
| return nil | ||
| }) | ||
| if err != nil { | ||
| t.Fatalf("The build image failed validation: %v", err) | ||
| } | ||
| return | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| // +build extended | ||
|
|
||
| package extended | ||
|
|
||
| // This extended test exercise the Docker strategy build. This test succeed when | ||
| // the Docker image is successfully built. | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "testing" | ||
|
|
||
| "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" | ||
| buildapi "github.com/openshift/origin/pkg/build/api" | ||
| "github.com/openshift/origin/test/util" | ||
| ) | ||
|
|
||
| func init() { | ||
| util.RequireServer() | ||
| } | ||
|
|
||
| func TestDockerStrategyBuild(t *testing.T) { | ||
| namespace := util.RandomNamespace("docker") | ||
| fmt.Printf("Using '%s' namespace\n", namespace) | ||
|
|
||
| build := util.GetBuildFixture("fixtures/docker-build.json") | ||
| client, _ := util.GetClusterAdminClient(util.KubeConfigPath()) | ||
|
|
||
| if repo == nil { | ||
| t.Fatal("Failed to create ImageRepository") | ||
| } | ||
|
|
||
| // TODO: Tweak the selector to match the build name | ||
| watcher, err := client.Builds(namespace).Watch(labels.Everything(), labels.Everything(), "0") | ||
| if err != nil { | ||
| t.Fatalf("Failed to create watcher: %v", err) | ||
| } | ||
| defer watcher.Stop() | ||
|
|
||
| newBuild, err := client.Builds(namespace).Create(build) | ||
| if err != nil { | ||
| t.Fatalf("Unexpected error: %v", err) | ||
| } | ||
|
|
||
| for event := range watcher.ResultChan() { | ||
| build, ok := event.Object.(*buildapi.Build) | ||
| if !ok { | ||
| t.Fatalf("cannot convert input to Build") | ||
| } | ||
|
|
||
| if build.Name == newBuild.Name { | ||
| switch build.Status { | ||
| case buildapi.BuildStatusFailed, buildapi.BuildStatusError: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd add |
||
| t.Fatalf("Unexpected build status: ", buildapi.BuildStatusFailed) | ||
| case buildapi.BuildStatusComplete: | ||
| // If the Docker build strategy finishes with Complete, then this test | ||
| // succeeded | ||
| return | ||
| } | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the reason for using random ports that you could run the tests in parallel on a single machine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that was my thinking... We have random ports when you start the server using utils/server.go (StartAllInOneServer?)... Problem is that having random ports also means we need to have bash function that will scan if the ports is free... I don't want to add this now... I think I will add more reasoning to this comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pick a port based on the PID.
technically you should still collide w/ some other process, but at least you won't collide between test invocations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would think you'd also want a random etcd port
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bparees @csrwng I'm thinking about making a small Go helper that returns free port (same as we're doing here: https://github.com/openshift/origin/blob/master/test/integration/server_test.go#L44)
(go run test/util/helpers/address.go => 127.0.0.1:RANDOM)