Skip to content
This repository has been archived by the owner on Apr 21, 2021. It is now read-only.

Commit

Permalink
Merge pull request opencontainers#636 from kinvolk/dongsu/test-path-m…
Browse files Browse the repository at this point in the history
…atch-type

validation: add a new test for NSPathMatchTypeError
  • Loading branch information
Zhou Hao authored May 30, 2018
2 parents 9b65419 + 1fb00d9 commit 128c588
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 16 deletions.
17 changes: 1 addition & 16 deletions validation/linux_ns_path.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,6 @@ import (
"github.com/opencontainers/runtime-tools/validation/util"
)

func getRuntimeToolsNamespace(ns string) string {
// Deal with exceptional cases of "net" and "mnt", because those strings
// cannot be recognized by mapStrToNamespace(), which actually expects
// "network" and "mount" respectively.
switch ns {
case "net":
return "network"
case "mnt":
return "mount"
}

// In other cases, return just the original string
return ns
}

func waitForState(stateCheckFunc func() error) error {
timeout := 3 * time.Second
alarm := time.After(timeout)
Expand Down Expand Up @@ -104,7 +89,7 @@ func checkNamespacePath(unsharePid int, ns string) error {
return fmt.Errorf("cannot get the default generator: %v", err)
}

rtns := getRuntimeToolsNamespace(ns)
rtns := util.GetRuntimeToolsNamespace(ns)
g.AddOrReplaceLinuxNamespace(rtns, unshareNsPath)

return util.RuntimeOutsideValidate(g, func(config *rspec.Spec, state *rspec.State) error {
Expand Down
105 changes: 105 additions & 0 deletions validation/linux_ns_path_type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package main

import (
"fmt"
"os/exec"
"runtime"
"syscall"

"github.com/mndrix/tap-go"
rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/specerror"
"github.com/opencontainers/runtime-tools/validation/util"
)

func checkNSPathMatchType(t *tap.T, ns, wrongNs string) error {
// Deliberately set ns path with a wrong namespace, to check if the runtime
// returns error when running with the wrong namespace path.
unshareNsPath := fmt.Sprintf("/proc/self/ns/%s", wrongNs)

g, err := util.GetDefaultGenerator()
if err != nil {
return fmt.Errorf("cannot get default config from generator: %v", err)
}

rtns := util.GetRuntimeToolsNamespace(ns)
g.AddOrReplaceLinuxNamespace(rtns, unshareNsPath)

err = util.RuntimeOutsideValidate(g, nil)

t.Ok(err != nil, fmt.Sprintf("got error when setting a wrong namespace path %q with type %s", unshareNsPath, rtns))
if err == nil {
rfcError, errRfc := specerror.NewRFCError(specerror.NSPathMatchTypeError,
fmt.Errorf("got no error when setting a wrong namespace path %q with type %s", unshareNsPath, rtns),
rspec.Version)
if errRfc != nil {
return fmt.Errorf("cannot get new rfcError: %v", errRfc)
}
diagnostic := map[string]string{
"expected": fmt.Sprintf("err == %v", err),
"actual": "err == nil",
"namespace type": rtns,
"level": rfcError.Level.String(),
"reference": rfcError.Reference,
}
t.YAML(diagnostic)

return fmt.Errorf("cannot validate path with wrong type")
}

return nil
}

func testNSPathMatchType(t *tap.T, ns, unshareOpt, wrongNs string) error {
// Calling 'unshare' (part of util-linux) is easier than doing it from
// Golang: mnt namespaces cannot be unshared from multithreaded
// programs.
cmd := exec.Command("unshare", unshareOpt, "--fork", "sleep", "10000")
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
err := cmd.Start()
if err != nil {
return fmt.Errorf("cannot run unshare: %s", err)
}
defer func() {
if cmd.Process != nil {
cmd.Process.Kill()
}
cmd.Wait()
syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
}()
if cmd.Process == nil {
return fmt.Errorf("process failed to start")
}

return checkNSPathMatchType(t, ns, wrongNs)
}

func main() {
t := tap.New()
t.Header(0)

cases := []struct {
name string
unshareOpt string
wrongname string
}{
{"cgroup", "--cgroup", "ipc"},
{"ipc", "--ipc", "mnt"},
{"mnt", "--mount", "net"},
{"net", "--net", "pid"},
{"pid", "--pid", "user"},
{"user", "--user", "uts"},
{"uts", "--uts", "cgroup"},
}

for _, c := range cases {
if "linux" != runtime.GOOS {
t.Skip(1, fmt.Sprintf("linux-specific namespace test: %s", c))
}

err := testNSPathMatchType(t, c.name, c.unshareOpt, c.wrongname)
t.Ok(err == nil, fmt.Sprintf("namespace path matches with type %s", c.name))
}

t.AutoPlan()
}

0 comments on commit 128c588

Please sign in to comment.