Skip to content

WIP: Test PushSecretName via extended tests #1515

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

Merged
merged 1 commit into from
Apr 2, 2015
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
46 changes: 35 additions & 11 deletions hack/test-extended.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,12 @@ 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}
pid=$(cat ${BASETMPDIR}/server.pid 2>/dev/null)
if [ ! -z "$pid" ]; then
server_pids=$(pgrep -P $pid)
kill $server_pids $(cat ${BASETMPDIR}/server.pid) ${ETCD_PID}
fi
rm -rf ${ETCD_DIR-}
echo "[INFO] Cleanup complete"
}

Expand Down Expand Up @@ -75,7 +78,7 @@ start_server() {
--signer-key="${CERT_DIR}/ca/key.key" \
--signer-serial="${CERT_DIR}/ca/serial.txt"

echo "[INFO] Starting OpenShift server"
echo "[INFO] Starting OpenShift ..."
sudo env "PATH=${PATH}" openshift start \
--listen="https://0.0.0.0:${OS_MASTER_PORT}" \
--public-master="https://${OS_MASTER_ADDR}" \
Expand All @@ -92,16 +95,25 @@ start_server() {

start_docker_registry() {
mkdir -p ${BASETMPDIR}/.registry
echo "[INFO] Creating Router"
echo "[INFO] Creating Router ..."
openshift ex router --create --credentials="${KUBECONFIG}" \
--images='openshift/origin-${component}:latest' &>/dev/null

echo "[INFO] Creating Docker Registry"
echo "[INFO] Creating Registry ..."
openshift ex registry --create --credentials="${KUBECONFIG}" \
--mount-host="${BASETMPDIR}/.registry" \
--images='openshift/origin-${component}:latest' &>/dev/null
}

push_to_registry() {
local image=$1
local registry=$2
echo "[INFO] Caching $image to $registry"
( docker tag $image "${registry}/${image}" && \
docker push "${registry}/${image}" \
) &>/dev/null
}

# Go to the top of the tree.
cd "${OS_ROOT}"

Expand Down Expand Up @@ -134,10 +146,22 @@ wait_for_url_timed "http://${REGISTRY_ADDR}" "" $((2*TIME_MIN))
# "409 - Image already exists" during the 'push' when the Build finishes.
# This is because Docker Registry cannot handle parallel pushes.
# See: https://github.com/docker/docker-registry/issues/537
echo "[INFO] Pushing openshift/ruby-20-centos7 image to ${REGISTRY_ADDR}"
docker tag openshift/ruby-20-centos7 ${REGISTRY_ADDR}/openshift/ruby-20-centos7
docker push ${REGISTRY_ADDR}/openshift/ruby-20-centos7 &>/dev/null
push_to_registry "openshift/ruby-20-centos7" $REGISTRY_ADDR
push_to_registry "openshift/origin-custom-docker-builder" $REGISTRY_ADDR

export REGISTRY_ADDR

[ ! -z "${DEBUG-}" ] && set +e

# 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 $@
while true; do
echo "[INFO] Starting extended tests ..."
time OS_TEST_PACKAGE="test/extended" OS_TEST_TAGS="extended" OS_TEST_NAMESPACE="extended" ${OS_ROOT}/hack/test-integration.sh $@
if [ ! -z "${DEBUG-}" ]; then
read -p "Do you want to re-run the test cases? " yn
case $yn in
[Nn]* ) exit;;
* ) echo "Please answer yes or no.";;
esac
fi
done
185 changes: 74 additions & 111 deletions test/extended/builds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import (
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
"testing"

"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
buildapi "github.com/openshift/origin/pkg/build/api"
testutil "github.com/openshift/origin/test/util"
)
Expand All @@ -18,116 +21,72 @@ func init() {
testutil.RequireServer()
}

