Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions hack/test-extended.sh
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
Copy link
Contributor

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?

Copy link
Contributor Author

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

Copy link
Contributor

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.

Copy link
Contributor

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

Copy link
Contributor Author

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)

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
Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 does the registry creation command offer 'watch' ?

Copy link
Contributor

Choose a reason for hiding this comment

The 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

Copy link
Contributor

Choose a reason for hiding this comment

The 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 $@
29 changes: 20 additions & 9 deletions hack/test-integration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,20 @@ os::build::setup_env

function cleanup()
{
set +e
kill ${ETCD_PID} 1>&2 2>/dev/null
rm -rf ${ETCD_DIR} 1>&2 2>/dev/null
echo
echo "Complete"
[ ! -z "${ETCD_STARTED-}" ] && return
set +e
kill ${ETCD_PID} 1>&2 2>/dev/null
rm -rf ${ETCD_DIR} 1>&2 2>/dev/null
echo
echo "Complete"
}

package="${OS_TEST_PACKAGE:-test/integration}"
tags="${OS_TEST_TAGS:-integration no-docker}"

TMPDIR=${TMPDIR:-/tmp}
export BASETMPDIR=${BASETMPDIR:-"${TMPDIR}/openshift-integration"}

echo
echo "Test ${package} -tags='${tags}' ..."
echo
Expand All @@ -44,15 +48,21 @@ start_etcd
trap cleanup EXIT SIGINT

function exectest() {
echo "running $1..."
echo "Running $1..."

out=$("${testexec}" -test.run="^$1$" "${@:2}" 2>&1)
result=1
if [ ! -z "${VERBOSE-}" ]; then
out=$("${testexec}" -test.v=true -v ${VERBOSE-} -test.run="^$1$" "${@:2}" 2>&1)
result=$?
else
out=$("${testexec}" -test.run="^$1$" "${@:2}" 2>&1)
result=$?
fi

tput cuu 1 # Move up one line
tput el # Clear "running" line

res=$?
if [[ ${res} -eq 0 ]]; then
if [[ ${result} -eq 0 ]]; then
tput setaf 2 # green
echo "ok $1"
tput sgr0 # reset
Expand All @@ -65,6 +75,7 @@ function exectest() {
exit 1
fi
}

export -f exectest
export testexec
export childargs
Expand Down
4 changes: 3 additions & 1 deletion hack/util.sh
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ function validate_response {
# $1 - Optional host (Default: 127.0.0.1)
# $2 - Optional port (Default: 4001)
function start_etcd {
[ ! -z "${ETCD_STARTED-}" ] && return

host=${ETCD_HOST:-127.0.0.1}
port=${ETCD_PORT:-4001}

Expand Down Expand Up @@ -228,7 +230,7 @@ function start_etcd {
etcd -name test -data-dir ${ETCD_DIR} -bind-addr ${host}:${port} ${initial_cluster} >/dev/null 2>/dev/null &
export ETCD_PID=$!

wait_for_url "http://127.0.0.1:4001/version" "etcd: "
wait_for_url "http://${host}:${port}/version" "etcd: "
}

# stop_openshift_server utility function to terminate an
Expand Down
85 changes: 85 additions & 0 deletions test/extended/build_context_dir_test.go
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:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add BuildStatusCancelled here as well, as it's also an end status of a build.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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
}
}
}
}
61 changes: 61 additions & 0 deletions test/extended/build_docker_test.go
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:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add BuildStatusCancelled here as well, as it's also an end status of a build.

t.Fatalf("Unexpected build status: ", buildapi.BuildStatusFailed)
case buildapi.BuildStatusComplete:
// If the Docker build strategy finishes with Complete, then this test
// succeeded
return
}
}
}
}
Loading