github.com/adxhyt/docker@v1.4.2-0.20150117221845-467b7c821390/daemon/graphdriver/graphtest/graphtest.go (about)

     1  package graphtest
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path"
     8  	"syscall"
     9  	"testing"
    10  
    11  	"github.com/docker/docker/daemon/graphdriver"
    12  )
    13  
    14  var (
    15  	drv *Driver
    16  )
    17  
    18  type Driver struct {
    19  	graphdriver.Driver
    20  	root     string
    21  	refCount int
    22  }
    23  
    24  // InitLoopbacks ensures that the loopback devices are properly created within
    25  // the system running the device mapper tests.
    26  func InitLoopbacks() error {
    27  	stat_t, err := getBaseLoopStats()
    28  	if err != nil {
    29  		return err
    30  	}
    31  	// create atleast 8 loopback files, ya, that is a good number
    32  	for i := 0; i < 8; i++ {
    33  		loopPath := fmt.Sprintf("/dev/loop%d", i)
    34  		// only create new loopback files if they don't exist
    35  		if _, err := os.Stat(loopPath); err != nil {
    36  			if mkerr := syscall.Mknod(loopPath,
    37  				uint32(stat_t.Mode|syscall.S_IFBLK), int((7<<8)|(i&0xff)|((i&0xfff00)<<12))); mkerr != nil {
    38  				return mkerr
    39  			}
    40  			os.Chown(loopPath, int(stat_t.Uid), int(stat_t.Gid))
    41  		}
    42  	}
    43  	return nil
    44  }
    45  
    46  // getBaseLoopStats inspects /dev/loop0 to collect uid,gid, and mode for the
    47  // loop0 device on the system.  If it does not exist we assume 0,0,0660 for the
    48  // stat data
    49  func getBaseLoopStats() (*syscall.Stat_t, error) {
    50  	loop0, err := os.Stat("/dev/loop0")
    51  	if err != nil {
    52  		if os.IsNotExist(err) {
    53  			return &syscall.Stat_t{
    54  				Uid:  0,
    55  				Gid:  0,
    56  				Mode: 0660,
    57  			}, nil
    58  		}
    59  		return nil, err
    60  	}
    61  	return loop0.Sys().(*syscall.Stat_t), nil
    62  }
    63  
    64  func newDriver(t *testing.T, name string) *Driver {
    65  	root, err := ioutil.TempDir("/var/tmp", "docker-graphtest-")
    66  	if err != nil {
    67  		t.Fatal(err)
    68  	}
    69  
    70  	if err := os.MkdirAll(root, 0755); err != nil {
    71  		t.Fatal(err)
    72  	}
    73  
    74  	d, err := graphdriver.GetDriver(name, root, nil)
    75  	if err != nil {
    76  		if err == graphdriver.ErrNotSupported || err == graphdriver.ErrPrerequisites {
    77  			t.Skipf("Driver %s not supported", name)
    78  		}
    79  		t.Fatal(err)
    80  	}
    81  	return &Driver{d, root, 1}
    82  }
    83  
    84  func cleanup(t *testing.T, d *Driver) {
    85  	if err := drv.Cleanup(); err != nil {
    86  		t.Fatal(err)
    87  	}
    88  	os.RemoveAll(d.root)
    89  }
    90  
    91  func GetDriver(t *testing.T, name string) graphdriver.Driver {
    92  	if drv == nil {
    93  		drv = newDriver(t, name)
    94  	} else {
    95  		drv.refCount++
    96  	}
    97  	return drv
    98  }
    99  
   100  func PutDriver(t *testing.T) {
   101  	if drv == nil {
   102  		t.Skip("No driver to put!")
   103  	}
   104  	drv.refCount--
   105  	if drv.refCount == 0 {
   106  		cleanup(t, drv)
   107  		drv = nil
   108  	}
   109  }
   110  
   111  func verifyFile(t *testing.T, path string, mode os.FileMode, uid, gid uint32) {
   112  	fi, err := os.Stat(path)
   113  	if err != nil {
   114  		t.Fatal(err)
   115  	}
   116  
   117  	if fi.Mode()&os.ModeType != mode&os.ModeType {
   118  		t.Fatalf("Expected %s type 0x%x, got 0x%x", path, mode&os.ModeType, fi.Mode()&os.ModeType)
   119  	}
   120  
   121  	if fi.Mode()&os.ModePerm != mode&os.ModePerm {
   122  		t.Fatalf("Expected %s mode %o, got %o", path, mode&os.ModePerm, fi.Mode()&os.ModePerm)
   123  	}
   124  
   125  	if fi.Mode()&os.ModeSticky != mode&os.ModeSticky {
   126  		t.Fatalf("Expected %s sticky 0x%x, got 0x%x", path, mode&os.ModeSticky, fi.Mode()&os.ModeSticky)
   127  	}
   128  
   129  	if fi.Mode()&os.ModeSetuid != mode&os.ModeSetuid {
   130  		t.Fatalf("Expected %s setuid 0x%x, got 0x%x", path, mode&os.ModeSetuid, fi.Mode()&os.ModeSetuid)
   131  	}
   132  
   133  	if fi.Mode()&os.ModeSetgid != mode&os.ModeSetgid {
   134  		t.Fatalf("Expected %s setgid 0x%x, got 0x%x", path, mode&os.ModeSetgid, fi.Mode()&os.ModeSetgid)
   135  	}
   136  
   137  	if stat, ok := fi.Sys().(*syscall.Stat_t); ok {
   138  		if stat.Uid != uid {
   139  			t.Fatalf("%s no owned by uid %d", path, uid)
   140  		}
   141  		if stat.Gid != gid {
   142  			t.Fatalf("%s not owned by gid %d", path, gid)
   143  		}
   144  	}
   145  
   146  }
   147  
   148  // Creates an new image and verifies it is empty and the right metadata
   149  func DriverTestCreateEmpty(t *testing.T, drivername string) {
   150  	driver := GetDriver(t, drivername)
   151  	defer PutDriver(t)
   152  
   153  	if err := driver.Create("empty", ""); err != nil {
   154  		t.Fatal(err)
   155  	}
   156  
   157  	if !driver.Exists("empty") {
   158  		t.Fatal("Newly created image doesn't exist")
   159  	}
   160  
   161  	dir, err := driver.Get("empty", "")
   162  	if err != nil {
   163  		t.Fatal(err)
   164  	}
   165  
   166  	verifyFile(t, dir, 0755|os.ModeDir, 0, 0)
   167  
   168  	// Verify that the directory is empty
   169  	fis, err := ioutil.ReadDir(dir)
   170  	if err != nil {
   171  		t.Fatal(err)
   172  	}
   173  
   174  	if len(fis) != 0 {
   175  		t.Fatal("New directory not empty")
   176  	}
   177  
   178  	driver.Put("empty")
   179  
   180  	if err := driver.Remove("empty"); err != nil {
   181  		t.Fatal(err)
   182  	}
   183  
   184  }
   185  
   186  func createBase(t *testing.T, driver graphdriver.Driver, name string) {
   187  	// We need to be able to set any perms
   188  	oldmask := syscall.Umask(0)
   189  	defer syscall.Umask(oldmask)
   190  
   191  	if err := driver.Create(name, ""); err != nil {
   192  		t.Fatal(err)
   193  	}
   194  
   195  	dir, err := driver.Get(name, "")
   196  	if err != nil {
   197  		t.Fatal(err)
   198  	}
   199  	defer driver.Put(name)
   200  
   201  	subdir := path.Join(dir, "a subdir")
   202  	if err := os.Mkdir(subdir, 0705|os.ModeSticky); err != nil {
   203  		t.Fatal(err)
   204  	}
   205  	if err := os.Chown(subdir, 1, 2); err != nil {
   206  		t.Fatal(err)
   207  	}
   208  
   209  	file := path.Join(dir, "a file")
   210  	if err := ioutil.WriteFile(file, []byte("Some data"), 0222|os.ModeSetuid); err != nil {
   211  		t.Fatal(err)
   212  	}
   213  }
   214  
   215  func verifyBase(t *testing.T, driver graphdriver.Driver, name string) {
   216  	dir, err := driver.Get(name, "")
   217  	if err != nil {
   218  		t.Fatal(err)
   219  	}
   220  	defer driver.Put(name)
   221  
   222  	subdir := path.Join(dir, "a subdir")
   223  	verifyFile(t, subdir, 0705|os.ModeDir|os.ModeSticky, 1, 2)
   224  
   225  	file := path.Join(dir, "a file")
   226  	verifyFile(t, file, 0222|os.ModeSetuid, 0, 0)
   227  
   228  	fis, err := ioutil.ReadDir(dir)
   229  	if err != nil {
   230  		t.Fatal(err)
   231  	}
   232  
   233  	if len(fis) != 2 {
   234  		t.Fatal("Unexpected files in base image")
   235  	}
   236  
   237  }
   238  
   239  func DriverTestCreateBase(t *testing.T, drivername string) {
   240  	driver := GetDriver(t, drivername)
   241  	defer PutDriver(t)
   242  
   243  	createBase(t, driver, "Base")
   244  	verifyBase(t, driver, "Base")
   245  
   246  	if err := driver.Remove("Base"); err != nil {
   247  		t.Fatal(err)
   248  	}
   249  }
   250  
   251  func DriverTestCreateSnap(t *testing.T, drivername string) {
   252  	driver := GetDriver(t, drivername)
   253  	defer PutDriver(t)
   254  
   255  	createBase(t, driver, "Base")
   256  
   257  	if err := driver.Create("Snap", "Base"); err != nil {
   258  		t.Fatal(err)
   259  	}
   260  
   261  	verifyBase(t, driver, "Snap")
   262  
   263  	if err := driver.Remove("Snap"); err != nil {
   264  		t.Fatal(err)
   265  	}
   266  
   267  	if err := driver.Remove("Base"); err != nil {
   268  		t.Fatal(err)
   269  	}
   270  }