// TestSTIContextDirBuild excercises 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.
func TestSTIContextDirBuild(t *testing.T) {
namespace := testutil.RandomNamespace("contextdir")
fmt.Printf("Using '%s' namespace\n", namespace)

build := testutil.GetBuildFixture("fixtures/contextdir-build.json")
// TestPushSecretName exercises one of the complex Build scenarios, where you
// first build a Docker image using Docker build strategy, which will later by
// consumed by Custom build strategy to verify that the 'PushSecretName' (Docker
// credentials) were successfully transported to the builder. The content of the
// Secret file is verified in the end.
func TestPushSecretName(t *testing.T) {
namespace := testutil.RandomNamespace("secret")
client, _ := testutil.GetClusterAdminClient(testutil.KubeConfigPath())
kclient, _ := testutil.GetClusterAdminKubeClient(testutil.KubeConfigPath())

repo := testutil.CreateSampleImageRepository(namespace)

if repo == nil {
t.Fatal("Failed to create ImageRepository")
}
defer testutil.DeleteSampleImageRepository(repo, namespace)

// TODO: Tweak the selector to match the build name
watcher, err := client.Builds(namespace).Watch(labels.Everything(), labels.Everything(), "0")
// Create Secret with dockercfg
secret := testutil.GetSecretFixture("fixtures/test-secret.json")
// TODO: Why do I need to set namespace here?
secret.Namespace = namespace
_, err := kclient.Secrets(namespace).Create(secret)
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:
t.Fatalf("Unexpected build status: ", buildapi.BuildStatusFailed)
case buildapi.BuildStatusComplete:
err := testutil.VerifyImage(repo, namespace, validateContextDirImage)
if err != nil {
t.Fatalf("The build image failed validation: %v", err)
}
return
}
}
}
}

// TestDockerStrategyBuild exercises the Docker strategy build. This test succeed when
// the Docker image is successfully built.
func TestDockerStrategyBuild(t *testing.T) {
namespace := testutil.RandomNamespace("docker")
fmt.Printf("Using '%s' namespace\n", namespace)

build := testutil.GetBuildFixture("fixtures/docker-build.json")
client, _ := testutil.GetClusterAdminClient(testutil.KubeConfigPath())

repo := testutil.CreateSampleImageRepository(namespace)
if repo == nil {
t.Fatal("Failed to create ImageRepository")
t.Fatalf("Failed to create Secret: %v", err)
}
defer testutil.DeleteSampleImageRepository(repo, namespace)

// TODO: Tweak the selector to match the build name
watcher, err := client.Builds(namespace).Watch(labels.Everything(), labels.Everything(), "0")
watcher, err := client.Builds(namespace).Watch(labels.Everything(), fields.Everything(), "0")
if err != nil {
t.Fatalf("Failed to create watcher: %v", err)
}
defer watcher.Stop()

newBuild, err := client.Builds(namespace).Create(build)
// First build the builder image (custom build builder)
dockerBuild := testutil.GetBuildFixture("fixtures/test-secret-build.json")
newDockerBuild, err := client.Builds(namespace).Create(dockerBuild)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
t.Fatalf("Unable to create Build %s: %v", dockerBuild.Name, err)
}
waitForComplete(newDockerBuild, watcher, t)

for event := range watcher.ResultChan() {
build, ok := event.Object.(*buildapi.Build)
if !ok {
t.Fatalf("cannot convert input to Build")
}
// Now build the application image using custom build (run the previous image)
// Custom build will copy the dockercfg file into the application image.
customBuild := testutil.GetBuildFixture("fixtures/test-custom-build.json")
imageName := fmt.Sprintf("%s/%s/%s", os.Getenv("REGISTRY_ADDR"), namespace, repo.Name)
customBuild.Parameters.Strategy.CustomStrategy.Image = imageName
newCustomBuild, err := client.Builds(namespace).Create(customBuild)
if err != nil {
t.Fatalf("Unable to create Build %s: %v", dockerBuild.Name, err)
}
waitForComplete(newCustomBuild, watcher, t)

if build.Name == newBuild.Name {
switch build.Status {
case buildapi.BuildStatusFailed, buildapi.BuildStatusError:
t.Fatalf("Unexpected build status: ", buildapi.BuildStatusFailed)
case buildapi.BuildStatusComplete:
// If the Docker build strategy finishes with Complete, then this test
// succeeded
return
}
}
// Verify that the dockercfg file is there
if err := testutil.VerifyImage(repo, "application", namespace, validatePushSecret); err != nil {
t.Fatalf("Image verification failed: %v", err)
}
}

