From bb6fe03a9a4dae5b517f7702c3eb73df8f082db3 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Sat, 20 Jun 2020 18:35:48 +1000 Subject: [PATCH] travis: run unit tests on MacOS This requires a little bit of working around MacOS-specific weirdnesses (which are fine under POSIX but don't match Linux). The most obvious one is the lack of 'readlink -f', but there's also the lack of sub-second granularity of filesystem timesamps, and the default-follow behaviour of link(2) when trying to hardlink a symlink. Signed-off-by: Aleksa Sarai --- .travis.yml | 5 ++- Makefile | 3 +- hack/publish-site.sh | 3 +- hack/readlinkf.sh | 43 ++++++++++++++++++ hack/release.sh | 3 +- hack/test-integration.sh | 8 ++-- hack/test-unit.sh | 7 +-- hack/test-vendor.sh | 3 +- oci/layer/tar_extract_test.go | 77 +++++++++++++++++++------------- pkg/fseval/fseval_default.go | 19 +++++--- pkg/fseval/fseval_rootless.go | 8 ++-- pkg/system/utime_unix_test.go | 17 +++---- pkg/testutils/ftimes.go | 28 ++++++++++++ pkg/testutils/ftimes_darwin.go | 29 ++++++++++++ pkg/testutils/ftimes_unix.go | 32 +++++++++++++ pkg/unpriv/unpriv.go | 39 +++++++++------- pkg/unpriv/unpriv_test.go | 14 +++--- pkg/unpriv/unpriv_utimes_test.go | 17 +++---- test/helpers.bash | 4 +- 19 files changed, 265 insertions(+), 94 deletions(-) create mode 100644 hack/readlinkf.sh create mode 100644 pkg/testutils/ftimes.go create mode 100644 pkg/testutils/ftimes_darwin.go create mode 100644 pkg/testutils/ftimes_unix.go diff --git a/.travis.yml b/.travis.yml index d56878ffe..1e6078b12 100644 --- a/.travis.yml +++ b/.travis.yml @@ -71,6 +71,7 @@ matrix: # Clear DOCKER_IMAGE since we don't use it. - DOCKER_IMAGE="" script: - # TODO: Run the integration and unit tests, so we don't need to - # special-case MacOS here. + # TODO: Run the integration tests and rest of the CI, so we don't need + # to special-case MacOS here. - make local-validate-build + - make local-test-unit diff --git a/Makefile b/Makefile index 45afe9a27..242570438 100644 --- a/Makefile +++ b/Makefile @@ -156,7 +156,8 @@ umociimage: docker build -t $(UMOCI_IMAGE) --build-arg DOCKER_IMAGE=$(DOCKER_IMAGE) . ifndef COVERAGE -COVERAGE := $(basename $(shell mktemp -u umoci.cov.XXXXXX)) +COVERAGE := $(notdir $(shell mktemp -u umoci.cov.XXXXXX)) +export COVERAGE endif .PHONY: test-unit diff --git a/hack/publish-site.sh b/hack/publish-site.sh index 9aaebefc9..9785e1d56 100755 --- a/hack/publish-site.sh +++ b/hack/publish-site.sh @@ -15,9 +15,10 @@ # limitations under the License. set -Eeuo pipefail +source "$(dirname "$BASH_SOURCE")/readlinkf.sh" # Change to site root. -site_root="$(readlink -f "$(dirname "${BASH_SOURCE}")/../.site")" +site_root="$(readlinkf_posix "$(dirname "${BASH_SOURCE}")/../.site")" cd "$site_root" # Make sure that we've checked out submodules. diff --git a/hack/readlinkf.sh b/hack/readlinkf.sh new file mode 100644 index 000000000..f2b0c0857 --- /dev/null +++ b/hack/readlinkf.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# readlinkf: POSIX-compliant implementation of readlink -f. +# Author: Koichi Nakashima +# Licensed under the Creative Commons Zero v1.0 Universal license. +# + +# Copied verbatim from v1.1.0 of . + +# POSIX compliant version +readlinkf_posix() { + [ "${1:-}" ] || return 1 + max_symlinks=40 + CDPATH='' # to avoid changing to an unexpected directory + + target=$1 + [ -e "${target%/}" ] || target=${1%"${1##*[!/]}"} # trim trailing slashes + [ -d "${target:-/}" ] && target="$target/" + + cd -P . 2>/dev/null || return 1 + while [ "$max_symlinks" -ge 0 ] && max_symlinks=$((max_symlinks - 1)); do + if [ ! "$target" = "${target%/*}" ]; then + case $target in + /*) cd -P "${target%/*}/" 2>/dev/null || break ;; + *) cd -P "./${target%/*}" 2>/dev/null || break ;; + esac + target=${target##*/} + fi + + if [ ! -L "$target" ]; then + target="${PWD%/}${target:+/}${target}" + printf '%s\n' "${target:-/}" + return 0 + fi + + # `ls -dl` format: "%s %u %s %s %u %s %s -> %s\n", + # , , , , + # , , , + # https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html + link=$(ls -dl -- "$target" 2>/dev/null) || break + target=${link#*" $target -> "} + done + return 1 +} diff --git a/hack/release.sh b/hack/release.sh index 004a89af0..bb8753b36 100755 --- a/hack/release.sh +++ b/hack/release.sh @@ -7,12 +7,13 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. set -Eeuo pipefail +source "$(dirname "$BASH_SOURCE")/readlinkf.sh" ## ---> # Project-specific options and functions. In *theory* you shouldn't need to # touch anything else in this script in order to use this elsewhere. project="umoci" -root="$(readlink -f "$(dirname "${BASH_SOURCE}")/..")" +root="$(readlinkf_posix "$(dirname "${BASH_SOURCE}")/..")" # These functions allow you to configure how the defaults are computed. function get_arch() { go env GOARCH || uname -m; } diff --git a/hack/test-integration.sh b/hack/test-integration.sh index 082bde159..54e867e6b 100755 --- a/hack/test-integration.sh +++ b/hack/test-integration.sh @@ -15,11 +15,13 @@ # limitations under the License. set -Eeuxo pipefail +source "$(dirname "$BASH_SOURCE")/readlinkf.sh" -export COVER="${COVER:-0}" +export ROOT="$(readlinkf_posix "$(dirname "$BASH_SOURCE")/..")" -# Set up the root and coverage directories. -export ROOT="$(readlink -f "$(dirname "$(readlink -f "$BASH_SOURCE")")/..")" +# Set up the coverage directory. +COVERAGE="${COVERAGE:-}" +export COVER="${COVER:-0}" if [ "$COVER" -eq 1 ]; then export COVERAGE_DIR=$(mktemp -dt umoci-coverage.XXXXXX) fi diff --git a/hack/test-unit.sh b/hack/test-unit.sh index 7164ad07b..746a0087f 100755 --- a/hack/test-unit.sh +++ b/hack/test-unit.sh @@ -15,13 +15,14 @@ # limitations under the License. set -Eeuxo pipefail +source "$(dirname "$BASH_SOURCE")/readlinkf.sh" + +export ROOT="$(readlinkf_posix "$(dirname "$BASH_SOURCE")/..")" GO="${GO:-go}" +COVERAGE="${COVERAGE:-}" PROJECT="${PROJECT:-github.com/opencontainers/umoci}" -# Set up the root and coverage directories. -export ROOT="$(readlink -f "$(dirname "$(readlink -f "$BASH_SOURCE")")/..")" - # Run the tests. extra_args=() if [ -n "$COVERAGE" ] diff --git a/hack/test-vendor.sh b/hack/test-vendor.sh index 7f46cdfab..aa6faf7a7 100755 --- a/hack/test-vendor.sh +++ b/hack/test-vendor.sh @@ -15,6 +15,7 @@ # limitations under the License. set -Eeuxo pipefail +source "$(dirname "$BASH_SOURCE")/readlinkf.sh" # Generate a hash-of-hashes for the entire vendor/ tree. function gethash() { @@ -26,7 +27,7 @@ function gethash() { } # Figure out root directory. -ROOT="$(readlink -f "$(dirname "$(readlink -f "$BASH_SOURCE")")/..")" +ROOT="$(readlinkf_posix "$(dirname "$BASH_SOURCE")/..")" STASHED_ROOT="$(mktemp -dt umoci-vendor.XXXXXX)" # Stash away old vendor tree, and restore it on-exit. diff --git a/oci/layer/tar_extract_test.go b/oci/layer/tar_extract_test.go index afc0a90e1..40e861184 100644 --- a/oci/layer/tar_extract_test.go +++ b/oci/layer/tar_extract_test.go @@ -25,11 +25,13 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "strings" "testing" "time" rspec "github.com/opencontainers/runtime-spec/specs-go" + "github.com/opencontainers/umoci/pkg/testutils" "github.com/pkg/errors" "golang.org/x/sys/unix" ) @@ -226,8 +228,8 @@ func TestUnpackEntryWhiteout(t *testing.T) { {"HiddenDirInSubdir", "another/path/.hiddendir", true}, } { t.Logf("running Test%s", test.name) - testMtime := time.Unix(123, 456) - testAtime := time.Unix(789, 111) + testMtime := testutils.Unix(123, 456) + testAtime := testutils.Unix(789, 111) dir, err := ioutil.TempDir("", "umoci-TestUnpackEntryWhiteout") if err != nil { @@ -344,9 +346,9 @@ func TestUnpackOpaqueWhiteout(t *testing.T) { Typeflag: ph.typeflag, Mode: int64(mode), Size: size, - ModTime: time.Unix(1210393, 4528036), - AccessTime: time.Unix(7892829, 2341211), - ChangeTime: time.Unix(8731293, 8218947), + ModTime: testutils.Unix(1210393, 4528036), + AccessTime: testutils.Unix(7892829, 2341211), + ChangeTime: testutils.Unix(8731293, 8218947), }, r } @@ -590,6 +592,9 @@ func TestUnpackHardlink(t *testing.T) { var ( hdr *tar.Header + // On MacOS, this might not work. + hardlinkToSymlinkSupported = true + ctrValue = []byte("some content we won't check") regFile = "regular" symFile = "link" @@ -650,10 +655,17 @@ func TestUnpackHardlink(t *testing.T) { Gid: os.Getgid() + 2020, } if err := te.UnpackEntry(dir, hdr, nil); err != nil { - t.Fatalf("hardlinkB: unexpected UnpackEntry error: %s", err) + // On Travis' setup, hardlinks to symlinks are not permitted under + // MacOS. That's fine. + if runtime.GOOS == "darwin" && errors.Is(err, unix.ENOTSUP) { + hardlinkToSymlinkSupported = false + t.Logf("hardlinks to symlinks unsupported -- skipping that part of the test") + } else { + t.Fatalf("hardlinkB: unexpected UnpackEntry error: %s", err) + } } - // Quickly make sure that the contents are as expected. + // Make sure that the contents are as expected. ctrValueGot, err := ioutil.ReadFile(filepath.Join(dir, regFile)) if err != nil { t.Fatalf("regular file was not created: %s", err) @@ -663,7 +675,7 @@ func TestUnpackHardlink(t *testing.T) { } // Now we have to check the inode numbers. - var regFi, symFi, hardAFi, hardBFi unix.Stat_t + var regFi, symFi, hardAFi unix.Stat_t if err := unix.Lstat(filepath.Join(dir, regFile), ®Fi); err != nil { t.Fatalf("could not stat regular file: %s", err) @@ -674,36 +686,41 @@ func TestUnpackHardlink(t *testing.T) { if err := unix.Lstat(filepath.Join(dir, hardFileA), &hardAFi); err != nil { t.Fatalf("could not stat hardlinkA: %s", err) } - if err := unix.Lstat(filepath.Join(dir, hardFileB), &hardBFi); err != nil { - t.Fatalf("could not stat hardlinkB: %s", err) - } - - // This test only runs on Linux anyway. if regFi.Ino == symFi.Ino { t.Errorf("regular and symlink have the same inode! ino=%d", regFi.Ino) } - if hardAFi.Ino == hardBFi.Ino { - t.Errorf("both hardlinks have the same inode! ino=%d", hardAFi.Ino) - } if hardAFi.Ino != regFi.Ino { t.Errorf("hardlink to regular has a different inode: reg=%d hard=%d", regFi.Ino, hardAFi.Ino) } - if hardBFi.Ino != symFi.Ino { - t.Errorf("hardlink to symlink has a different inode: sym=%d hard=%d", symFi.Ino, hardBFi.Ino) - } - // Double-check readlink. - linknameA, err := os.Readlink(filepath.Join(dir, symFile)) - if err != nil { - t.Errorf("unexpected error reading symlink: %s", err) - } - linknameB, err := os.Readlink(filepath.Join(dir, hardFileB)) - if err != nil { - t.Errorf("unexpected error reading hardlink to symlink: %s", err) - } - if linknameA != linknameB { - t.Errorf("hardlink to symlink doesn't match linkname: link=%s hard=%s", linknameA, linknameB) + if hardlinkToSymlinkSupported { + var hardBFi unix.Stat_t + + if err := unix.Lstat(filepath.Join(dir, hardFileB), &hardBFi); err != nil { + t.Fatalf("could not stat hardlinkB: %s", err) + } + + // Check inode numbers of hardlink-to-symlink. + if hardAFi.Ino == hardBFi.Ino { + t.Errorf("both hardlinks have the same inode! ino=%d", hardAFi.Ino) + } + if hardBFi.Ino != symFi.Ino { + t.Errorf("hardlink to symlink has a different inode: sym=%d hard=%d", symFi.Ino, hardBFi.Ino) + } + + // Double-check readlink. + linknameA, err := os.Readlink(filepath.Join(dir, symFile)) + if err != nil { + t.Errorf("unexpected error reading symlink: %s", err) + } + linknameB, err := os.Readlink(filepath.Join(dir, hardFileB)) + if err != nil { + t.Errorf("unexpected error reading hardlink to symlink: %s", err) + } + if linknameA != linknameB { + t.Errorf("hardlink to symlink doesn't match linkname: link=%s hard=%s", linknameA, linknameB) + } } // Make sure that uid and gid don't apply to hardlinks. diff --git a/pkg/fseval/fseval_default.go b/pkg/fseval/fseval_default.go index 6505fad55..33128bca9 100644 --- a/pkg/fseval/fseval_default.go +++ b/pkg/fseval/fseval_default.go @@ -74,13 +74,18 @@ func (fs osFsEval) Readlink(path string) (string, error) { } // Symlink is equivalent to os.Symlink. -func (fs osFsEval) Symlink(linkname, path string) error { - return os.Symlink(linkname, path) -} - -// Link is equivalent to os.Link. -func (fs osFsEval) Link(linkname, path string) error { - return os.Link(linkname, path) +func (fs osFsEval) Symlink(target, linkname string) error { + return os.Symlink(target, linkname) +} + +// Link is equivalent to unix.Link(..., ~AT_SYMLINK_FOLLOW). +func (fs osFsEval) Link(target, linkname string) error { + // We need to explicitly pass 0 as a flag because POSIX allows the default + // behaviour of link(2) when it comes to target being a symlink to be + // implementation-defined. Only linkat(2) allows us to guarantee the right + // behaviour. + // + return unix.Linkat(unix.AT_FDCWD, target, unix.AT_FDCWD, linkname, 0) } // Chmod is equivalent to os.Chmod. diff --git a/pkg/fseval/fseval_rootless.go b/pkg/fseval/fseval_rootless.go index 256fda144..bdc898618 100644 --- a/pkg/fseval/fseval_rootless.go +++ b/pkg/fseval/fseval_rootless.go @@ -68,13 +68,13 @@ func (fs unprivFsEval) Readlink(path string) (string, error) { } // Symlink is equivalent to unpriv.Symlink. -func (fs unprivFsEval) Symlink(linkname, path string) error { - return unpriv.Symlink(linkname, path) +func (fs unprivFsEval) Symlink(target, linkname string) error { + return unpriv.Symlink(target, linkname) } // Link is equivalent to unpriv.Link. -func (fs unprivFsEval) Link(linkname, path string) error { - return unpriv.Link(linkname, path) +func (fs unprivFsEval) Link(target, linkname string) error { + return unpriv.Link(target, linkname) } // Chmod is equivalent to unpriv.Chmod. diff --git a/pkg/system/utime_unix_test.go b/pkg/system/utime_unix_test.go index 92af9304a..757a6a962 100644 --- a/pkg/system/utime_unix_test.go +++ b/pkg/system/utime_unix_test.go @@ -24,6 +24,7 @@ import ( "testing" "time" + "github.com/opencontainers/umoci/pkg/testutils" "golang.org/x/sys/unix" ) @@ -42,8 +43,8 @@ func TestLutimesFile(t *testing.T) { t.Fatal(err) } - atime := time.Unix(125812851, 128518257) - mtime := time.Unix(257172893, 995216512) + atime := testutils.Unix(125812851, 128518257) + mtime := testutils.Unix(257172893, 995216512) if err := unix.Lstat(path, &fiOld); err != nil { t.Fatal(err) @@ -91,8 +92,8 @@ func TestLutimesDirectory(t *testing.T) { t.Fatal(err) } - atime := time.Unix(128551231, 273285257) - mtime := time.Unix(185726393, 752135712) + atime := testutils.Unix(128551231, 273285257) + mtime := testutils.Unix(185726393, 752135712) if err := unix.Lstat(path, &fiOld); err != nil { t.Fatal(err) @@ -140,8 +141,8 @@ func TestLutimesSymlink(t *testing.T) { t.Fatal(err) } - atime := time.Unix(128551231, 273285257) - mtime := time.Unix(185726393, 752135712) + atime := testutils.Unix(128551231, 273285257) + mtime := testutils.Unix(185726393, 752135712) if err := unix.Lstat(path, &fiOld); err != nil { t.Fatal(err) @@ -218,8 +219,8 @@ func TestLutimesRelative(t *testing.T) { t.Fatal(err) } - atime := time.Unix(134858232, 258921237) - mtime := time.Unix(171257291, 425815288) + atime := testutils.Unix(134858232, 258921237) + mtime := testutils.Unix(171257291, 425815288) if err := unix.Lstat(path, &fiOld); err != nil { t.Fatal(err) diff --git a/pkg/testutils/ftimes.go b/pkg/testutils/ftimes.go new file mode 100644 index 000000000..b6e05c07f --- /dev/null +++ b/pkg/testutils/ftimes.go @@ -0,0 +1,28 @@ +/* + * umoci: Umoci Modifies Open Containers' Images + * Copyright (C) 2016-2020 SUSE 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 testutils + +import ( + "time" +) + +// Unix returns the local Time corresponding to the given Unix time, rounded to +// the timestamp granularity for this system. +func Unix(sec, nsec int64) time.Time { + return time.Unix(sec, nsec).Round(FtimeGranularity()) +} diff --git a/pkg/testutils/ftimes_darwin.go b/pkg/testutils/ftimes_darwin.go new file mode 100644 index 000000000..8c4f3b60b --- /dev/null +++ b/pkg/testutils/ftimes_darwin.go @@ -0,0 +1,29 @@ +/* + * umoci: Umoci Modifies Open Containers' Images + * Copyright (C) 2016-2020 SUSE 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 testutils + +import ( + "time" +) + +// FtimeGranularity is the filesystem timestamp granularity for this system. +func FtimeGranularity() time.Duration { + // On OS X, filesystem timestamps have second-level granularity. + // Nanosecond values are silently truncated if you try to set them. + return time.Second +} diff --git a/pkg/testutils/ftimes_unix.go b/pkg/testutils/ftimes_unix.go new file mode 100644 index 000000000..17a709ae0 --- /dev/null +++ b/pkg/testutils/ftimes_unix.go @@ -0,0 +1,32 @@ +// +build !darwin + +/* + * umoci: Umoci Modifies Open Containers' Images + * Copyright (C) 2016-2020 SUSE 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 testutils + +import ( + "time" +) + +// FtimeGranularity is the filesystem timestamp granularity for this system. +// TODO: We should probably make this dependent on the path since some +// filesystems can have different granularities... +func FtimeGranularity() time.Duration { + // On Linux, most filesystems have nano-second-level granularity. + return time.Nanosecond +} diff --git a/pkg/unpriv/unpriv.go b/pkg/unpriv/unpriv.go index 0bdb15e24..3e17be9f8 100644 --- a/pkg/unpriv/unpriv.go +++ b/pkg/unpriv/unpriv.go @@ -218,19 +218,19 @@ func Lstatx(path string) (unix.Stat_t, error) { } // Readlink is a wrapper around os.Readlink which has been wrapped with -// unpriv.Wrap to make it possible to get the linkname of a symlink even if you +// unpriv.Wrap to make it possible to get the target of a symlink even if you // do not currently have the required mode bits set to resolve the path. Note // that you may not have resolve access after this function returns because all // of this trickery is reverted by unpriv.Wrap. func Readlink(path string) (string, error) { - var linkname string + var target string err := Wrap(path, func(path string) error { // Fairly simple. var err error - linkname, err = os.Readlink(path) + target, err = os.Readlink(path) return err }) - return linkname, errors.Wrap(err, "unpriv.readlink") + return target, errors.Wrap(err, "unpriv.readlink") } // Symlink is a wrapper around os.Symlink which has been wrapped with @@ -238,25 +238,30 @@ func Readlink(path string) (string, error) { // currently have the required access bits to create the symlink. Note that you // may not have resolve access after this function returns because all of the // trickery is reverted by unpriv.Wrap. -func Symlink(linkname, path string) error { - return errors.Wrap(Wrap(path, func(path string) error { - return os.Symlink(linkname, path) +func Symlink(target, linkname string) error { + return errors.Wrap(Wrap(linkname, func(linkname string) error { + return os.Symlink(target, linkname) }), "unpriv.symlink") } -// Link is a wrapper around os.Link which has been wrapped with unpriv.Wrap to -// make it possible to create a hard link even if you do not currently have the -// required access bits to create the hard link. Note that you may not have -// resolve access after this function returns because all of the trickery is -// reverted by unpriv.Wrap. -func Link(linkname, path string) error { - return errors.Wrap(Wrap(path, func(path string) error { +// Link is a wrapper around unix.Link(..., 0) which has been wrapped with +// unpriv.Wrap to make it possible to create a hard link even if you do not +// currently have the required access bits to create the hard link. Note that +// you may not have resolve access after this function returns because all of +// the trickery is reverted by unpriv.Wrap. +func Link(target, linkname string) error { + return errors.Wrap(Wrap(linkname, func(linkname string) error { // We have to double-wrap this, because you need search access to the // linkname. This is safe because any common ancestors will be reverted // in reverse call stack order. - return errors.Wrap(Wrap(linkname, func(linkname string) error { - return os.Link(linkname, path) - }), "unpriv.wrap linkname") + return errors.Wrap(Wrap(target, func(target string) error { + // We need to explicitly pass 0 as a flag because POSIX allows the + // default behaviour of link(2) when it comes to target being a + // symlink to be implementation-defined. Only linkat(2) allows us + // to guarantee the right behaviour. + // + return unix.Linkat(unix.AT_FDCWD, target, unix.AT_FDCWD, linkname, 0) + }), "unpriv.wrap target") }), "unpriv.link") } diff --git a/pkg/unpriv/unpriv_test.go b/pkg/unpriv/unpriv_test.go index c1277fb6b..3fc2ad891 100644 --- a/pkg/unpriv/unpriv_test.go +++ b/pkg/unpriv/unpriv_test.go @@ -25,8 +25,8 @@ import ( "path/filepath" "reflect" "testing" - "time" + "github.com/opencontainers/umoci/pkg/testutils" "github.com/pkg/errors" ) @@ -891,8 +891,8 @@ func TestChtimes(t *testing.T) { hdrOld, _ := tar.FileInfoHeader(fi, "") // Modify the times. - atime := time.Unix(12345678, 12421512) - mtime := time.Unix(11245631, 13373321) + atime := testutils.Unix(12345678, 12421512) + mtime := testutils.Unix(11245631, 13373321) if err := Chtimes(filepath.Join(dir, "some", "parent", "directories"), atime, mtime); err != nil { t.Errorf("unexpected error from unpriv.chtimes: %s", err) } @@ -1008,8 +1008,8 @@ func TestLutimes(t *testing.T) { hdrDirOld, _ := tar.FileInfoHeader(fi, "") // Modify the times. - atime := time.Unix(12345678, 12421512) - mtime := time.Unix(11245631, 13373321) + atime := testutils.Unix(12345678, 12421512) + mtime := testutils.Unix(11245631, 13373321) if err := Lutimes(filepath.Join(dir, "some", "parent", "directories"), atime, mtime); err != nil { t.Errorf("unexpected error from unpriv.lutimes: %s", err) } @@ -1035,8 +1035,8 @@ func TestLutimes(t *testing.T) { } // Do the same for a symlink. - atime = time.Unix(18127518, 12421122) - mtime = time.Unix(15245123, 19912991) + atime = testutils.Unix(18127518, 12421122) + mtime = testutils.Unix(15245123, 19912991) fi, err = Lstat(filepath.Join(dir, "some", "parent", "directories", "link2")) if err != nil { diff --git a/pkg/unpriv/unpriv_utimes_test.go b/pkg/unpriv/unpriv_utimes_test.go index aa044312b..2d3470f01 100644 --- a/pkg/unpriv/unpriv_utimes_test.go +++ b/pkg/unpriv/unpriv_utimes_test.go @@ -24,6 +24,7 @@ import ( "testing" "time" + "github.com/opencontainers/umoci/pkg/testutils" "golang.org/x/sys/unix" ) @@ -42,8 +43,8 @@ func TestLutimesFile(t *testing.T) { t.Fatal(err) } - atime := time.Unix(125812851, 128518257) - mtime := time.Unix(257172893, 995216512) + atime := testutils.Unix(125812851, 128518257) + mtime := testutils.Unix(257172893, 995216512) if err := unix.Lstat(path, &fiOld); err != nil { t.Fatal(err) @@ -91,8 +92,8 @@ func TestLutimesDirectory(t *testing.T) { t.Fatal(err) } - atime := time.Unix(128551231, 273285257) - mtime := time.Unix(185726393, 752135712) + atime := testutils.Unix(128551231, 273285257) + mtime := testutils.Unix(185726393, 752135712) if err := unix.Lstat(path, &fiOld); err != nil { t.Fatal(err) @@ -140,8 +141,8 @@ func TestLutimesSymlink(t *testing.T) { t.Fatal(err) } - atime := time.Unix(128551231, 273285257) - mtime := time.Unix(185726393, 752135712) + atime := testutils.Unix(128551231, 273285257) + mtime := testutils.Unix(185726393, 752135712) if err := unix.Lstat(path, &fiOld); err != nil { t.Fatal(err) @@ -218,8 +219,8 @@ func TestLutimesRelative(t *testing.T) { t.Fatal(err) } - atime := time.Unix(134858232, 258921237) - mtime := time.Unix(171257291, 425815288) + atime := testutils.Unix(134858232, 258921237) + mtime := testutils.Unix(171257291, 425815288) if err := unix.Lstat(path, &fiOld); err != nil { t.Fatal(err) diff --git a/test/helpers.bash b/test/helpers.bash index 5ff4d7750..14cbeb3be 100644 --- a/test/helpers.bash +++ b/test/helpers.bash @@ -14,8 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +source "$(dirname "$BASH_SOURCE")/../hack/readlinkf.sh" + # Root directory of integration tests. -INTEGRATION_ROOT=$(dirname "$(readlink -f "$BASH_SOURCE")") +INTEGRATION_ROOT=$(dirname "$(readlinkf_posix "$BASH_SOURCE")") UMOCI="${UMOCI:-${INTEGRATION_ROOT}/../umoci}" GOMTREE="/usr/bin/gomtree" # For some reason $(whence ...) and $(where ...) are broken.