Skip to content
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

specs-go/round_trip_test: Add round-trip testing for the config #759

Closed
wants to merge 4 commits into from
Closed
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
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ install: true

script:
- env | grep TRAVIS_
- make .govet
- make .golint
- echo "${TRAVIS_COMMIT_RANGE} -> ${TRAVIS_COMMIT_RANGE/.../..} (travis-ci/travis-ci#4596)"
- TRAVIS_COMMIT_RANGE="${TRAVIS_COMMIT_RANGE/.../..}" make .gitvalidation
- TRAVIS_COMMIT_RANGE="${TRAVIS_COMMIT_RANGE/.../..}" make test
- make docs
- make -C schema test
17 changes: 15 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,14 @@ HOST_GOLANG_VERSION = $(shell go version | cut -d ' ' -f3 | cut -c 3-)
# this variable is used like a function. First arg is the minimum version, Second arg is the version to be checked.
ALLOWED_GO_VERSION = $(shell test '$(shell /bin/echo -e "$(1)\n$(2)" | sort -V | head -n1)' = '$(1)' && echo 'true')

test: .govet .golint .gitvalidation
TESTS := .govet .golint .gitvalidation

# (*testing.T).Run is new in 1.7, https://golang.org/doc/go1.7#testing
ifeq ($(call ALLOWED_GO_VERSION,1.7,$(HOST_GOLANG_VERSION)),true)
TESTS += .specs-go
endif

test: $(TESTS)

.govet:
go vet -x ./...
Expand All @@ -77,7 +84,10 @@ else
git-validation -v -run DCO,short-subject,dangling-whitespace -range $(EPOCH_TEST_COMMIT)..HEAD
endif

install.tools: .install.golint .install.gitvalidation
.specs-go:
go test ./specs-go

install.tools: .install.golint .install.gitvalidation .install.canonicaljson

# golint does not even build for <go1.6
.install.golint:
Expand All @@ -88,6 +98,9 @@ endif
.install.gitvalidation:
go get -u github.com/vbatts/git-validation

.install.canonicaljson:
go get -d -u github.com/docker/go/canonical/json

