From 1c5b6d9bd26ba090610d05366df90d4fee91c677 Mon Sep 17 00:00:00 2001 From: "chris.zn" Date: Tue, 30 Apr 2019 23:35:36 +0800 Subject: Use different pidns among different containers The different containers in a sandbox used only one pid namespace before. This results in that a container can see the processes in another container in the same sandbox. This patch use different pid namespace for different containers. Signed-off-by: chris.zn --- pkg/sentry/control/proc.go | 8 ++- pkg/sentry/kernel/kernel.go | 14 +++-- runsc/boot/fs.go | 1 + runsc/boot/loader.go | 32 ++++++++++- runsc/container/container_test.go | 10 ++++ runsc/container/multi_container_test.go | 98 +++++++++++++++++++++++++++++++++ 6 files changed, 154 insertions(+), 9 deletions(-) diff --git a/pkg/sentry/control/proc.go b/pkg/sentry/control/proc.go index 60e6c9285..3f9772b87 100644 --- a/pkg/sentry/control/proc.go +++ b/pkg/sentry/control/proc.go @@ -92,6 +92,9 @@ type ExecArgs struct { // ContainerID is the container for the process being executed. ContainerID string + + // PIDNamespace is the pid namespace for the process being executed. + PIDNamespace *kernel.PIDNamespace } // String prints the arguments as a string. @@ -162,6 +165,7 @@ func (proc *Proc) execAsync(args *ExecArgs) (*kernel.ThreadGroup, kernel.ThreadI IPCNamespace: proc.Kernel.RootIPCNamespace(), AbstractSocketNamespace: proc.Kernel.RootAbstractSocketNamespace(), ContainerID: args.ContainerID, + PIDNamespace: args.PIDNamespace, } if initArgs.Root != nil { // initArgs must hold a reference on Root, which will be @@ -341,7 +345,7 @@ func Processes(k *kernel.Kernel, containerID string, out *[]*Process) error { ts := k.TaskSet() now := k.RealtimeClock().Now() for _, tg := range ts.Root.ThreadGroups() { - pid := ts.Root.IDOfThreadGroup(tg) + pid := tg.PIDNamespace().IDOfThreadGroup(tg) // If tg has already been reaped ignore it. if pid == 0 { continue @@ -352,7 +356,7 @@ func Processes(k *kernel.Kernel, containerID string, out *[]*Process) error { ppid := kernel.ThreadID(0) if p := tg.Leader().Parent(); p != nil { - ppid = ts.Root.IDOfThreadGroup(p.ThreadGroup()) + ppid = p.PIDNamespace().IDOfThreadGroup(p.ThreadGroup()) } *out = append(*out, &Process{ UID: tg.Leader().Credentials().EffectiveKUID, diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 38b49cba2..70f5a3f0b 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -622,6 +622,9 @@ type CreateProcessArgs struct { // IPCNamespace is the initial IPC namespace. IPCNamespace *IPCNamespace + // PIDNamespace is the initial PID Namespace. + PIDNamespace *PIDNamespace + // AbstractSocketNamespace is the initial Abstract Socket namespace. AbstractSocketNamespace *AbstractSocketNamespace @@ -668,9 +671,7 @@ func (ctx *createProcessContext) Value(key interface{}) interface{} { case CtxKernel: return ctx.k case CtxPIDNamespace: - // "The new task ... is in the root PID namespace." - - // Kernel.CreateProcess - return ctx.k.tasks.Root + return ctx.args.PIDNamespace case CtxUTSNamespace: return ctx.args.UTSNamespace case CtxIPCNamespace: @@ -745,7 +746,7 @@ func (k *Kernel) CreateProcess(args CreateProcessArgs) (*ThreadGroup, ThreadID, mounts.IncRef() } - tg := k.newThreadGroup(mounts, k.tasks.Root, NewSignalHandlers(), linux.SIGCHLD, args.Limits, k.monotonicClock) + tg := k.newThreadGroup(mounts, args.PIDNamespace, NewSignalHandlers(), linux.SIGCHLD, args.Limits, k.monotonicClock) ctx := args.NewContext(k) // Grab the root directory. @@ -1018,6 +1019,11 @@ func (k *Kernel) RootIPCNamespace() *IPCNamespace { return k.rootIPCNamespace } +// RootPIDNamespace returns the root PIDNamespace. +func (k *Kernel) RootPIDNamespace() *PIDNamespace { + return k.tasks.Root +} + // RootAbstractSocketNamespace returns the root AbstractSocketNamespace. func (k *Kernel) RootAbstractSocketNamespace() *AbstractSocketNamespace { return k.rootAbstractSocketNamespace diff --git a/runsc/boot/fs.go b/runsc/boot/fs.go index 55bfc27ff..4bff0d034 100644 --- a/runsc/boot/fs.go +++ b/runsc/boot/fs.go @@ -505,6 +505,7 @@ func (c *containerMounter) setupFS(ctx context.Context, conf *Config, procArgs * Credentials: auth.NewRootCredentials(creds.UserNamespace), Umask: 0022, MaxSymlinkTraversals: linux.MaxSymlinkTraversals, + PIDNamespace: procArgs.PIDNamespace, } rootCtx := rootProcArgs.NewContext(c.k) diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index a8adaf292..b91553c4c 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -138,6 +138,9 @@ type execProcess struct { // tty will be nil if the process is not attached to a terminal. tty *host.TTYFileOperations + + // pidnsPath is the pid namespace path in spec + pidnsPath string } func init() { @@ -298,7 +301,7 @@ func New(args Args) (*Loader, error) { // Create a watchdog. dog := watchdog.New(k, watchdog.DefaultTimeout, args.Conf.WatchdogAction) - procArgs, err := newProcess(args.ID, args.Spec, creds, k) + procArgs, err := newProcess(args.ID, args.Spec, creds, k, k.RootPIDNamespace()) if err != nil { return nil, fmt.Errorf("creating init process for root container: %v", err) } @@ -376,7 +379,7 @@ func New(args Args) (*Loader, error) { } // newProcess creates a process that can be run with kernel.CreateProcess. -func newProcess(id string, spec *specs.Spec, creds *auth.Credentials, k *kernel.Kernel) (kernel.CreateProcessArgs, error) { +func newProcess(id string, spec *specs.Spec, creds *auth.Credentials, k *kernel.Kernel, pidns *kernel.PIDNamespace) (kernel.CreateProcessArgs, error) { // Create initial limits. ls, err := createLimitSet(spec) if err != nil { @@ -396,7 +399,9 @@ func newProcess(id string, spec *specs.Spec, creds *auth.Credentials, k *kernel. IPCNamespace: k.RootIPCNamespace(), AbstractSocketNamespace: k.RootAbstractSocketNamespace(), ContainerID: id, + PIDNamespace: pidns, } + return procArgs, nil } @@ -559,6 +564,9 @@ func (l *Loader) run() error { } ep.tg = l.k.GlobalInit() + if ns, ok := specutils.GetNS(specs.PIDNamespace, l.spec); ok { + ep.pidnsPath = ns.Path + } if l.console { ttyFile, _ := l.rootProcArgs.FDTable.Get(0) defer ttyFile.DecRef() @@ -627,7 +635,24 @@ func (l *Loader) startContainer(spec *specs.Spec, conf *Config, cid string, file caps, l.k.RootUserNamespace()) - procArgs, err := newProcess(cid, spec, creds, l.k) + var pidns *kernel.PIDNamespace + if ns, ok := specutils.GetNS(specs.PIDNamespace, spec); ok { + if ns.Path != "" { + for _, p := range l.processes { + if ns.Path == p.pidnsPath { + pidns = p.tg.PIDNamespace() + break + } + } + } + if pidns == nil { + pidns = l.k.RootPIDNamespace().NewChild(l.k.RootUserNamespace()) + } + l.processes[eid].pidnsPath = ns.Path + } else { + pidns = l.k.RootPIDNamespace() + } + procArgs, err := newProcess(cid, spec, creds, l.k, pidns) if err != nil { return fmt.Errorf("creating new process: %v", err) } @@ -749,6 +774,7 @@ func (l *Loader) executeAsync(args *control.ExecArgs) (kernel.ThreadID, error) { // Start the process. proc := control.Proc{Kernel: l.k} + args.PIDNamespace = tg.PIDNamespace() newTG, tgid, ttyFile, err := control.ExecAsync(&proc, args) if err != nil { return 0, err diff --git a/runsc/container/container_test.go b/runsc/container/container_test.go index c1d6ca7b8..ff68c586e 100644 --- a/runsc/container/container_test.go +++ b/runsc/container/container_test.go @@ -714,6 +714,16 @@ func TestKillPid(t *testing.T) { if err := waitForProcessCount(cont, nProcs-1); err != nil { t.Fatal(err) } + + procs, err = cont.Processes() + if err != nil { + t.Fatalf("failed to get process list: %v", err) + } + for _, p := range procs { + if pid == int32(p.PID) { + t.Fatalf("pid %d is still alive, which should be killed", pid) + } + } } } diff --git a/runsc/container/multi_container_test.go b/runsc/container/multi_container_test.go index e299a0e88..978a422f5 100644 --- a/runsc/container/multi_container_test.go +++ b/runsc/container/multi_container_test.go @@ -165,6 +165,104 @@ func TestMultiContainerSanity(t *testing.T) { } } +// TestMultiPIDNS checks that it is possible to run 2 dead-simple +// containers in the same sandbox with different pidns. +func TestMultiPIDNS(t *testing.T) { + for _, conf := range configs(all...) { + t.Logf("Running test with conf: %+v", conf) + + // Setup the containers. + sleep := []string{"sleep", "100"} + testSpecs, ids := createSpecs(sleep, sleep) + testSpecs[1].Linux = &specs.Linux{ + Namespaces: []specs.LinuxNamespace{ + { + Type: "pid", + }, + }, + } + + containers, cleanup, err := startContainers(conf, testSpecs, ids) + if err != nil { + t.Fatalf("error starting containers: %v", err) + } + defer cleanup() + + // Check via ps that multiple processes are running. + expectedPL := []*control.Process{ + {PID: 1, Cmd: "sleep"}, + } + if err := waitForProcessList(containers[0], expectedPL); err != nil { + t.Errorf("failed to wait for sleep to start: %v", err) + } + expectedPL = []*control.Process{ + {PID: 1, Cmd: "sleep"}, + } + if err := waitForProcessList(containers[1], expectedPL); err != nil { + t.Errorf("failed to wait for sleep to start: %v", err) + } + } +} + +// TestMultiPIDNSPath checks the pidns path. +func TestMultiPIDNSPath(t *testing.T) { + for _, conf := range configs(all...) { + t.Logf("Running test with conf: %+v", conf) + + // Setup the containers. + sleep := []string{"sleep", "100"} + testSpecs, ids := createSpecs(sleep, sleep, sleep) + testSpecs[0].Linux = &specs.Linux{ + Namespaces: []specs.LinuxNamespace{ + { + Type: "pid", + Path: "/proc/1/ns/pid", + }, + }, + } + testSpecs[1].Linux = &specs.Linux{ + Namespaces: []specs.LinuxNamespace{ + { + Type: "pid", + Path: "/proc/1/ns/pid", + }, + }, + } + testSpecs[2].Linux = &specs.Linux{ + Namespaces: []specs.LinuxNamespace{ + { + Type: "pid", + Path: "/proc/2/ns/pid", + }, + }, + } + + containers, cleanup, err := startContainers(conf, testSpecs, ids) + if err != nil { + t.Fatalf("error starting containers: %v", err) + } + defer cleanup() + + // Check via ps that multiple processes are running. + expectedPL := []*control.Process{ + {PID: 1, Cmd: "sleep"}, + } + if err := waitForProcessList(containers[0], expectedPL); err != nil { + t.Errorf("failed to wait for sleep to start: %v", err) + } + if err := waitForProcessList(containers[2], expectedPL); err != nil { + t.Errorf("failed to wait for sleep to start: %v", err) + } + + expectedPL = []*control.Process{ + {PID: 2, Cmd: "sleep"}, + } + if err := waitForProcessList(containers[1], expectedPL); err != nil { + t.Errorf("failed to wait for sleep to start: %v", err) + } + } +} + func TestMultiContainerWait(t *testing.T) { // The first container should run the entire duration of the test. cmd1 := []string{"sleep", "100"} -- cgit v1.2.3 From 444a9d9e545f01dc204f1863e91acb8700823c6e Mon Sep 17 00:00:00 2001 From: Samantha Sample Date: Fri, 26 Jul 2019 10:56:43 -0700 Subject: Publish Dockerfiles and test-runner binaries for running language tests. By following the directions in the README file, these Dockerfiles can be built and used to run native language tests for their respective runtimes. PiperOrigin-RevId: 260174430 --- runsc/test/runtimes/BUILD | 27 +---- runsc/test/runtimes/README.md | 40 +++++++ runsc/test/runtimes/go/BUILD | 8 ++ runsc/test/runtimes/go/Dockerfile | 31 ++++++ runsc/test/runtimes/go/proctor-go.go | 161 +++++++++++++++++++++++++++ runsc/test/runtimes/java/BUILD | 8 ++ runsc/test/runtimes/java/Dockerfile | 52 +++++++++ runsc/test/runtimes/java/proctor-java.go | 110 ++++++++++++++++++ runsc/test/runtimes/nodejs/BUILD | 8 ++ runsc/test/runtimes/nodejs/Dockerfile | 29 +++++ runsc/test/runtimes/nodejs/proctor-nodejs.go | 108 ++++++++++++++++++ runsc/test/runtimes/php/BUILD | 8 ++ runsc/test/runtimes/php/Dockerfile | 29 +++++ runsc/test/runtimes/php/proctor-php.go | 107 ++++++++++++++++++ runsc/test/runtimes/proctor-go.go | 161 --------------------------- runsc/test/runtimes/proctor-java.go | 110 ------------------ runsc/test/runtimes/proctor-nodejs.go | 108 ------------------ runsc/test/runtimes/proctor-php.go | 107 ------------------ runsc/test/runtimes/proctor-python.go | 108 ------------------ runsc/test/runtimes/python/BUILD | 8 ++ runsc/test/runtimes/python/Dockerfile | 31 ++++++ runsc/test/runtimes/python/proctor-python.go | 108 ++++++++++++++++++ 22 files changed, 847 insertions(+), 620 deletions(-) create mode 100644 runsc/test/runtimes/README.md create mode 100644 runsc/test/runtimes/go/BUILD create mode 100644 runsc/test/runtimes/go/Dockerfile create mode 100644 runsc/test/runtimes/go/proctor-go.go create mode 100644 runsc/test/runtimes/java/BUILD create mode 100644 runsc/test/runtimes/java/Dockerfile create mode 100644 runsc/test/runtimes/java/proctor-java.go create mode 100644 runsc/test/runtimes/nodejs/BUILD create mode 100644 runsc/test/runtimes/nodejs/Dockerfile create mode 100644 runsc/test/runtimes/nodejs/proctor-nodejs.go create mode 100644 runsc/test/runtimes/php/BUILD create mode 100644 runsc/test/runtimes/php/Dockerfile create mode 100644 runsc/test/runtimes/php/proctor-php.go delete mode 100644 runsc/test/runtimes/proctor-go.go delete mode 100644 runsc/test/runtimes/proctor-java.go delete mode 100644 runsc/test/runtimes/proctor-nodejs.go delete mode 100644 runsc/test/runtimes/proctor-php.go delete mode 100644 runsc/test/runtimes/proctor-python.go create mode 100644 runsc/test/runtimes/python/BUILD create mode 100644 runsc/test/runtimes/python/Dockerfile create mode 100644 runsc/test/runtimes/python/proctor-python.go diff --git a/runsc/test/runtimes/BUILD b/runsc/test/runtimes/BUILD index 36d0a761e..ea87029dd 100644 --- a/runsc/test/runtimes/BUILD +++ b/runsc/test/runtimes/BUILD @@ -1,6 +1,6 @@ # These packages are used to run language runtime tests inside gVisor sandboxes. -load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library") load("//runsc/test:build_defs.bzl", "runtime_test") package(licenses = ["notice"]) @@ -23,28 +23,3 @@ runtime_test( ], deps = ["//runsc/test/testutil"], ) - -go_binary( - name = "proctor-go", - srcs = ["proctor-go.go"], -) - -go_binary( - name = "proctor-java", - srcs = ["proctor-java.go"], -) - -go_binary( - name = "proctor-nodejs", - srcs = ["proctor-nodejs.go"], -) - -go_binary( - name = "proctor-php", - srcs = ["proctor-php.go"], -) - -go_binary( - name = "proctor-python", - srcs = ["proctor-python.go"], -) diff --git a/runsc/test/runtimes/README.md b/runsc/test/runtimes/README.md new file mode 100644 index 000000000..4e5a950bc --- /dev/null +++ b/runsc/test/runtimes/README.md @@ -0,0 +1,40 @@ +# 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 + +#### Prerequisites: + +1) [Install and configure Docker](https://docs.docker.com/install/) + +2) Build each Docker container: + +```bash +$ docker build -f $LANG/Dockerfile [-t $NAME] . +``` + +### Testing: + +If the prerequisites have been fulfilled, you can run the tests with the +following command: + +```bash +$ docker run --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 <name>: Run a single test from the list of available tests +- --v: Print the language version diff --git a/runsc/test/runtimes/go/BUILD b/runsc/test/runtimes/go/BUILD new file mode 100644 index 000000000..c34f49ea6 --- /dev/null +++ b/runsc/test/runtimes/go/BUILD @@ -0,0 +1,8 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary") + +package(licenses = ["notice"]) + +go_binary( + name = "proctor-go", + srcs = ["proctor-go.go"], +) diff --git a/runsc/test/runtimes/go/Dockerfile b/runsc/test/runtimes/go/Dockerfile new file mode 100644 index 000000000..cd55608cd --- /dev/null +++ b/runsc/test/runtimes/go/Dockerfile @@ -0,0 +1,31 @@ +FROM ubuntu:bionic +ENV LANG_VER=1.12.5 +ENV LANG_NAME=Go + +RUN apt-get update && apt-get install -y \ + curl \ + gcc \ + git + +WORKDIR /root + +# Download Go 1.4 to use as a bootstrap for building Go from the source. +RUN curl -o go1.4.linux-amd64.tar.gz https://dl.google.com/go/go1.4.linux-amd64.tar.gz +RUN curl -LJO https://github.com/golang/go/archive/go${LANG_VER}.tar.gz +RUN mkdir bootstr +RUN tar -C bootstr -xzf go1.4.linux-amd64.tar.gz +RUN tar -xzf go-go${LANG_VER}.tar.gz +RUN mv go-go${LANG_VER} go + +ENV GOROOT=/root/go +ENV GOROOT_BOOTSTRAP=/root/bootstr/go +ENV LANG_DIR=${GOROOT} + +WORKDIR ${LANG_DIR}/src +RUN ./make.bash + +WORKDIR ${LANG_DIR} + +COPY proctor-go.go ${LANG_DIR} + +ENTRYPOINT ["/root/go/bin/go", "run", "proctor-go.go"] diff --git a/runsc/test/runtimes/go/proctor-go.go b/runsc/test/runtimes/go/proctor-go.go new file mode 100644 index 000000000..c5387e21d --- /dev/null +++ b/runsc/test/runtimes/go/proctor-go.go @@ -0,0 +1,161 @@ +// Copyright 2019 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. + +// Binary proctor-go is a utility that facilitates language testing for Go. + +// There are two types of Go tests: "Go tool tests" and "Go tests on disk". +// "Go tool tests" are found and executed using `go tool dist test`. +// "Go tests on disk" are found in the /test directory and are +// executed using `go run run.go`. +package main + +import ( + "flag" + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" + "strings" +) + +var ( + list = flag.Bool("list", false, "list all available tests") + test = flag.String("test", "", "run a single test from the list of available tests") + version = flag.Bool("v", false, "print out the version of node that is installed") + + dir = os.Getenv("LANG_DIR") + testDir = filepath.Join(dir, "test") + testRegEx = regexp.MustCompile(`^.+\.go$`) + + // Directories with .dir contain helper files for tests. + // Exclude benchmarks and stress tests. + exclDirs = regexp.MustCompile(`^.+\/(bench|stress)\/.+$|^.+\.dir.+$`) +) + +func main() { + flag.Parse() + + if *list && *test != "" { + flag.PrintDefaults() + os.Exit(1) + } + if *list { + tests, err := listTests() + if err != nil { + log.Fatalf("Failed to list tests: %v", err) + } + for _, test := range tests { + fmt.Println(test) + } + return + } + if *version { + fmt.Println("Go version: ", os.Getenv("LANG_VER"), " is installed.") + return + } + if *test != "" { + runTest(*test) + return + } + runAllTests() +} + +func listTests() ([]string, error) { + // Go tool dist test tests. + args := []string{"tool", "dist", "test", "-list"} + cmd := exec.Command(filepath.Join(dir, "bin/go"), args...) + cmd.Stderr = os.Stderr + out, err := cmd.Output() + if err != nil { + log.Fatalf("Failed to list: %v", err) + } + var testSlice []string + for _, test := range strings.Split(string(out), "\n") { + testSlice = append(testSlice, test) + } + + // Go tests on disk. + if err := filepath.Walk(testDir, func(path string, info os.FileInfo, err error) error { + name := filepath.Base(path) + + if info.IsDir() { + return nil + } + + if !testRegEx.MatchString(name) { + return nil + } + + if exclDirs.MatchString(path) { + return nil + } + + testSlice = append(testSlice, path) + return nil + }); err != nil { + return nil, fmt.Errorf("walking %q: %v", testDir, err) + } + + return testSlice, nil +} + +func runTest(test string) { + toolArgs := []string{ + "tool", + "dist", + "test", + } + diskArgs := []string{ + "run", + "run.go", + "-v", + } + // Check if test exists on disk by searching for file of the same name. + // This will determine whether or not it is a Go test on disk. + if _, err := os.Stat(test); err == nil { + relPath, err := filepath.Rel(testDir, test) + if err != nil { + log.Fatalf("Failed to get rel path: %v", err) + } + diskArgs = append(diskArgs, "--", relPath) + cmd := exec.Command(filepath.Join(dir, "bin/go"), diskArgs...) + cmd.Dir = testDir + cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr + if err := cmd.Run(); err != nil { + log.Fatalf("Failed to run: %v", err) + } + } else if os.IsNotExist(err) { + // File was not found, try running as Go tool test. + toolArgs = append(toolArgs, "-run", test) + cmd := exec.Command(filepath.Join(dir, "bin/go"), toolArgs...) + cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr + if err := cmd.Run(); err != nil { + log.Fatalf("Failed to run: %v", err) + } + } else { + log.Fatalf("Error searching for test: %v", err) + } +} + +func runAllTests() { + tests, err := listTests() + if err != nil { + log.Fatalf("Failed to list tests: %v", err) + } + for _, test := range tests { + runTest(test) + } +} diff --git a/runsc/test/runtimes/java/BUILD b/runsc/test/runtimes/java/BUILD new file mode 100644 index 000000000..7e2808ece --- /dev/null +++ b/runsc/test/runtimes/java/BUILD @@ -0,0 +1,8 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary") + +package(licenses = ["notice"]) + +go_binary( + name = "proctor-java", + srcs = ["proctor-java.go"], +) diff --git a/runsc/test/runtimes/java/Dockerfile b/runsc/test/runtimes/java/Dockerfile new file mode 100644 index 000000000..e162d7218 --- /dev/null +++ b/runsc/test/runtimes/java/Dockerfile @@ -0,0 +1,52 @@ +FROM ubuntu:bionic +# This hash is associated with a specific JDK release and needed for ensuring +# the same version is downloaded every time. +ENV LANG_HASH=af47e0398606 +ENV LANG_VER=11u-dev +ENV LANG_NAME=Java + +RUN apt-get update && apt-get install -y \ + autoconf \ + build-essential \ + curl\ + file \ + libasound2-dev \ + libcups2-dev \ + libfontconfig1-dev \ + libx11-dev \ + libxext-dev \ + libxrandr-dev \ + libxrender-dev \ + libxt-dev \ + libxtst-dev \ + make \ + unzip \ + zip + +WORKDIR /root +RUN curl -o go.tar.gz https://dl.google.com/go/go1.12.6.linux-amd64.tar.gz +RUN tar -zxf go.tar.gz + +# Use curl instead of ADD to prevent redownload every time. +RUN curl -o jdk.tar.gz http://hg.openjdk.java.net/jdk-updates/jdk${LANG_VER}/archive/${LANG_HASH}.tar.gz +# Download Java version N-1 to be used as the Boot JDK to build Java version N. +RUN curl -o bootjdk.tar.gz https://download.java.net/openjdk/jdk10/ri/openjdk-10+44_linux-x64_bin_ri.tar.gz + +RUN tar -zxf jdk.tar.gz +RUN tar -zxf bootjdk.tar.gz + +# Specify the JDK to be used by jtreg. +ENV JT_JAVA=/root/jdk${LANG_VER}-${LANG_HASH}/build/linux-x86_64-normal-server-release/jdk +ENV LANG_DIR=/root/jdk${LANG_VER}-${LANG_HASH} + +WORKDIR ${LANG_DIR} + +RUN curl -o jtreg.tar.gz https://ci.adoptopenjdk.net/view/Dependencies/job/jtreg/lastSuccessfulBuild/artifact/jtreg-4.2.0-tip.tar.gz +RUN tar -xzf jtreg.tar.gz +RUN bash configure --with-boot-jdk=/root/jdk-10 --with-jtreg=${LANG_DIR}/jtreg +RUN make clean +RUN make images + +COPY proctor-java.go ${LANG_DIR} + +ENTRYPOINT ["/root/go/bin/go", "run", "proctor-java.go"] diff --git a/runsc/test/runtimes/java/proctor-java.go b/runsc/test/runtimes/java/proctor-java.go new file mode 100644 index 000000000..0177f421d --- /dev/null +++ b/runsc/test/runtimes/java/proctor-java.go @@ -0,0 +1,110 @@ +// Copyright 2019 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. + +// Binary proctor-java is a utility that facilitates language testing for Java. +package main + +import ( + "flag" + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" + "strings" +) + +var ( + list = flag.Bool("list", false, "list all available tests") + test = flag.String("test", "", "run a single test from the list of available tests") + version = flag.Bool("v", false, "print out the version of node that is installed") + + dir = os.Getenv("LANG_DIR") + jtreg = filepath.Join(dir, "jtreg/bin/jtreg") + exclDirs = regexp.MustCompile(`(^(sun\/security)|(java\/util\/stream)|(java\/time)| )`) +) + +func main() { + flag.Parse() + + if *list && *test != "" { + flag.PrintDefaults() + os.Exit(1) + } + if *list { + tests, err := listTests() + if err != nil { + log.Fatalf("Failed to list tests: %v", err) + } + for _, test := range tests { + fmt.Println(test) + } + return + } + if *version { + fmt.Println("Java version: ", os.Getenv("LANG_VER"), " is installed.") + return + } + if *test != "" { + runTest(*test) + return + } + runAllTests() +} + +func listTests() ([]string, error) { + args := []string{ + "-dir:test/jdk", + "-ignore:quiet", + "-a", + "-listtests", + ":jdk_core", + ":jdk_svc", + ":jdk_sound", + ":jdk_imageio", + } + cmd := exec.Command(jtreg, args...) + cmd.Stderr = os.Stderr + out, err := cmd.Output() + if err != nil { + return nil, fmt.Errorf("jtreg -listtests : %v", err) + } + var testSlice []string + for _, test := range strings.Split(string(out), "\n") { + if !exclDirs.MatchString(test) { + testSlice = append(testSlice, test) + } + } + return testSlice, nil +} + +func runTest(test string) { + args := []string{"-dir:test/jdk/", test} + cmd := exec.Command(jtreg, args...) + cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr + if err := cmd.Run(); err != nil { + log.Fatalf("Failed to run: %v", err) + } +} + +func runAllTests() { + tests, err := listTests() + if err != nil { + log.Fatalf("Failed to list tests: %v", err) + } + for _, test := range tests { + runTest(test) + } +} diff --git a/runsc/test/runtimes/nodejs/BUILD b/runsc/test/runtimes/nodejs/BUILD new file mode 100644 index 000000000..0fe5ff83e --- /dev/null +++ b/runsc/test/runtimes/nodejs/BUILD @@ -0,0 +1,8 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary") + +package(licenses = ["notice"]) + +go_binary( + name = "proctor-nodejs", + srcs = ["proctor-nodejs.go"], +) diff --git a/runsc/test/runtimes/nodejs/Dockerfile b/runsc/test/runtimes/nodejs/Dockerfile new file mode 100644 index 000000000..b2416cce8 --- /dev/null +++ b/runsc/test/runtimes/nodejs/Dockerfile @@ -0,0 +1,29 @@ +FROM ubuntu:bionic +ENV LANG_VER=12.4.0 +ENV LANG_NAME=Node + +RUN apt-get update && apt-get install -y \ + curl \ + dumb-init \ + g++ \ + make \ + python + +WORKDIR /root +RUN curl -o go.tar.gz https://dl.google.com/go/go1.12.6.linux-amd64.tar.gz +RUN tar -zxf go.tar.gz + +RUN curl -o node-v${LANG_VER}.tar.gz https://nodejs.org/dist/v${LANG_VER}/node-v${LANG_VER}.tar.gz +RUN tar -zxf node-v${LANG_VER}.tar.gz +ENV LANG_DIR=/root/node-v${LANG_VER} + +WORKDIR ${LANG_DIR} +RUN ./configure +RUN make +RUN make test-build + +COPY proctor-nodejs.go ${LANG_DIR} + +# Including dumb-init emulates the Linux "init" process, preventing the failure +# of tests involving worker processes. +ENTRYPOINT ["/usr/bin/dumb-init", "/root/go/bin/go", "run", "proctor-nodejs.go"] diff --git a/runsc/test/runtimes/nodejs/proctor-nodejs.go b/runsc/test/runtimes/nodejs/proctor-nodejs.go new file mode 100644 index 000000000..8ddfb67fe --- /dev/null +++ b/runsc/test/runtimes/nodejs/proctor-nodejs.go @@ -0,0 +1,108 @@ +// Copyright 2019 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. + +// Binary proctor-nodejs is a utility that facilitates language testing for NodeJS. +package main + +import ( + "flag" + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" +) + +var ( + list = flag.Bool("list", false, "list all available tests") + test = flag.String("test", "", "run a single test from the list of available tests") + version = flag.Bool("v", false, "print out the version of node that is installed") + + dir = os.Getenv("LANG_DIR") + testRegEx = regexp.MustCompile(`^test-.+\.js$`) +) + +func main() { + flag.Parse() + + if *list && *test != "" { + flag.PrintDefaults() + os.Exit(1) + } + if *list { + tests, err := listTests() + if err != nil { + log.Fatalf("Failed to list tests: %v", err) + } + for _, test := range tests { + fmt.Println(test) + } + return + } + if *version { + fmt.Println("Node.js version: ", os.Getenv("LANG_VER"), " is installed.") + return + } + if *test != "" { + runTest(*test) + return + } + runAllTests() +} + +func listTests() ([]string, error) { + var testSlice []string + root := filepath.Join(dir, "test") + + err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + name := filepath.Base(path) + + if info.IsDir() || !testRegEx.MatchString(name) { + return nil + } + + relPath, err := filepath.Rel(root, path) + if err != nil { + return err + } + testSlice = append(testSlice, relPath) + return nil + }) + + if err != nil { + return nil, fmt.Errorf("walking %q: %v", root, err) + } + + return testSlice, nil +} + +func runTest(test string) { + args := []string{filepath.Join(dir, "tools", "test.py"), test} + cmd := exec.Command("/usr/bin/python", args...) + cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr + if err := cmd.Run(); err != nil { + log.Fatalf("Failed to run: %v", err) + } +} + +func runAllTests() { + tests, err := listTests() + if err != nil { + log.Fatalf("Failed to list tests: %v", err) + } + for _, test := range tests { + runTest(test) + } +} diff --git a/runsc/test/runtimes/php/BUILD b/runsc/test/runtimes/php/BUILD new file mode 100644 index 000000000..22aef7ba4 --- /dev/null +++ b/runsc/test/runtimes/php/BUILD @@ -0,0 +1,8 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary") + +package(licenses = ["notice"]) + +go_binary( + name = "proctor-php", + srcs = ["proctor-php.go"], +) diff --git a/runsc/test/runtimes/php/Dockerfile b/runsc/test/runtimes/php/Dockerfile new file mode 100644 index 000000000..1f8959b50 --- /dev/null +++ b/runsc/test/runtimes/php/Dockerfile @@ -0,0 +1,29 @@ +FROM ubuntu:bionic +ENV LANG_VER=7.3.6 +ENV LANG_NAME=PHP + +RUN apt-get update && apt-get install -y \ + autoconf \ + automake \ + bison \ + build-essential \ + curl \ + libtool \ + libxml2-dev \ + re2c + +WORKDIR /root +RUN curl -o go.tar.gz https://dl.google.com/go/go1.12.6.linux-amd64.tar.gz +RUN tar -zxf go.tar.gz + +RUN curl -o php-${LANG_VER}.tar.gz https://www.php.net/distributions/php-${LANG_VER}.tar.gz +RUN tar -zxf php-${LANG_VER}.tar.gz +ENV LANG_DIR=/root/php-${LANG_VER} + +WORKDIR ${LANG_DIR} +RUN ./configure +RUN make + +COPY proctor-php.go ${LANG_DIR} + +ENTRYPOINT ["/root/go/bin/go", "run", "proctor-php.go"] diff --git a/runsc/test/runtimes/php/proctor-php.go b/runsc/test/runtimes/php/proctor-php.go new file mode 100644 index 000000000..9dfb33b04 --- /dev/null +++ b/runsc/test/runtimes/php/proctor-php.go @@ -0,0 +1,107 @@ +// Copyright 2019 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. + +// Binary proctor-php is a utility that facilitates language testing for PHP. +package main + +import ( + "flag" + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" +) + +var ( + list = flag.Bool("list", false, "list all available tests") + test = flag.String("test", "", "run a single test from the list of available tests") + version = flag.Bool("v", false, "print out the version of node that is installed") + + dir = os.Getenv("LANG_DIR") + testRegEx = regexp.MustCompile(`^.+\.phpt$`) +) + +func main() { + flag.Parse() + + if *list && *test != "" { + flag.PrintDefaults() + os.Exit(1) + } + if *list { + tests, err := listTests() + if err != nil { + log.Fatalf("Failed to list tests: %v", err) + } + for _, test := range tests { + fmt.Println(test) + } + return + } + if *version { + fmt.Println("PHP version: ", os.Getenv("LANG_VER"), " is installed.") + return + } + if *test != "" { + runTest(*test) + return + } + runAllTests() +} + +func listTests() ([]string, error) { + var testSlice []string + + err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + name := filepath.Base(path) + + if info.IsDir() || !testRegEx.MatchString(name) { + return nil + } + + relPath, err := filepath.Rel(dir, path) + if err != nil { + return err + } + testSlice = append(testSlice, relPath) + return nil + }) + + if err != nil { + return nil, fmt.Errorf("walking %q: %v", dir, err) + } + + return testSlice, nil +} + +func runTest(test string) { + args := []string{"test", "TESTS=" + test} + cmd := exec.Command("make", args...) + cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr + if err := cmd.Run(); err != nil { + log.Fatalf("Failed to run: %v", err) + } +} + +func runAllTests() { + tests, err := listTests() + if err != nil { + log.Fatalf("Failed to list tests: %v", err) + } + for _, test := range tests { + runTest(test) + } +} diff --git a/runsc/test/runtimes/proctor-go.go b/runsc/test/runtimes/proctor-go.go deleted file mode 100644 index c5387e21d..000000000 --- a/runsc/test/runtimes/proctor-go.go +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2019 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. - -// Binary proctor-go is a utility that facilitates language testing for Go. - -// There are two types of Go tests: "Go tool tests" and "Go tests on disk". -// "Go tool tests" are found and executed using `go tool dist test`. -// "Go tests on disk" are found in the /test directory and are -// executed using `go run run.go`. -package main - -import ( - "flag" - "fmt" - "log" - "os" - "os/exec" - "path/filepath" - "regexp" - "strings" -) - -var ( - list = flag.Bool("list", false, "list all available tests") - test = flag.String("test", "", "run a single test from the list of available tests") - version = flag.Bool("v", false, "print out the version of node that is installed") - - dir = os.Getenv("LANG_DIR") - testDir = filepath.Join(dir, "test") - testRegEx = regexp.MustCompile(`^.+\.go$`) - - // Directories with .dir contain helper files for tests. - // Exclude benchmarks and stress tests. - exclDirs = regexp.MustCompile(`^.+\/(bench|stress)\/.+$|^.+\.dir.+$`) -) - -func main() { - flag.Parse() - - if *list && *test != "" { - flag.PrintDefaults() - os.Exit(1) - } - if *list { - tests, err := listTests() - if err != nil { - log.Fatalf("Failed to list tests: %v", err) - } - for _, test := range tests { - fmt.Println(test) - } - return - } - if *version { - fmt.Println("Go version: ", os.Getenv("LANG_VER"), " is installed.") - return - } - if *test != "" { - runTest(*test) - return - } - runAllTests() -} - -func listTests() ([]string, error) { - // Go tool dist test tests. - args := []string{"tool", "dist", "test", "-list"} - cmd := exec.Command(filepath.Join(dir, "bin/go"), args...) - cmd.Stderr = os.Stderr - out, err := cmd.Output() - if err != nil { - log.Fatalf("Failed to list: %v", err) - } - var testSlice []string - for _, test := range strings.Split(string(out), "\n") { - testSlice = append(testSlice, test) - } - - // Go tests on disk. - if err := filepath.Walk(testDir, func(path string, info os.FileInfo, err error) error { - name := filepath.Base(path) - - if info.IsDir() { - return nil - } - - if !testRegEx.MatchString(name) { - return nil - } - - if exclDirs.MatchString(path) { - return nil - } - - testSlice = append(testSlice, path) - return nil - }); err != nil { - return nil, fmt.Errorf("walking %q: %v", testDir, err) - } - - return testSlice, nil -} - -func runTest(test string) { - toolArgs := []string{ - "tool", - "dist", - "test", - } - diskArgs := []string{ - "run", - "run.go", - "-v", - } - // Check if test exists on disk by searching for file of the same name. - // This will determine whether or not it is a Go test on disk. - if _, err := os.Stat(test); err == nil { - relPath, err := filepath.Rel(testDir, test) - if err != nil { - log.Fatalf("Failed to get rel path: %v", err) - } - diskArgs = append(diskArgs, "--", relPath) - cmd := exec.Command(filepath.Join(dir, "bin/go"), diskArgs...) - cmd.Dir = testDir - cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr - if err := cmd.Run(); err != nil { - log.Fatalf("Failed to run: %v", err) - } - } else if os.IsNotExist(err) { - // File was not found, try running as Go tool test. - toolArgs = append(toolArgs, "-run", test) - cmd := exec.Command(filepath.Join(dir, "bin/go"), toolArgs...) - cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr - if err := cmd.Run(); err != nil { - log.Fatalf("Failed to run: %v", err) - } - } else { - log.Fatalf("Error searching for test: %v", err) - } -} - -func runAllTests() { - tests, err := listTests() - if err != nil { - log.Fatalf("Failed to list tests: %v", err) - } - for _, test := range tests { - runTest(test) - } -} diff --git a/runsc/test/runtimes/proctor-java.go b/runsc/test/runtimes/proctor-java.go deleted file mode 100644 index 0177f421d..000000000 --- a/runsc/test/runtimes/proctor-java.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2019 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. - -// Binary proctor-java is a utility that facilitates language testing for Java. -package main - -import ( - "flag" - "fmt" - "log" - "os" - "os/exec" - "path/filepath" - "regexp" - "strings" -) - -var ( - list = flag.Bool("list", false, "list all available tests") - test = flag.String("test", "", "run a single test from the list of available tests") - version = flag.Bool("v", false, "print out the version of node that is installed") - - dir = os.Getenv("LANG_DIR") - jtreg = filepath.Join(dir, "jtreg/bin/jtreg") - exclDirs = regexp.MustCompile(`(^(sun\/security)|(java\/util\/stream)|(java\/time)| )`) -) - -func main() { - flag.Parse() - - if *list && *test != "" { - flag.PrintDefaults() - os.Exit(1) - } - if *list { - tests, err := listTests() - if err != nil { - log.Fatalf("Failed to list tests: %v", err) - } - for _, test := range tests { - fmt.Println(test) - } - return - } - if *version { - fmt.Println("Java version: ", os.Getenv("LANG_VER"), " is installed.") - return - } - if *test != "" { - runTest(*test) - return - } - runAllTests() -} - -func listTests() ([]string, error) { - args := []string{ - "-dir:test/jdk", - "-ignore:quiet", - "-a", - "-listtests", - ":jdk_core", - ":jdk_svc", - ":jdk_sound", - ":jdk_imageio", - } - cmd := exec.Command(jtreg, args...) - cmd.Stderr = os.Stderr - out, err := cmd.Output() - if err != nil { - return nil, fmt.Errorf("jtreg -listtests : %v", err) - } - var testSlice []string - for _, test := range strings.Split(string(out), "\n") { - if !exclDirs.MatchString(test) { - testSlice = append(testSlice, test) - } - } - return testSlice, nil -} - -func runTest(test string) { - args := []string{"-dir:test/jdk/", test} - cmd := exec.Command(jtreg, args...) - cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr - if err := cmd.Run(); err != nil { - log.Fatalf("Failed to run: %v", err) - } -} - -func runAllTests() { - tests, err := listTests() - if err != nil { - log.Fatalf("Failed to list tests: %v", err) - } - for _, test := range tests { - runTest(test) - } -} diff --git a/runsc/test/runtimes/proctor-nodejs.go b/runsc/test/runtimes/proctor-nodejs.go deleted file mode 100644 index 8ddfb67fe..000000000 --- a/runsc/test/runtimes/proctor-nodejs.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2019 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. - -// Binary proctor-nodejs is a utility that facilitates language testing for NodeJS. -package main - -import ( - "flag" - "fmt" - "log" - "os" - "os/exec" - "path/filepath" - "regexp" -) - -var ( - list = flag.Bool("list", false, "list all available tests") - test = flag.String("test", "", "run a single test from the list of available tests") - version = flag.Bool("v", false, "print out the version of node that is installed") - - dir = os.Getenv("LANG_DIR") - testRegEx = regexp.MustCompile(`^test-.+\.js$`) -) - -func main() { - flag.Parse() - - if *list && *test != "" { - flag.PrintDefaults() - os.Exit(1) - } - if *list { - tests, err := listTests() - if err != nil { - log.Fatalf("Failed to list tests: %v", err) - } - for _, test := range tests { - fmt.Println(test) - } - return - } - if *version { - fmt.Println("Node.js version: ", os.Getenv("LANG_VER"), " is installed.") - return - } - if *test != "" { - runTest(*test) - return - } - runAllTests() -} - -func listTests() ([]string, error) { - var testSlice []string - root := filepath.Join(dir, "test") - - err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { - name := filepath.Base(path) - - if info.IsDir() || !testRegEx.MatchString(name) { - return nil - } - - relPath, err := filepath.Rel(root, path) - if err != nil { - return err - } - testSlice = append(testSlice, relPath) - return nil - }) - - if err != nil { - return nil, fmt.Errorf("walking %q: %v", root, err) - } - - return testSlice, nil -} - -func runTest(test string) { - args := []string{filepath.Join(dir, "tools", "test.py"), test} - cmd := exec.Command("/usr/bin/python", args...) - cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr - if err := cmd.Run(); err != nil { - log.Fatalf("Failed to run: %v", err) - } -} - -func runAllTests() { - tests, err := listTests() - if err != nil { - log.Fatalf("Failed to list tests: %v", err) - } - for _, test := range tests { - runTest(test) - } -} diff --git a/runsc/test/runtimes/proctor-php.go b/runsc/test/runtimes/proctor-php.go deleted file mode 100644 index 9dfb33b04..000000000 --- a/runsc/test/runtimes/proctor-php.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2019 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. - -// Binary proctor-php is a utility that facilitates language testing for PHP. -package main - -import ( - "flag" - "fmt" - "log" - "os" - "os/exec" - "path/filepath" - "regexp" -) - -var ( - list = flag.Bool("list", false, "list all available tests") - test = flag.String("test", "", "run a single test from the list of available tests") - version = flag.Bool("v", false, "print out the version of node that is installed") - - dir = os.Getenv("LANG_DIR") - testRegEx = regexp.MustCompile(`^.+\.phpt$`) -) - -func main() { - flag.Parse() - - if *list && *test != "" { - flag.PrintDefaults() - os.Exit(1) - } - if *list { - tests, err := listTests() - if err != nil { - log.Fatalf("Failed to list tests: %v", err) - } - for _, test := range tests { - fmt.Println(test) - } - return - } - if *version { - fmt.Println("PHP version: ", os.Getenv("LANG_VER"), " is installed.") - return - } - if *test != "" { - runTest(*test) - return - } - runAllTests() -} - -func listTests() ([]string, error) { - var testSlice []string - - err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - name := filepath.Base(path) - - if info.IsDir() || !testRegEx.MatchString(name) { - return nil - } - - relPath, err := filepath.Rel(dir, path) - if err != nil { - return err - } - testSlice = append(testSlice, relPath) - return nil - }) - - if err != nil { - return nil, fmt.Errorf("walking %q: %v", dir, err) - } - - return testSlice, nil -} - -func runTest(test string) { - args := []string{"test", "TESTS=" + test} - cmd := exec.Command("make", args...) - cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr - if err := cmd.Run(); err != nil { - log.Fatalf("Failed to run: %v", err) - } -} - -func runAllTests() { - tests, err := listTests() - if err != nil { - log.Fatalf("Failed to list tests: %v", err) - } - for _, test := range tests { - runTest(test) - } -} diff --git a/runsc/test/runtimes/proctor-python.go b/runsc/test/runtimes/proctor-python.go deleted file mode 100644 index 73c8deb49..000000000 --- a/runsc/test/runtimes/proctor-python.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2019 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. - -// Binary proctor-python is a utility that facilitates language testing for Pyhton. -package main - -import ( - "flag" - "fmt" - "log" - "os" - "os/exec" - "path/filepath" - "regexp" -) - -var ( - list = flag.Bool("list", false, "list all available tests") - test = flag.String("test", "", "run a single test from the list of available tests") - version = flag.Bool("v", false, "print out the version of node that is installed") - - dir = os.Getenv("LANG_DIR") - testRegEx = regexp.MustCompile(`^test_.+\.py$`) -) - -func main() { - flag.Parse() - - if *list && *test != "" { - flag.PrintDefaults() - os.Exit(1) - } - if *list { - tests, err := listTests() - if err != nil { - log.Fatalf("Failed to list tests: %v", err) - } - for _, test := range tests { - fmt.Println(test) - } - return - } - if *version { - fmt.Println("Python version: ", os.Getenv("LANG_VER"), " is installed.") - return - } - if *test != "" { - runTest(*test) - return - } - runAllTests() -} - -func listTests() ([]string, error) { - var testSlice []string - root := filepath.Join(dir, "Lib/test") - - err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { - name := filepath.Base(path) - - if info.IsDir() || !testRegEx.MatchString(name) { - return nil - } - - relPath, err := filepath.Rel(root, path) - if err != nil { - return err - } - testSlice = append(testSlice, relPath) - return nil - }) - - if err != nil { - return nil, fmt.Errorf("walking %q: %v", root, err) - } - - return testSlice, nil -} - -func runTest(test string) { - args := []string{"-m", "test", test} - cmd := exec.Command(filepath.Join(dir, "python"), args...) - cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr - if err := cmd.Run(); err != nil { - log.Fatalf("Failed to run: %v", err) - } -} - -func runAllTests() { - tests, err := listTests() - if err != nil { - log.Fatalf("Failed to list tests: %v", err) - } - for _, test := range tests { - runTest(test) - } -} diff --git a/runsc/test/runtimes/python/BUILD b/runsc/test/runtimes/python/BUILD new file mode 100644 index 000000000..501f77d63 --- /dev/null +++ b/runsc/test/runtimes/python/BUILD @@ -0,0 +1,8 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary") + +package(licenses = ["notice"]) + +go_binary( + name = "proctor-python", + srcs = ["proctor-python.go"], +) diff --git a/runsc/test/runtimes/python/Dockerfile b/runsc/test/runtimes/python/Dockerfile new file mode 100644 index 000000000..811f48f8a --- /dev/null +++ b/runsc/test/runtimes/python/Dockerfile @@ -0,0 +1,31 @@ +FROM ubuntu:bionic +ENV LANG_VER=3.7.3 +ENV LANG_NAME=Python + +RUN apt-get update && apt-get install -y \ + curl \ + gcc \ + libbz2-dev \ + libffi-dev \ + liblzma-dev \ + libreadline-dev \ + libssl-dev \ + make \ + zlib1g-dev + +WORKDIR /root +RUN curl -o go.tar.gz https://dl.google.com/go/go1.12.6.linux-amd64.tar.gz +RUN tar -zxf go.tar.gz + +# Use flags -LJO to follow the html redirect and download .tar.gz. +RUN curl -LJO https://github.com/python/cpython/archive/v${LANG_VER}.tar.gz +RUN tar -zxf cpython-${LANG_VER}.tar.gz +ENV LANG_DIR=/root/cpython-${LANG_VER} + +WORKDIR ${LANG_DIR} +RUN ./configure --with-pydebug +RUN make -s -j2 + +COPY proctor-python.go ${LANG_DIR} + +ENTRYPOINT ["/root/go/bin/go", "run", "proctor-python.go"] diff --git a/runsc/test/runtimes/python/proctor-python.go b/runsc/test/runtimes/python/proctor-python.go new file mode 100644 index 000000000..73c8deb49 --- /dev/null +++ b/runsc/test/runtimes/python/proctor-python.go @@ -0,0 +1,108 @@ +// Copyright 2019 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. + +// Binary proctor-python is a utility that facilitates language testing for Pyhton. +package main + +import ( + "flag" + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" +) + +var ( + list = flag.Bool("list", false, "list all available tests") + test = flag.String("test", "", "run a single test from the list of available tests") + version = flag.Bool("v", false, "print out the version of node that is installed") + + dir = os.Getenv("LANG_DIR") + testRegEx = regexp.MustCompile(`^test_.+\.py$`) +) + +func main() { + flag.Parse() + + if *list && *test != "" { + flag.PrintDefaults() + os.Exit(1) + } + if *list { + tests, err := listTests() + if err != nil { + log.Fatalf("Failed to list tests: %v", err) + } + for _, test := range tests { + fmt.Println(test) + } + return + } + if *version { + fmt.Println("Python version: ", os.Getenv("LANG_VER"), " is installed.") + return + } + if *test != "" { + runTest(*test) + return + } + runAllTests() +} + +func listTests() ([]string, error) { + var testSlice []string + root := filepath.Join(dir, "Lib/test") + + err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + name := filepath.Base(path) + + if info.IsDir() || !testRegEx.MatchString(name) { + return nil + } + + relPath, err := filepath.Rel(root, path) + if err != nil { + return err + } + testSlice = append(testSlice, relPath) + return nil + }) + + if err != nil { + return nil, fmt.Errorf("walking %q: %v", root, err) + } + + return testSlice, nil +} + +func runTest(test string) { + args := []string{"-m", "test", test} + cmd := exec.Command(filepath.Join(dir, "python"), args...) + cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr + if err := cmd.Run(); err != nil { + log.Fatalf("Failed to run: %v", err) + } +} + +func runAllTests() { + tests, err := listTests() + if err != nil { + log.Fatalf("Failed to list tests: %v", err) + } + for _, test := range tests { + runTest(test) + } +} -- cgit v1.2.3