1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00
moby--moby/daemon/graphdriver/graphtest/testutil.go
Daniel Nephin 4f0d95fa6e Add canonical import comment
Signed-off-by: Daniel Nephin <dnephin@docker.com>
2018-02-05 16:51:57 -05:00

337 lines
8.6 KiB
Go

package graphtest // import "github.com/docker/docker/daemon/graphdriver/graphtest"
import (
"bytes"
"fmt"
"math/rand"
"os"
"sort"
"github.com/containerd/continuity/driver"
"github.com/docker/docker/daemon/graphdriver"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/stringid"
)
func randomContent(size int, seed int64) []byte {
s := rand.NewSource(seed)
content := make([]byte, size)
for i := 0; i < len(content); i += 7 {
val := s.Int63()
for j := 0; i+j < len(content) && j < 7; j++ {
content[i+j] = byte(val)
val >>= 8
}
}
return content
}
func addFiles(drv graphdriver.Driver, layer string, seed int64) error {
root, err := drv.Get(layer, "")
if err != nil {
return err
}
defer drv.Put(layer)
if err := driver.WriteFile(root, root.Join(root.Path(), "file-a"), randomContent(64, seed), 0755); err != nil {
return err
}
if err := root.MkdirAll(root.Join(root.Path(), "dir-b"), 0755); err != nil {
return err
}
if err := driver.WriteFile(root, root.Join(root.Path(), "dir-b", "file-b"), randomContent(128, seed+1), 0755); err != nil {
return err
}
return driver.WriteFile(root, root.Join(root.Path(), "file-c"), randomContent(128*128, seed+2), 0755)
}
func checkFile(drv graphdriver.Driver, layer, filename string, content []byte) error {
root, err := drv.Get(layer, "")
if err != nil {
return err
}
defer drv.Put(layer)
fileContent, err := driver.ReadFile(root, root.Join(root.Path(), filename))
if err != nil {
return err
}
if !bytes.Equal(fileContent, content) {
return fmt.Errorf("mismatched file content %v, expecting %v", fileContent, content)
}
return nil
}
func addFile(drv graphdriver.Driver, layer, filename string, content []byte) error {
root, err := drv.Get(layer, "")
if err != nil {
return err
}
defer drv.Put(layer)
return driver.WriteFile(root, root.Join(root.Path(), filename), content, 0755)
}
func addDirectory(drv graphdriver.Driver, layer, dir string) error {
root, err := drv.Get(layer, "")
if err != nil {
return err
}
defer drv.Put(layer)
return root.MkdirAll(root.Join(root.Path(), dir), 0755)
}
func removeAll(drv graphdriver.Driver, layer string, names ...string) error {
root, err := drv.Get(layer, "")
if err != nil {
return err
}
defer drv.Put(layer)
for _, filename := range names {
if err := root.RemoveAll(root.Join(root.Path(), filename)); err != nil {
return err
}
}
return nil
}
func checkFileRemoved(drv graphdriver.Driver, layer, filename string) error {
root, err := drv.Get(layer, "")
if err != nil {
return err
}
defer drv.Put(layer)
if _, err := root.Stat(root.Join(root.Path(), filename)); err == nil {
return fmt.Errorf("file still exists: %s", root.Join(root.Path(), filename))
} else if !os.IsNotExist(err) {
return err
}
return nil
}
func addManyFiles(drv graphdriver.Driver, layer string, count int, seed int64) error {
root, err := drv.Get(layer, "")
if err != nil {
return err
}
defer drv.Put(layer)
for i := 0; i < count; i += 100 {
dir := root.Join(root.Path(), fmt.Sprintf("directory-%d", i))
if err := root.MkdirAll(dir, 0755); err != nil {
return err
}
for j := 0; i+j < count && j < 100; j++ {
file := root.Join(dir, fmt.Sprintf("file-%d", i+j))
if err := driver.WriteFile(root, file, randomContent(64, seed+int64(i+j)), 0755); err != nil {
return err
}
}
}
return nil
}
func changeManyFiles(drv graphdriver.Driver, layer string, count int, seed int64) ([]archive.Change, error) {
root, err := drv.Get(layer, "")
if err != nil {
return nil, err
}
defer drv.Put(layer)
changes := []archive.Change{}
for i := 0; i < count; i += 100 {
archiveRoot := fmt.Sprintf("/directory-%d", i)
if err := root.MkdirAll(root.Join(root.Path(), archiveRoot), 0755); err != nil {
return nil, err
}
for j := 0; i+j < count && j < 100; j++ {
if j == 0 {
changes = append(changes, archive.Change{
Path: archiveRoot,
Kind: archive.ChangeModify,
})
}
var change archive.Change
switch j % 3 {
// Update file
case 0:
change.Path = root.Join(archiveRoot, fmt.Sprintf("file-%d", i+j))
change.Kind = archive.ChangeModify
if err := driver.WriteFile(root, root.Join(root.Path(), change.Path), randomContent(64, seed+int64(i+j)), 0755); err != nil {
return nil, err
}
// Add file
case 1:
change.Path = root.Join(archiveRoot, fmt.Sprintf("file-%d-%d", seed, i+j))
change.Kind = archive.ChangeAdd
if err := driver.WriteFile(root, root.Join(root.Path(), change.Path), randomContent(64, seed+int64(i+j)), 0755); err != nil {
return nil, err
}
// Remove file
case 2:
change.Path = root.Join(archiveRoot, fmt.Sprintf("file-%d", i+j))
change.Kind = archive.ChangeDelete
if err := root.Remove(root.Join(root.Path(), change.Path)); err != nil {
return nil, err
}
}
changes = append(changes, change)
}
}
return changes, nil
}
func checkManyFiles(drv graphdriver.Driver, layer string, count int, seed int64) error {
root, err := drv.Get(layer, "")
if err != nil {
return err
}
defer drv.Put(layer)
for i := 0; i < count; i += 100 {
dir := root.Join(root.Path(), fmt.Sprintf("directory-%d", i))
for j := 0; i+j < count && j < 100; j++ {
file := root.Join(dir, fmt.Sprintf("file-%d", i+j))
fileContent, err := driver.ReadFile(root, file)
if err != nil {
return err
}
content := randomContent(64, seed+int64(i+j))
if !bytes.Equal(fileContent, content) {
return fmt.Errorf("mismatched file content %v, expecting %v", fileContent, content)
}
}
}
return nil
}
type changeList []archive.Change
func (c changeList) Less(i, j int) bool {
if c[i].Path == c[j].Path {
return c[i].Kind < c[j].Kind
}
return c[i].Path < c[j].Path
}
func (c changeList) Len() int { return len(c) }
func (c changeList) Swap(i, j int) { c[j], c[i] = c[i], c[j] }
func checkChanges(expected, actual []archive.Change) error {
if len(expected) != len(actual) {
return fmt.Errorf("unexpected number of changes, expected %d, got %d", len(expected), len(actual))
}
sort.Sort(changeList(expected))
sort.Sort(changeList(actual))
for i := range expected {
if expected[i] != actual[i] {
return fmt.Errorf("unexpected change, expecting %v, got %v", expected[i], actual[i])
}
}
return nil
}
func addLayerFiles(drv graphdriver.Driver, layer, parent string, i int) error {
root, err := drv.Get(layer, "")
if err != nil {
return err
}
defer drv.Put(layer)
if err := driver.WriteFile(root, root.Join(root.Path(), "top-id"), []byte(layer), 0755); err != nil {
return err
}
layerDir := root.Join(root.Path(), fmt.Sprintf("layer-%d", i))
if err := root.MkdirAll(layerDir, 0755); err != nil {
return err
}
if err := driver.WriteFile(root, root.Join(layerDir, "layer-id"), []byte(layer), 0755); err != nil {
return err
}
return driver.WriteFile(root, root.Join(layerDir, "parent-id"), []byte(parent), 0755)
}
func addManyLayers(drv graphdriver.Driver, baseLayer string, count int) (string, error) {
lastLayer := baseLayer
for i := 1; i <= count; i++ {
nextLayer := stringid.GenerateRandomID()
if err := drv.Create(nextLayer, lastLayer, nil); err != nil {
return "", err
}
if err := addLayerFiles(drv, nextLayer, lastLayer, i); err != nil {
return "", err
}
lastLayer = nextLayer
}
return lastLayer, nil
}
func checkManyLayers(drv graphdriver.Driver, layer string, count int) error {
root, err := drv.Get(layer, "")
if err != nil {
return err
}
defer drv.Put(layer)
layerIDBytes, err := driver.ReadFile(root, root.Join(root.Path(), "top-id"))
if err != nil {
return err
}
if !bytes.Equal(layerIDBytes, []byte(layer)) {
return fmt.Errorf("mismatched file content %v, expecting %v", layerIDBytes, []byte(layer))
}
for i := count; i > 0; i-- {
layerDir := root.Join(root.Path(), fmt.Sprintf("layer-%d", i))
thisLayerIDBytes, err := driver.ReadFile(root, root.Join(layerDir, "layer-id"))
if err != nil {
return err
}
if !bytes.Equal(thisLayerIDBytes, layerIDBytes) {
return fmt.Errorf("mismatched file content %v, expecting %v", thisLayerIDBytes, layerIDBytes)
}
layerIDBytes, err = driver.ReadFile(root, root.Join(layerDir, "parent-id"))
if err != nil {
return err
}
}
return nil
}
// readDir reads a directory just like driver.ReadDir()
// then hides specific files (currently "lost+found")
// so the tests don't "see" it
func readDir(r driver.Driver, dir string) ([]os.FileInfo, error) {
a, err := driver.ReadDir(r, dir)
if err != nil {
return nil, err
}
b := a[:0]
for _, x := range a {
if x.Name() != "lost+found" { // ext4 always have this dir
b = append(b, x)
}
}
return b, nil
}