2018-09-25 12:27:46 -04:00
|
|
|
/*
|
|
|
|
Copyright The containerd 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.
|
|
|
|
*/
|
|
|
|
|
2018-03-19 21:36:34 -04:00
|
|
|
package fs
|
|
|
|
|
|
|
|
import (
|
2018-09-25 12:27:46 -04:00
|
|
|
_ "crypto/sha256"
|
2018-03-19 21:36:34 -04:00
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"testing"
|
2018-09-25 12:27:46 -04:00
|
|
|
"time"
|
2018-03-19 21:36:34 -04:00
|
|
|
|
2018-09-25 12:27:46 -04:00
|
|
|
"github.com/containerd/continuity/fs/fstest"
|
2018-03-19 21:36:34 -04:00
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
// TODO: Create copy directory which requires privilege
|
|
|
|
// chown
|
|
|
|
// mknod
|
|
|
|
// setxattr fstest.SetXAttr("/home", "trusted.overlay.opaque", "y"),
|
|
|
|
|
|
|
|
func TestCopyDirectory(t *testing.T) {
|
|
|
|
apply := fstest.Apply(
|
|
|
|
fstest.CreateDir("/etc/", 0755),
|
|
|
|
fstest.CreateFile("/etc/hosts", []byte("localhost 127.0.0.1"), 0644),
|
|
|
|
fstest.Link("/etc/hosts", "/etc/hosts.allow"),
|
|
|
|
fstest.CreateDir("/usr/local/lib", 0755),
|
|
|
|
fstest.CreateFile("/usr/local/lib/libnothing.so", []byte{0x00, 0x00}, 0755),
|
|
|
|
fstest.Symlink("libnothing.so", "/usr/local/lib/libnothing.so.2"),
|
|
|
|
fstest.CreateDir("/home", 0755),
|
|
|
|
)
|
|
|
|
|
|
|
|
if err := testCopy(apply); err != nil {
|
|
|
|
t.Fatalf("Copy test failed: %+v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// This test used to fail because link-no-nothing.txt would be copied first,
|
|
|
|
// then file operations in dst during the CopyDir would follow the symlink and
|
|
|
|
// fail.
|
|
|
|
func TestCopyDirectoryWithLocalSymlink(t *testing.T) {
|
|
|
|
apply := fstest.Apply(
|
|
|
|
fstest.CreateFile("nothing.txt", []byte{0x00, 0x00}, 0755),
|
|
|
|
fstest.Symlink("nothing.txt", "link-no-nothing.txt"),
|
|
|
|
)
|
|
|
|
|
|
|
|
if err := testCopy(apply); err != nil {
|
|
|
|
t.Fatalf("Copy test failed: %+v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-25 12:27:46 -04:00
|
|
|
// TestCopyWithLargeFile tests copying a file whose size > 2^32 bytes.
|
|
|
|
func TestCopyWithLargeFile(t *testing.T) {
|
|
|
|
if testing.Short() {
|
|
|
|
t.SkipNow()
|
|
|
|
}
|
|
|
|
apply := fstest.Apply(
|
|
|
|
fstest.CreateDir("/banana", 0755),
|
|
|
|
fstest.CreateRandomFile("/banana/split", time.Now().UnixNano(), 3*1024*1024*1024, 0644),
|
|
|
|
)
|
|
|
|
|
|
|
|
if err := testCopy(apply); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-19 21:36:34 -04:00
|
|
|
func testCopy(apply fstest.Applier) error {
|
|
|
|
t1, err := ioutil.TempDir("", "test-copy-src-")
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "failed to create temporary directory")
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(t1)
|
|
|
|
|
|
|
|
t2, err := ioutil.TempDir("", "test-copy-dst-")
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "failed to create temporary directory")
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(t2)
|
|
|
|
|
|
|
|
if err := apply.Apply(t1); err != nil {
|
|
|
|
return errors.Wrap(err, "failed to apply changes")
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := CopyDir(t2, t1); err != nil {
|
|
|
|
return errors.Wrap(err, "failed to copy")
|
|
|
|
}
|
|
|
|
|
|
|
|
return fstest.CheckDirectoryEqual(t1, t2)
|
|
|
|
}
|