clean:
rm -rf $(OUTPUT_DIRNAME) *~
rm -f version.md
Expand Down
4 changes: 2 additions & 2 deletions specs-go/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ type Box struct {
// User specifies specific user (and group) information for the container process.
type User struct {
// UID is the user id.
UID uint32 `json:"uid" platform:"linux,solaris"`
UID *uint32 `json:"uid,omitempty" platform:"linux,solaris"`
// GID is the group id.
GID uint32 `json:"gid" platform:"linux,solaris"`
GID *uint32 `json:"gid,omitempty" platform:"linux,solaris"`
// AdditionalGids are additional group ids set for the container's process.
AdditionalGids []uint32 `json:"additionalGids,omitempty" platform:"linux,solaris"`
// Username is the user name.
Expand Down
39 changes: 39 additions & 0 deletions specs-go/round_trip_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package specs_test

import (
"bytes"
"fmt"
"testing"

"github.com/docker/go/canonical/json"
"github.com/opencontainers/runtime-spec/specs-go"
)

func TestConfigRoundTrip(t *testing.T) {
for i, configString := range []string{
// canonical version of the config.md example
`{"ociVersion":"0.5.0-dev","platform":{"os":"linux","arch":"amd64"},"process":{"terminal":true,"consoleSize":{"height":0,"width":0},"user":{"uid":1,"gid":1,"additionalGids":[5,6]},"args":["sh"],"env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","TERM=xterm"],"cwd":"/","capabilities":{"bounding":["CAP_AUDIT_WRITE","CAP_KILL","CAP_NET_BIND_SERVICE"],"effective":["CAP_AUDIT_WRITE","CAP_KILL"],"inheritable":["CAP_AUDIT_WRITE","CAP_KILL","CAP_NET_BIND_SERVICE"],"permitted":["CAP_AUDIT_WRITE","CAP_KILL","CAP_NET_BIND_SERVICE"],"ambient":["CAP_NET_BIND_SERVICE"]},"rlimits":[{"type":"RLIMIT_CORE","hard":1024,"soft":1024},{"type":"RLIMIT_NOFILE","hard":1024,"soft":1024}],"noNewPrivileges":true,"apparmorProfile":"acme_secure_profile","selinuxLabel":"system_u:system_r:svirt_lxc_net_t:s0:c124,c675"},"root":{"path":"rootfs","readonly":true},"hostname":"slartibartfast","mounts":[{"destination":"/proc","type":"proc","source":"proc"},{"destination":"/dev","type":"tmpfs","source":"tmpfs","options":["nosuid","strictatime","mode=755","size=65536k"]},{"destination":"/dev/pts","type":"devpts","source":"devpts","options":["nosuid","noexec","newinstance","ptmxmode=0666","mode=0620","gid=5"]},{"destination":"/dev/shm","type":"tmpfs","source":"shm","options":["nosuid","noexec","nodev","mode=1777","size=65536k"]},{"destination":"/dev/mqueue","type":"mqueue","source":"mqueue","options":["nosuid","noexec","nodev"]},{"destination":"/sys","type":"sysfs","source":"sysfs","options":["nosuid","noexec","nodev"]},{"destination":"/sys/fs/cgroup","type":"cgroup","source":"cgroup","options":["nosuid","noexec","nodev","relatime","ro"]}],"hooks":{"prestart":[{"path":"/usr/bin/fix-mounts","args":["fix-mounts","arg1","arg2"],"env":["key1=value1"]},{"path":"/usr/bin/setup-network"}],"poststart":[{"path":"/usr/bin/notify-start","timeout":5}],"poststop":[{"path":"/usr/sbin/cleanup.sh","args":["cleanup.sh","-f"]}]},"annotations":{"com.example.key1":"value1","com.example.key2":"value2"},"linux":{"uidMappings":[{"hostID":1000,"containerID":0,"size":32000}],"gidMappings":[{"hostID":1000,"containerID":0,"size":32000}],"sysctl":{"net.core.somaxconn":"256","net.ipv4.ip_forward":"1"},"resources":{"devices":[{"allow":false,"access":"rwm"},{"allow":true,"type":"c","major":10,"minor":229,"access":"rw"},{"allow":true,"type":"b","major":8,"minor":0,"access":"r"}],"disableOOMKiller":false,"oomScoreAdj":100,"memory":{"limit":536870912,"reservation":536870912,"swap":536870912,"kernel":0,"kernelTCP":0,"swappiness":0},"cpu":{"shares":1024,"quota":1000000,"period":500000,"realtimeRuntime":950000,"realtimePeriod":1000000,"cpus":"2-3","mems":"0-7"},"pids":{"limit":32771},"blockIO":{"blkioWeight":10,"blkioLeafWeight":10,"blkioWeightDevice":[{"major":8,"minor":0,"weight":500,"leafWeight":300},{"major":8,"minor":16,"weight":500}],"blkioThrottleReadBpsDevice":[{"major":8,"minor":0,"rate":600}],"blkioThrottleWriteIOPSDevice":[{"major":8,"minor":16,"rate":300}]},"hugepageLimits":[{"pageSize":"2MB","limit":9223372036854772000}],"network":{"classID":1048577,"priorities":[{"name":"eth0","priority":500},{"name":"eth1","priority":1000}]}},"cgroupsPath":"/myRuntime/myContainer","namespaces":[{"type":"pid"},{"type":"network"},{"type":"ipc"},{"type":"uts"},{"type":"mount"},{"type":"user"},{"type":"cgroup"}],"devices":[{"path":"/dev/fuse","type":"c","major":10,"minor":229,"fileMode":438,"uid":0,"gid":0},{"path":"/dev/sda","type":"b","major":8,"minor":0,"fileMode":432,"uid":0,"gid":0}],"seccomp":{"defaultAction":"SCMP_ACT_ALLOW","architectures":["SCMP_ARCH_X86","SCMP_ARCH_X32"],"syscalls":[{"names":["getcwd","chmod"],"action":"SCMP_ACT_ERRNO","args":null}]},"rootfsPropagation":"slave","maskedPaths":["/proc/kcore","/proc/latency_stats","/proc/timer_stats","/proc/sched_debug"],"readonlyPaths":["/proc/asound","/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"],"mountLabel":"system_u:object_r:svirt_sandbox_file_t:s0:c715,c811"}}`,

// minimal Linux example (removing optional fields from the config.md example)
`{"ociVersion":"1.0.0","platform":{"os":"linux","arch":"amd64"},"process":{"user":{"uid":1,"gid":1},"args":["sh"],"cwd":"/"},"root":{"path":"rootfs"}}`,

// minimal Windows example
`{"ociVersion":"1.0.0","platform":{"os":"windows","arch":"amd64"},"process":{"user":{"username":"containeradministrator"},"args":["sh"],"cwd":"C:\\"},"root":{"path":"rootfs"}}`,
} {
t.Run(fmt.Sprintf("config %d", i), func(t *testing.T) {
configBytes := []byte(configString)
var configStruct specs.Spec
err := json.NewDecoder(bytes.NewReader(configBytes)).Decode(&configStruct)
if err != nil {
t.Fatalf("failed to decode: %v", err)
}
outBytes, err := json.Marshal(configStruct)
if err != nil {
t.Fatalf("failed to encode: %v", err)
}
if bytes.Compare(configBytes, outBytes) != 0 {
t.Fatalf("failed to round-trip:\n%s", string(outBytes))
}
})
}
}