Skip to content

Commit

Permalink
Allow contributors to launch integration tests against local registry
Browse files Browse the repository at this point in the history
This change allows user to launch integration tests with a local registry

Fixes #1012
  • Loading branch information
antechrestos committed Jan 30, 2020
1 parent 8bdcb4f commit ea48aaf
Show file tree
Hide file tree
Showing 6 changed files with 294 additions and 100 deletions.
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ before_install:
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
- curl -LO https://storage.googleapis.com/container-diff/latest/container-diff-linux-amd64 && chmod +x container-diff-linux-amd64 && sudo mv container-diff-linux-amd64 /usr/local/bin/container-diff
- docker run -d -p 5000:5000 --restart always --name registry registry:2
- ./integration/replace-gcr-with-local-registry.sh integration/dockerfiles

script:
- make test
- ./integration-test.sh --uploadToGCS=false
- make integration-test
- make images
68 changes: 55 additions & 13 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,35 +67,77 @@ _These tests will not run correctly unless you have [checked out your fork into

### Integration tests

The integration tests live in [`integration`](./integration) and can be run with:
Currently the integration tests that live in [`integration`](./integration) can be run against your own gcloud space or a local registry.

In either case, you will need the following tools:

* [`container-diff`](https://github.com/GoogleContainerTools/container-diff#installation)

#### GCloud

To run integration tests with your GCloud Storage, you will also need the following tools:

* [`gcloud`](https://cloud.google.com/sdk/install)
* [`gsutil`](https://cloud.google.com/storage/docs/gsutil_install)
* A bucket in [GCS](https://cloud.google.com/storage/) which you have write access to via
the user currently logged into `gcloud`
* An image repo which you have write access to via the user currently logged into `gcloud`

Once this step done, you must override the project using environment variables:

* `GCS_BUCKET` - The name of your GCS bucket
* `IMAGE_REPO` - The path to your docker image repo

This can be done as follows:

```shell
export GCS_BUCKET="gs://<your bucket>"
export IMAGE_REPO="gcr.io/somerepo"
make integration-test
```

If you want to run `make integration-test`, you must override the project using environment variables:
Then you can launch integration tests as follows:

* `GCS_BUCKET` - The name of your GCS bucket
* `IMAGE_REPO` - The path to your docker image repo
```shell
make integration-test
```

You can also run tests with `go test`, for example to run tests individually:

```shell
go test ./integration -v --bucket $GCS_BUCKET --repo $IMAGE_REPO -run TestLayers/test_layer_Dockerfile_test_copy_bucket
```

Requirements:
These tests will be kicked off by [reviewers](#reviews) for submitted PRs by the kokoro task.

#### Local repository

Otherwise you can run integration tests locally. To do so, install a local docker registry

```shell
docker run --rm -d -p 5000:5000 --name registry registry:2
```

Then export the `IMAGE_REPO` variable with the `localhost:5000`value

```shell
export IMAGE_REPO=localhost:5000
```

And run the integration tests

```shell
make integration-test
```

You can also run tests with `go test`, for example to run tests individually:

```shell
go test ./integration -v --repo localhost:5000 -run TestLayers/test_layer_Dockerfile_test_copy_bucket
```

These tests will be kicked off by [reviewers](#reviews) for submitted PRs by the travis task.

* [`gcloud`](https://cloud.google.com/sdk/install)
* [`gsutil`](https://cloud.google.com/storage/docs/gsutil_install)
* [`container-diff`](https://github.com/GoogleContainerTools/container-diff#installation)
* A bucket in [GCS](https://cloud.google.com/storage/) which you have write access to via
the user currently logged into `gcloud`
* An image repo which you have write access to via the user currently logged into `gcloud`

These tests will be kicked off by [reviewers](#reviews) for submitted PRs.

### Benchmarking

Expand Down
34 changes: 34 additions & 0 deletions integration/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Copyright 2018 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package integration

import "strings"

type gcpConfig struct {
gcsBucket string
imageRepo string
onbuildBaseImage string
hardlinkBaseImage string
serviceAccount string
dockerMajorVersion int
}

const gcrRepoPrefix string = "gcr.io/"

func (config *gcpConfig) isGcrRepository() bool {
return strings.HasPrefix(config.imageRepo, gcrRepoPrefix)
}
96 changes: 55 additions & 41 deletions integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"encoding/json"
"flag"
"fmt"
"github.com/pkg/errors"
"log"
"math"
"os"
Expand Down Expand Up @@ -80,37 +81,67 @@ func getDockerMajorVersion() int {
}
return ver
}
func launchTests(m *testing.M, dockerfiles [] string) (error, int) {

func TestMain(m *testing.M) {
if !meetsRequirements() {
fmt.Println("Missing required tools")
os.Exit(1)
}
config = initGCPConfig()

if config.uploadToGCS {
if config.isGcrRepository() {
contextFile, err := CreateIntegrationTarball()
if err != nil {
fmt.Println("Failed to create tarball of integration files for build context", err)
os.Exit(1)
return errors.Wrap(err, "Failed to create tarball of integration files for build context"), 1
}

fileInBucket, err := UploadFileToBucket(config.gcsBucket, contextFile, contextFile)
if err != nil {
fmt.Println("Failed to upload build context", err)
os.Exit(1)
return errors.Wrap(err, "Failed to upload build context"), 1
}

err = os.Remove(contextFile)
if err != nil {
fmt.Printf("Failed to remove tarball at %s: %s\n", contextFile, err)
os.Exit(1)
if err = os.Remove(contextFile); err != nil {
return errors.Wrap(err, fmt.Sprintf("Failed to remove tarball at %s", contextFile)), 1
}

RunOnInterrupt(func() { DeleteFromBucket(fileInBucket) })
defer DeleteFromBucket(fileInBucket)
} else {
var err error
var migratedFiles [] string
if err, migratedFiles = MigrateGcsRegistry(dockerfilesPath, dockerfiles, config.imageRepo); err != nil {
RollbackMigratedFiles(dockerfilesPath, migratedFiles)
return errors.Wrap(err, "Fail to migrate dockerfiles from gcs"), 1
}
RunOnInterrupt(func() { RollbackMigratedFiles(dockerfilesPath, migratedFiles) })
defer RollbackMigratedFiles(dockerfilesPath, migratedFiles)
}
if err := buildRequiredImages(); err != nil {
return errors.Wrap(err, "Error while building images"), 1
}

imageBuilder = NewDockerFileBuilder(dockerfiles)

return nil, m.Run()
}

func TestMain(m *testing.M) {
if !meetsRequirements() {
fmt.Println("Missing required tools")
os.Exit(1)
}

if dockerfiles, err := FindDockerFiles(dockerfilesPath); err != nil {
fmt.Println("Coudn't create map of dockerfiles", err)
os.Exit(1)
} else {
config = initGCPConfig()
if err, exitCode := launchTests(m, dockerfiles); err != nil {
fmt.Println(err)
os.Exit(exitCode)
} else {
os.Exit(exitCode)
}
}


}

func buildRequiredImages() error {
setupCommands := []struct {
name string
command []string
Expand Down Expand Up @@ -145,20 +176,10 @@ func TestMain(m *testing.M) {
fmt.Println(setupCmd.name)
cmd := exec.Command(setupCmd.command[0], setupCmd.command[1:]...)
if out, err := RunCommandWithoutTest(cmd); err != nil {
fmt.Printf("%s failed: %s", setupCmd.name, err)
fmt.Println(string(out))
os.Exit(1)
return errors.Wrap(err, fmt.Sprintf("%s failed: %s", setupCmd.name, string(out)))
}
}

dockerfiles, err := FindDockerFiles(dockerfilesPath)
if err != nil {
fmt.Printf("Coudn't create map of dockerfiles: %s", err)
os.Exit(1)
}
imageBuilder = NewDockerFileBuilder(dockerfiles)

os.Exit(m.Run())
return nil
}

func TestRun(t *testing.T) {
Expand Down Expand Up @@ -535,16 +556,6 @@ func logBenchmarks(benchmark string) error {
return nil
}

type gcpConfig struct {
gcsBucket string
imageRepo string
onbuildBaseImage string
hardlinkBaseImage string
serviceAccount string
dockerMajorVersion int
uploadToGCS bool
}

type imageDetails struct {
name string
numLayers int
Expand All @@ -560,7 +571,6 @@ func initGCPConfig() *gcpConfig {
flag.StringVar(&c.gcsBucket, "bucket", "gs://kaniko-test-bucket", "The gcs bucket argument to uploaded the tar-ed contents of the `integration` dir to.")
flag.StringVar(&c.imageRepo, "repo", "gcr.io/kaniko-test", "The (docker) image repo to build and push images to during the test. `gcloud` must be authenticated with this repo or serviceAccount must be set.")
flag.StringVar(&c.serviceAccount, "serviceAccount", "", "The path to the service account push images to GCR and upload/download files to GCS.")
flag.BoolVar(&c.uploadToGCS, "uploadToGCS", true, "Upload the tar-ed contents of `integration` dir to GCS bucket. Default is true. Set this to false to prevent uploading.")
flag.Parse()

if len(c.serviceAccount) > 0 {
Expand All @@ -575,8 +585,12 @@ func initGCPConfig() *gcpConfig {
os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", absPath)
}

if c.gcsBucket == "" || c.imageRepo == "" {
log.Fatalf("You must provide a gcs bucket (\"%s\" was provided) and a docker repo (\"%s\" was provided)", c.gcsBucket, c.imageRepo)
if c.imageRepo == "" {
log.Fatalf("You must provide a docker repo (\"%s\" was provided)", c.imageRepo)
}

if c.isGcrRepository() && c.gcsBucket == "" {
log.Fatalf("You must provide a gcs bucket (\"%s\" was provided) when using a gcr docker repo (\"%s\" was provided)", c.gcsBucket, c.imageRepo)
}
if !strings.HasSuffix(c.imageRepo, "/") {
c.imageRepo = c.imageRepo + "/"
Expand Down
Loading

0 comments on commit ea48aaf

Please sign in to comment.