func TestTreeStore(t *testing.T) { if !sys.HasChrootCapability() { t.Skipf("chroot capability not available. Disabling test.") } dir, err := ioutil.TempDir("", tstprefix) if err != nil { t.Fatalf("error creating tempdir: %v", err) } defer os.RemoveAll(dir) s, err := NewStore(dir) if err != nil { t.Fatalf("unexpected error: %v", err) } imj := ` { "acKind": "ImageManifest", "acVersion": "0.7.1", "name": "example.com/test01" } ` entries := []*aci.ACIEntry{ // An empty dir { Header: &tar.Header{ Name: "rootfs/a", Typeflag: tar.TypeDir, }, }, { Contents: "hello", Header: &tar.Header{ Name: "hello.txt", Size: 5, }, }, { Header: &tar.Header{ Name: "rootfs/link.txt", Linkname: "rootfs/hello.txt", Typeflag: tar.TypeSymlink, }, }, // dangling symlink { Header: &tar.Header{ Name: "rootfs/link2.txt", Linkname: "rootfs/missingfile.txt", Typeflag: tar.TypeSymlink, }, }, { Header: &tar.Header{ Name: "rootfs/fifo", Typeflag: tar.TypeFifo, }, }, } aci, err := aci.NewACI(dir, imj, entries) if err != nil { t.Fatalf("error creating test tar: %v", err) } defer aci.Close() // Rewind the ACI if _, err := aci.Seek(0, 0); err != nil { t.Fatalf("unexpected error %v", err) } // Import the new ACI key, err := s.WriteACI(aci, false) if err != nil { t.Fatalf("unexpected error: %v", err) } // Ask the store to render the treestore id, err := s.RenderTreeStore(key, false) if err != nil { t.Fatalf("unexpected error: %v", err) } // Verify image Hash. Should be the same. err = s.CheckTreeStore(id) if err != nil { t.Fatalf("unexpected error: %v", err) } // Change a file permission rootfs := s.GetTreeStoreRootFS(id) err = os.Chmod(filepath.Join(rootfs, "a"), 0600) if err != nil { t.Fatalf("unexpected error: %v", err) } // Verify image Hash. Should be different err = s.CheckTreeStore(id) if err == nil { t.Errorf("expected non-nil error!") } // rebuild the tree prevID := id id, err = s.RenderTreeStore(key, true) if err != nil { t.Fatalf("unexpected error: %v", err) } if id != prevID { t.Fatalf("unexpected different IDs. prevID: %s, id: %s", prevID, id) } // Add a file rootfs = s.GetTreeStoreRootFS(id) err = ioutil.WriteFile(filepath.Join(rootfs, "newfile"), []byte("newfile"), 0644) if err != nil { t.Fatalf("unexpected error: %v", err) } // Verify image Hash. Should be different err = s.CheckTreeStore(id) if err == nil { t.Errorf("expected non-nil error!") } }
// TODO(sgotti) when the TreeStore will use an interface, change it to a // test implementation without relying on store/imagestore func testStoreWriteACI(dir string, s *imagestore.Store) (string, error) { imj := ` { "acKind": "ImageManifest", "acVersion": "0.8.8", "name": "example.com/test01" } ` entries := []*aci.ACIEntry{ // An empty dir { Header: &tar.Header{ Name: "rootfs/a", Typeflag: tar.TypeDir, }, }, { Contents: "hello", Header: &tar.Header{ Name: "hello.txt", Size: 5, }, }, { Header: &tar.Header{ Name: "rootfs/link.txt", Linkname: "rootfs/hello.txt", Typeflag: tar.TypeSymlink, }, }, // dangling symlink { Header: &tar.Header{ Name: "rootfs/link2.txt", Linkname: "rootfs/missingfile.txt", Typeflag: tar.TypeSymlink, }, }, { Header: &tar.Header{ Name: "rootfs/fifo", Typeflag: tar.TypeFifo, }, }, } aci, err := aci.NewACI(dir, imj, entries) if err != nil { return "", err } defer aci.Close() // Rewind the ACI if _, err := aci.Seek(0, 0); err != nil { return "", err } // Import the new ACI key, err := s.WriteACI(aci, imagestore.ACIFetchInfo{Latest: false}) if err != nil { return "", err } return key, nil }