// TestSTIContextDirBuild exercises the scenario of having the '.sti/environment'
// file in the application sources that should set the defined environment
// variables for the resulting application. HTTP request is made to Pod that
// runs the output image and this HTTP request should reply the value of the
// TEST_VAR.
// TestSTIEnvironmentBuild exercises the scenario where you have .sti/environment
// file in your source code repository and you use STI build strategy. In that
// case the STI build should read that file and set all environment variables
// from that file to output image.
func TestSTIEnvironmentBuild(t *testing.T) {
namespace := testutil.RandomNamespace("stienv")
fmt.Printf("Using '%s' namespace\n", namespace)

build := testutil.GetBuildFixture("fixtures/sti-env-build.json")
build := testutil.GetBuildFixture("fixtures/test-env-build.json")
client, _ := testutil.GetClusterAdminClient(testutil.KubeConfigPath())

repo := testutil.CreateSampleImageRepository(namespace)
Expand All @@ -137,7 +96,7 @@ func TestSTIEnvironmentBuild(t *testing.T) {
defer testutil.DeleteSampleImageRepository(repo, namespace)

// TODO: Tweak the selector to match the build name
watcher, err := client.Builds(namespace).Watch(labels.Everything(), labels.Everything(), "0")
watcher, err := client.Builds(namespace).Watch(labels.Everything(), fields.Everything(), "0")
if err != nil {
t.Fatalf("Failed to create watcher: %v", err)
}
Expand All @@ -148,27 +107,9 @@ func TestSTIEnvironmentBuild(t *testing.T) {
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:
t.Fatalf("Unexpected build status: ", buildapi.BuildStatusFailed)
case buildapi.BuildStatusComplete:
err := testutil.VerifyImage(repo, namespace, validateSTIEnvironment)
if err != nil {
t.Fatalf("The build image failed validation: %v", err)
}
return
}
}
waitForComplete(newBuild, watcher, t)
if err := testutil.VerifyImage(repo, "", namespace, validateSTIEnvironment); err != nil {
t.Fatalf("The build image failed validation: %v", err)
}
}

Expand All @@ -187,17 +128,39 @@ func validateSTIEnvironment(address string) error {
return nil
}

// validateContextDirImage verifies that the image with contextDir set can
// properly start and respond to HTTP requests
func validateContextDirImage(address string) error {
resp, err := http.Get("http://" + address)
// validatePushSecret verifies that the content of the sample dockercfg is
// properly returned from the Pod running the image that contains this file.
func validatePushSecret(address string) error {
expected := `{"https://registryhost/v1":{"auth":"secret","email":"[email protected]"}}`
resp, err := http.Get("http://" + address + "/SECRET_FILE")
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)
if strings.TrimSpace(string(body)) != expected {
return fmt.Errorf("Expected '%s' '%s'", expected, body)
}
return nil
}

// waitForComplete waits for the Build to finish
func waitForComplete(build *buildapi.Build, w watch.Interface, t *testing.T) {
for event := range w.ResultChan() {
eventBuild, ok := event.Object.(*buildapi.Build)
if !ok {
t.Fatalf("Cannot convert input to Build")
}
if build.Name != eventBuild.Name {
continue
}
switch eventBuild.Status {
case buildapi.BuildStatusFailed, buildapi.BuildStatusError:
t.Fatalf("Unexpected status for Build %s: ", eventBuild.Name, buildapi.BuildStatusFailed)
case buildapi.BuildStatusComplete:
return
default:
fmt.Printf("Build %s updated: %v\n", eventBuild.Name, eventBuild.Status)
}
}
}
3 changes: 0 additions & 3 deletions test/extended/fixtures/context-build-app/Gemfile

This file was deleted.

1 change: 0 additions & 1 deletion test/extended/fixtures/context-build-app/config.ru

This file was deleted.

30 changes: 0 additions & 30 deletions test/extended/fixtures/contextdir-build.json

This file was deleted.

3 changes: 3 additions & 0 deletions test/extended/fixtures/custom-secret-builder/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM openshift/origin-custom-docker-builder
# Override the default build script
ADD build.sh /tmp/build.sh
Loading