123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- 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)
- var 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
- }
|