summaryrefslogtreecommitdiffhomepage
path: root/test/runtimes
diff options
context:
space:
mode:
authorAdin Scannell <ascannell@google.com>2020-04-23 11:32:08 -0700
committergVisor bot <gvisor-bot@google.com>2020-04-23 11:33:30 -0700
commit1481499fe27157ad2716c00682f6ad819115a6c7 (patch)
treef89a7643f5e7272494ccd3de5681e3445e0ed00a /test/runtimes
parente0c67014cb2200ad58cd28b12fddb3f55652a21b (diff)
Simplify Docker test infrastructure.
This change adds a layer of abstraction around the internal Docker APIs, and eliminates all direct dependencies on Dockerfiles in the infrastructure. A subsequent change will automated the generation of local images (with efficient caching). Note that this change drops the use of bazel container rules, as that experiment does not seem to be viable. PiperOrigin-RevId: 308095430
Diffstat (limited to 'test/runtimes')
-rw-r--r--test/runtimes/BUILD22
-rw-r--r--test/runtimes/README.md56
-rw-r--r--test/runtimes/build_defs.bzl75
-rw-r--r--test/runtimes/defs.bzl79
-rw-r--r--test/runtimes/proctor/BUILD (renamed from test/runtimes/images/proctor/BUILD)5
-rw-r--r--test/runtimes/proctor/go.go (renamed from test/runtimes/images/proctor/go.go)0
-rw-r--r--test/runtimes/proctor/java.go (renamed from test/runtimes/images/proctor/java.go)0
-rw-r--r--test/runtimes/proctor/nodejs.go (renamed from test/runtimes/images/proctor/nodejs.go)0
-rw-r--r--test/runtimes/proctor/php.go (renamed from test/runtimes/images/proctor/php.go)0
-rw-r--r--test/runtimes/proctor/proctor.go (renamed from test/runtimes/images/proctor/proctor.go)0
-rw-r--r--test/runtimes/proctor/proctor_test.go (renamed from test/runtimes/images/proctor/proctor_test.go)14
-rw-r--r--test/runtimes/proctor/python.go (renamed from test/runtimes/images/proctor/python.go)0
-rwxr-xr-xtest/runtimes/runner.sh35
-rw-r--r--test/runtimes/runner/BUILD21
-rw-r--r--test/runtimes/runner/blacklist_test.go (renamed from test/runtimes/blacklist_test.go)0
-rw-r--r--test/runtimes/runner/main.go (renamed from test/runtimes/runner.go)37
16 files changed, 126 insertions, 218 deletions
diff --git a/test/runtimes/BUILD b/test/runtimes/BUILD
index 2c472bf8d..4cd627222 100644
--- a/test/runtimes/BUILD
+++ b/test/runtimes/BUILD
@@ -1,20 +1,7 @@
-# These packages are used to run language runtime tests inside gVisor sandboxes.
-
-load("//tools:defs.bzl", "go_binary", "go_test")
-load("//test/runtimes:build_defs.bzl", "runtime_test")
+load("//test/runtimes:defs.bzl", "runtime_test")
package(licenses = ["notice"])
-go_binary(
- name = "runner",
- testonly = 1,
- srcs = ["runner.go"],
- deps = [
- "//runsc/dockerutil",
- "//runsc/testutil",
- ],
-)
-
runtime_test(
name = "go1.12",
blacklist_file = "blacklist_go1.12.csv",
@@ -44,10 +31,3 @@ runtime_test(
blacklist_file = "blacklist_python3.7.3.csv",
lang = "python",
)
-
-go_test(
- name = "blacklist_test",
- size = "small",
- srcs = ["blacklist_test.go"],
- library = ":runner",
-)
diff --git a/test/runtimes/README.md b/test/runtimes/README.md
deleted file mode 100644
index 42d722553..000000000
--- a/test/runtimes/README.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# Runtimes Tests Dockerfiles
-
-The Dockerfiles defined under this path are configured to host the execution of
-the runtimes language tests. Each Dockerfile can support the language indicated
-by its directory.
-
-The following runtimes are currently supported:
-
-- Go 1.12
-- Java 11
-- Node.js 12
-- PHP 7.3
-- Python 3.7
-
-### Building and pushing the images:
-
-The canonical source of images is the
-[gvisor-presubmit container registry](https://gcr.io/gvisor-presubmit/). You can
-build new images with the following command:
-
-```bash
-$ cd images
-$ docker build -f Dockerfile_$LANG [-t $NAME] .
-```
-
-To push them to our container registry, set the tag in the command above to
-`gcr.io/gvisor-presubmit/$LANG`, then push them. (Note that you will need
-appropriate permissions to the `gvisor-presubmit` GCP project.)
-
-```bash
-gcloud docker -- push gcr.io/gvisor-presubmit/$LANG
-```
-
-#### Running in Docker locally:
-
-1) [Install and configure Docker](https://docs.docker.com/install/)
-
-2) Pull the image you want to run:
-
-```bash
-$ docker pull gcr.io/gvisor-presubmit/$LANG
-```
-
-3) Run docker with the image.
-
-```bash
-$ docker run [--runtime=runsc] --rm -it $NAME [FLAG]
-```
-
-Running the command with no flags will cause all the available tests to execute.
-
-Flags can be added for additional functionality:
-
-- --list: Print a list of all available tests
-- --test &lt;name&gt;: Run a single test from the list of available tests
-- --v: Print the language version
diff --git a/test/runtimes/build_defs.bzl b/test/runtimes/build_defs.bzl
deleted file mode 100644
index 92e275a76..000000000
--- a/test/runtimes/build_defs.bzl
+++ /dev/null
@@ -1,75 +0,0 @@
-"""Defines a rule for runtime test targets."""
-
-load("//tools:defs.bzl", "go_test", "loopback")
-
-def runtime_test(
- name,
- lang,
- image_repo = "gcr.io/gvisor-presubmit",
- image_name = None,
- blacklist_file = None,
- shard_count = 50,
- size = "enormous"):
- """Generates sh_test and blacklist test targets for a given runtime.
-
- Args:
- name: The name of the runtime being tested. Typically, the lang + version.
- This is used in the names of the generated test targets.
- lang: The language being tested.
- image_repo: The docker repository containing the proctor image to run.
- i.e., the prefix to the fully qualified docker image id.
- image_name: The name of the image in the image_repo.
- Defaults to the test name.
- blacklist_file: A test blacklist to pass to the runtime test's runner.
- shard_count: See Bazel common test attributes.
- size: See Bazel common test attributes.
- """
- if image_name == None:
- image_name = name
- args = [
- "--lang",
- lang,
- "--image",
- "/".join([image_repo, image_name]),
- ]
- data = [
- ":runner",
- loopback,
- ]
- if blacklist_file:
- args += ["--blacklist_file", "test/runtimes/" + blacklist_file]
- data += [blacklist_file]
-
- # Add a test that the blacklist parses correctly.
- blacklist_test(name, blacklist_file)
-
- sh_test(
- name = name + "_test",
- srcs = ["runner.sh"],
- args = args,
- data = data,
- size = size,
- shard_count = shard_count,
- tags = [
- # Requires docker and runsc to be configured before the test runs.
- "local",
- # Don't include test target in wildcard target patterns.
- "manual",
- ],
- )
-
-def blacklist_test(name, blacklist_file):
- """Test that a blacklist parses correctly."""
- go_test(
- name = name + "_blacklist_test",
- library = ":runner",
- srcs = ["blacklist_test.go"],
- args = ["--blacklist_file", "test/runtimes/" + blacklist_file],
- data = [blacklist_file],
- )
-
-def sh_test(**kwargs):
- """Wraps the standard sh_test."""
- native.sh_test(
- **kwargs
- )
diff --git a/test/runtimes/defs.bzl b/test/runtimes/defs.bzl
new file mode 100644
index 000000000..f836dd952
--- /dev/null
+++ b/test/runtimes/defs.bzl
@@ -0,0 +1,79 @@
+"""Defines a rule for runtime test targets."""
+
+load("//tools:defs.bzl", "go_test")
+
+def _runtime_test_impl(ctx):
+ # Construct arguments.
+ args = [
+ "--lang",
+ ctx.attr.lang,
+ "--image",
+ ctx.attr.image,
+ ]
+ if ctx.attr.blacklist_file:
+ args += [
+ "--blacklist_file",
+ ctx.files.blacklist_file[0].short_path,
+ ]
+
+ # Build a runner.
+ runner = ctx.actions.declare_file("%s-executer" % ctx.label.name)
+ runner_content = "\n".join([
+ "#!/bin/bash",
+ "%s %s\n" % (ctx.files._runner[0].short_path, " ".join(args)),
+ ])
+ ctx.actions.write(runner, runner_content, is_executable = True)
+
+ # Return the runner.
+ return [DefaultInfo(
+ executable = runner,
+ runfiles = ctx.runfiles(
+ files = ctx.files._runner + ctx.files.blacklist_file + ctx.files._proctor,
+ collect_default = True,
+ collect_data = True,
+ ),
+ )]
+
+_runtime_test = rule(
+ implementation = _runtime_test_impl,
+ attrs = {
+ "image": attr.string(
+ mandatory = False,
+ ),
+ "lang": attr.string(
+ mandatory = True,
+ ),
+ "blacklist_file": attr.label(
+ mandatory = False,
+ allow_single_file = True,
+ ),
+ "_runner": attr.label(
+ default = "//test/runtimes/runner:runner",
+ ),
+ "_proctor": attr.label(
+ default = "//test/runtimes/proctor:proctor",
+ ),
+ },
+ test = True,
+)
+
+def runtime_test(name, **kwargs):
+ _runtime_test(
+ name = name,
+ image = name, # Resolved as images/runtimes/%s.
+ tags = [
+ "local",
+ "manual",
+ ],
+ **kwargs
+ )
+
+def blacklist_test(name, blacklist_file):
+ """Test that a blacklist parses correctly."""
+ go_test(
+ name = name + "_blacklist_test",
+ library = ":runner",
+ srcs = ["blacklist_test.go"],
+ args = ["--blacklist_file", "test/runtimes/" + blacklist_file],
+ data = [blacklist_file],
+ )
diff --git a/test/runtimes/images/proctor/BUILD b/test/runtimes/proctor/BUILD
index 85e004c45..50a26d182 100644
--- a/test/runtimes/images/proctor/BUILD
+++ b/test/runtimes/proctor/BUILD
@@ -12,7 +12,8 @@ go_binary(
"proctor.go",
"python.go",
],
- visibility = ["//test/runtimes/images:__subpackages__"],
+ pure = True,
+ visibility = ["//test/runtimes:__pkg__"],
)
go_test(
@@ -21,6 +22,6 @@ go_test(
srcs = ["proctor_test.go"],
library = ":proctor",
deps = [
- "//runsc/testutil",
+ "//pkg/test/testutil",
],
)
diff --git a/test/runtimes/images/proctor/go.go b/test/runtimes/proctor/go.go
index 3e2d5d8db..3e2d5d8db 100644
--- a/test/runtimes/images/proctor/go.go
+++ b/test/runtimes/proctor/go.go
diff --git a/test/runtimes/images/proctor/java.go b/test/runtimes/proctor/java.go
index 8b362029d..8b362029d 100644
--- a/test/runtimes/images/proctor/java.go
+++ b/test/runtimes/proctor/java.go
diff --git a/test/runtimes/images/proctor/nodejs.go b/test/runtimes/proctor/nodejs.go
index bd57db444..bd57db444 100644
--- a/test/runtimes/images/proctor/nodejs.go
+++ b/test/runtimes/proctor/nodejs.go
diff --git a/test/runtimes/images/proctor/php.go b/test/runtimes/proctor/php.go
index 9115040e1..9115040e1 100644
--- a/test/runtimes/images/proctor/php.go
+++ b/test/runtimes/proctor/php.go
diff --git a/test/runtimes/images/proctor/proctor.go b/test/runtimes/proctor/proctor.go
index b54abe434..b54abe434 100644
--- a/test/runtimes/images/proctor/proctor.go
+++ b/test/runtimes/proctor/proctor.go
diff --git a/test/runtimes/images/proctor/proctor_test.go b/test/runtimes/proctor/proctor_test.go
index 6bb61d142..6ef2de085 100644
--- a/test/runtimes/images/proctor/proctor_test.go
+++ b/test/runtimes/proctor/proctor_test.go
@@ -23,24 +23,24 @@ import (
"strings"
"testing"
- "gvisor.dev/gvisor/runsc/testutil"
+ "gvisor.dev/gvisor/pkg/test/testutil"
)
func touch(t *testing.T, name string) {
t.Helper()
f, err := os.Create(name)
if err != nil {
- t.Fatal(err)
+ t.Fatalf("error creating file %q: %v", name, err)
}
if err := f.Close(); err != nil {
- t.Fatal(err)
+ t.Fatalf("error closing file %q: %v", name, err)
}
}
func TestSearchEmptyDir(t *testing.T) {
td, err := ioutil.TempDir(testutil.TmpDir(), "searchtest")
if err != nil {
- t.Fatal(err)
+ t.Fatalf("error creating searchtest: %v", err)
}
defer os.RemoveAll(td)
@@ -60,7 +60,7 @@ func TestSearchEmptyDir(t *testing.T) {
func TestSearch(t *testing.T) {
td, err := ioutil.TempDir(testutil.TmpDir(), "searchtest")
if err != nil {
- t.Fatal(err)
+ t.Fatalf("error creating searchtest: %v", err)
}
defer os.RemoveAll(td)
@@ -101,14 +101,14 @@ func TestSearch(t *testing.T) {
if strings.HasSuffix(item, "/") {
// This item is a directory, create it.
if err := os.MkdirAll(filepath.Join(td, item), 0755); err != nil {
- t.Fatal(err)
+ t.Fatalf("error making directory: %v", err)
}
} else {
// This item is a file, create the directory and touch file.
// Create directory in which file should be created
fullDirPath := filepath.Join(td, filepath.Dir(item))
if err := os.MkdirAll(fullDirPath, 0755); err != nil {
- t.Fatal(err)
+ t.Fatalf("error making directory: %v", err)
}
// Create file with full path to file.
touch(t, filepath.Join(td, item))
diff --git a/test/runtimes/images/proctor/python.go b/test/runtimes/proctor/python.go
index b9e0fbe6f..b9e0fbe6f 100644
--- a/test/runtimes/images/proctor/python.go
+++ b/test/runtimes/proctor/python.go
diff --git a/test/runtimes/runner.sh b/test/runtimes/runner.sh
deleted file mode 100755
index a8d9a3460..000000000
--- a/test/runtimes/runner.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-
-# Copyright 2018 The gVisor Authors.
-#
-# 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.
-
-set -euf -x -o pipefail
-
-echo -- "$@"
-
-# Create outputs dir if it does not exist.
-if [[ -n "${TEST_UNDECLARED_OUTPUTS_DIR}" ]]; then
- mkdir -p "${TEST_UNDECLARED_OUTPUTS_DIR}"
- chmod a+rwx "${TEST_UNDECLARED_OUTPUTS_DIR}"
-fi
-
-# Update the timestamp on the shard status file. Bazel looks for this.
-touch "${TEST_SHARD_STATUS_FILE}"
-
-# Get location of runner binary.
-readonly runner=$(find "${TEST_SRCDIR}" -name runner)
-
-# Pass the arguments of this script directly to the runner.
-exec "${runner}" "$@"
-
diff --git a/test/runtimes/runner/BUILD b/test/runtimes/runner/BUILD
new file mode 100644
index 000000000..63924b9c5
--- /dev/null
+++ b/test/runtimes/runner/BUILD
@@ -0,0 +1,21 @@
+load("//tools:defs.bzl", "go_binary", "go_test")
+
+package(licenses = ["notice"])
+
+go_binary(
+ name = "runner",
+ testonly = 1,
+ srcs = ["main.go"],
+ visibility = ["//test/runtimes:__pkg__"],
+ deps = [
+ "//pkg/test/dockerutil",
+ "//pkg/test/testutil",
+ ],
+)
+
+go_test(
+ name = "blacklist_test",
+ size = "small",
+ srcs = ["blacklist_test.go"],
+ library = ":runner",
+)
diff --git a/test/runtimes/blacklist_test.go b/test/runtimes/runner/blacklist_test.go
index 0ff69ab18..0ff69ab18 100644
--- a/test/runtimes/blacklist_test.go
+++ b/test/runtimes/runner/blacklist_test.go
diff --git a/test/runtimes/runner.go b/test/runtimes/runner/main.go
index 3c98f4570..57540e00e 100644
--- a/test/runtimes/runner.go
+++ b/test/runtimes/runner/main.go
@@ -26,8 +26,8 @@ import (
"testing"
"time"
- "gvisor.dev/gvisor/runsc/dockerutil"
- "gvisor.dev/gvisor/runsc/testutil"
+ "gvisor.dev/gvisor/pkg/test/dockerutil"
+ "gvisor.dev/gvisor/pkg/test/testutil"
)
var (
@@ -45,7 +45,6 @@ func main() {
fmt.Fprintf(os.Stderr, "lang and image flags must not be empty\n")
os.Exit(1)
}
-
os.Exit(runTests())
}
@@ -60,8 +59,8 @@ func runTests() int {
return 1
}
- // Create a single docker container that will be used for all tests.
- d := dockerutil.MakeDocker("gvisor-" + *lang)
+ // Construct the shared docker instance.
+ d := dockerutil.MakeDocker(testutil.DefaultLogger(*lang))
defer d.CleanUp()
// Get a slice of tests to run. This will also start a single Docker
@@ -77,21 +76,18 @@ func runTests() int {
return m.Run()
}
-// getTests returns a slice of tests to run, subject to the shard size and
-// index.
-func getTests(d dockerutil.Docker, blacklist map[string]struct{}) ([]testing.InternalTest, error) {
- // Pull the image.
- if err := dockerutil.Pull(*image); err != nil {
- return nil, fmt.Errorf("docker pull %q failed: %v", *image, err)
- }
-
- // Run proctor with --pause flag to keep container alive forever.
- if err := d.Run(*image, "--pause"); err != nil {
+// getTests executes all tests as table tests.
+func getTests(d *dockerutil.Docker, blacklist map[string]struct{}) ([]testing.InternalTest, error) {
+ // Start the container.
+ d.CopyFiles("/proctor", "test/runtimes/proctor/proctor")
+ if err := d.Spawn(dockerutil.RunOpts{
+ Image: fmt.Sprintf("runtimes/%s", *image),
+ }, "/proctor/proctor", "--pause"); err != nil {
return nil, fmt.Errorf("docker run failed: %v", err)
}
// Get a list of all tests in the image.
- list, err := d.Exec("/proctor", "--runtime", *lang, "--list")
+ list, err := d.Exec(dockerutil.RunOpts{}, "/proctor/proctor", "--runtime", *lang, "--list")
if err != nil {
return nil, fmt.Errorf("docker exec failed: %v", err)
}
@@ -126,7 +122,7 @@ func getTests(d dockerutil.Docker, blacklist map[string]struct{}) ([]testing.Int
go func() {
fmt.Printf("RUNNING %s...\n", tc)
- output, err = d.Exec("/proctor", "--runtime", *lang, "--test", tc)
+ output, err = d.Exec(dockerutil.RunOpts{}, "/proctor/proctor", "--runtime", *lang, "--test", tc)
close(done)
}()
@@ -143,6 +139,7 @@ func getTests(d dockerutil.Docker, blacklist map[string]struct{}) ([]testing.Int
},
})
}
+
return itests, nil
}
@@ -153,11 +150,7 @@ func getBlacklist() (map[string]struct{}, error) {
if *blacklistFile == "" {
return blacklist, nil
}
- file, err := testutil.FindFile(*blacklistFile)
- if err != nil {
- return nil, err
- }
- f, err := os.Open(file)
+ f, err := os.Open(*blacklistFile)
if err != nil {
return nil, err
}