github.com/resin-io/docker@v1.13.1/image/store_test.go (about)

     1  package image
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"testing"
     7  
     8  	"github.com/docker/distribution/digest"
     9  	"github.com/docker/docker/layer"
    10  )
    11  
    12  func TestRestore(t *testing.T) {
    13  	tmpdir, err := ioutil.TempDir("", "images-fs-store")
    14  	if err != nil {
    15  		t.Fatal(err)
    16  	}
    17  	defer os.RemoveAll(tmpdir)
    18  	fs, err := NewFSStoreBackend(tmpdir)
    19  	if err != nil {
    20  		t.Fatal(err)
    21  	}
    22  
    23  	id1, err := fs.Set([]byte(`{"comment": "abc", "rootfs": {"type": "layers"}}`))
    24  	if err != nil {
    25  		t.Fatal(err)
    26  	}
    27  	_, err = fs.Set([]byte(`invalid`))
    28  	if err != nil {
    29  		t.Fatal(err)
    30  	}
    31  	id2, err := fs.Set([]byte(`{"comment": "def", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`))
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  	err = fs.SetMetadata(id2, "parent", []byte(id1))
    36  	if err != nil {
    37  		t.Fatal(err)
    38  	}
    39  
    40  	is, err := NewImageStore(fs, &mockLayerGetReleaser{})
    41  	if err != nil {
    42  		t.Fatal(err)
    43  	}
    44  
    45  	imgs := is.Map()
    46  	if actual, expected := len(imgs), 2; actual != expected {
    47  		t.Fatalf("invalid images length, expected 2, got %q", len(imgs))
    48  	}
    49  
    50  	img1, err := is.Get(ID(id1))
    51  	if err != nil {
    52  		t.Fatal(err)
    53  	}
    54  
    55  	if actual, expected := img1.computedID, ID(id1); actual != expected {
    56  		t.Fatalf("invalid image ID: expected %q, got %q", expected, actual)
    57  	}
    58  
    59  	if actual, expected := img1.computedID.String(), string(id1); actual != expected {
    60  		t.Fatalf("invalid image ID string: expected %q, got %q", expected, actual)
    61  	}
    62  
    63  	img2, err := is.Get(ID(id2))
    64  	if err != nil {
    65  		t.Fatal(err)
    66  	}
    67  
    68  	if actual, expected := img1.Comment, "abc"; actual != expected {
    69  		t.Fatalf("invalid comment for image1: expected %q, got %q", expected, actual)
    70  	}
    71  
    72  	if actual, expected := img2.Comment, "def"; actual != expected {
    73  		t.Fatalf("invalid comment for image2: expected %q, got %q", expected, actual)
    74  	}
    75  
    76  	p, err := is.GetParent(ID(id1))
    77  	if err == nil {
    78  		t.Fatal("expected error for getting parent")
    79  	}
    80  
    81  	p, err = is.GetParent(ID(id2))
    82  	if err != nil {
    83  		t.Fatal(err)
    84  	}
    85  	if actual, expected := p, ID(id1); actual != expected {
    86  		t.Fatalf("invalid parent: expected %q, got %q", expected, actual)
    87  	}
    88  
    89  	children := is.Children(ID(id1))
    90  	if len(children) != 1 {
    91  		t.Fatalf("invalid children length: %q", len(children))
    92  	}
    93  	if actual, expected := children[0], ID(id2); actual != expected {
    94  		t.Fatalf("invalid child for id1: expected %q, got %q", expected, actual)
    95  	}
    96  
    97  	heads := is.Heads()
    98  	if actual, expected := len(heads), 1; actual != expected {
    99  		t.Fatalf("invalid images length: expected %q, got %q", expected, actual)
   100  	}
   101  
   102  	sid1, err := is.Search(string(id1)[:10])
   103  	if err != nil {
   104  		t.Fatal(err)
   105  	}
   106  	if actual, expected := sid1, ID(id1); actual != expected {
   107  		t.Fatalf("searched ID mismatch: expected %q, got %q", expected, actual)
   108  	}
   109  
   110  	sid1, err = is.Search(digest.Digest(id1).Hex()[:6])
   111  	if err != nil {
   112  		t.Fatal(err)
   113  	}
   114  	if actual, expected := sid1, ID(id1); actual != expected {
   115  		t.Fatalf("searched ID mismatch: expected %q, got %q", expected, actual)
   116  	}
   117  
   118  	invalidPattern := digest.Digest(id1).Hex()[1:6]
   119  	_, err = is.Search(invalidPattern)
   120  	if err == nil {
   121  		t.Fatalf("expected search for %q to fail", invalidPattern)
   122  	}
   123  
   124  }
   125  
   126  func TestAddDelete(t *testing.T) {
   127  	tmpdir, err := ioutil.TempDir("", "images-fs-store")
   128  	if err != nil {
   129  		t.Fatal(err)
   130  	}
   131  	defer os.RemoveAll(tmpdir)
   132  	fs, err := NewFSStoreBackend(tmpdir)
   133  	if err != nil {
   134  		t.Fatal(err)
   135  	}
   136  
   137  	is, err := NewImageStore(fs, &mockLayerGetReleaser{})
   138  	if err != nil {
   139  		t.Fatal(err)
   140  	}
   141  
   142  	id1, err := is.Create([]byte(`{"comment": "abc", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`))
   143  	if err != nil {
   144  		t.Fatal(err)
   145  	}
   146  
   147  	if actual, expected := id1, ID("sha256:8d25a9c45df515f9d0fe8e4a6b1c64dd3b965a84790ddbcc7954bb9bc89eb993"); actual != expected {
   148  		t.Fatalf("create ID mismatch: expected %q, got %q", expected, actual)
   149  	}
   150  
   151  	img, err := is.Get(id1)
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  
   156  	if actual, expected := img.Comment, "abc"; actual != expected {
   157  		t.Fatalf("invalid comment in image: expected %q, got %q", expected, actual)
   158  	}
   159  
   160  	id2, err := is.Create([]byte(`{"comment": "def", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`))
   161  	if err != nil {
   162  		t.Fatal(err)
   163  	}
   164  
   165  	err = is.SetParent(id2, id1)
   166  	if err != nil {
   167  		t.Fatal(err)
   168  	}
   169  
   170  	pid1, err := is.GetParent(id2)
   171  	if err != nil {
   172  		t.Fatal(err)
   173  	}
   174  	if actual, expected := pid1, id1; actual != expected {
   175  		t.Fatalf("invalid parent for image: expected %q, got %q", expected, actual)
   176  	}
   177  
   178  	_, err = is.Delete(id1)
   179  	if err != nil {
   180  		t.Fatal(err)
   181  	}
   182  	_, err = is.Get(id1)
   183  	if err == nil {
   184  		t.Fatalf("expected get for deleted image %q to fail", id1)
   185  	}
   186  	_, err = is.Get(id2)
   187  	if err != nil {
   188  		t.Fatal(err)
   189  	}
   190  	pid1, err = is.GetParent(id2)
   191  	if err == nil {
   192  		t.Fatalf("expected parent check for image %q to fail, got %q", id2, pid1)
   193  	}
   194  
   195  }
   196  
   197  func TestSearchAfterDelete(t *testing.T) {
   198  	tmpdir, err := ioutil.TempDir("", "images-fs-store")
   199  	if err != nil {
   200  		t.Fatal(err)
   201  	}
   202  	defer os.RemoveAll(tmpdir)
   203  	fs, err := NewFSStoreBackend(tmpdir)
   204  	if err != nil {
   205  		t.Fatal(err)
   206  	}
   207  
   208  	is, err := NewImageStore(fs, &mockLayerGetReleaser{})
   209  	if err != nil {
   210  		t.Fatal(err)
   211  	}
   212  
   213  	id, err := is.Create([]byte(`{"comment": "abc", "rootfs": {"type": "layers"}}`))
   214  	if err != nil {
   215  		t.Fatal(err)
   216  	}
   217  
   218  	id1, err := is.Search(string(id)[:15])
   219  	if err != nil {
   220  		t.Fatal(err)
   221  	}
   222  
   223  	if actual, expected := id1, id; expected != actual {
   224  		t.Fatalf("wrong id returned from search: expected %q, got %q", expected, actual)
   225  	}
   226  
   227  	if _, err := is.Delete(id); err != nil {
   228  		t.Fatal(err)
   229  	}
   230  
   231  	if _, err := is.Search(string(id)[:15]); err == nil {
   232  		t.Fatal("expected search after deletion to fail")
   233  	}
   234  }
   235  
   236  func TestParentReset(t *testing.T) {
   237  	tmpdir, err := ioutil.TempDir("", "images-fs-store")
   238  	if err != nil {
   239  		t.Fatal(err)
   240  	}
   241  	defer os.RemoveAll(tmpdir)
   242  	fs, err := NewFSStoreBackend(tmpdir)
   243  	if err != nil {
   244  		t.Fatal(err)
   245  	}
   246  
   247  	is, err := NewImageStore(fs, &mockLayerGetReleaser{})
   248  	if err != nil {
   249  		t.Fatal(err)
   250  	}
   251  
   252  	id, err := is.Create([]byte(`{"comment": "abc1", "rootfs": {"type": "layers"}}`))
   253  	if err != nil {
   254  		t.Fatal(err)
   255  	}
   256  
   257  	id2, err := is.Create([]byte(`{"comment": "abc2", "rootfs": {"type": "layers"}}`))
   258  	if err != nil {
   259  		t.Fatal(err)
   260  	}
   261  
   262  	id3, err := is.Create([]byte(`{"comment": "abc3", "rootfs": {"type": "layers"}}`))
   263  	if err != nil {
   264  		t.Fatal(err)
   265  	}
   266  
   267  	if err := is.SetParent(id, id2); err != nil {
   268  		t.Fatal(err)
   269  	}
   270  
   271  	ids := is.Children(id2)
   272  	if actual, expected := len(ids), 1; expected != actual {
   273  		t.Fatalf("wrong number of children: %d, got %d", expected, actual)
   274  	}
   275  
   276  	if err := is.SetParent(id, id3); err != nil {
   277  		t.Fatal(err)
   278  	}
   279  
   280  	ids = is.Children(id2)
   281  	if actual, expected := len(ids), 0; expected != actual {
   282  		t.Fatalf("wrong number of children after parent reset: %d, got %d", expected, actual)
   283  	}
   284  
   285  	ids = is.Children(id3)
   286  	if actual, expected := len(ids), 1; expected != actual {
   287  		t.Fatalf("wrong number of children after parent reset: %d, got %d", expected, actual)
   288  	}
   289  
   290  }
   291  
   292  type mockLayerGetReleaser struct{}
   293  
   294  func (ls *mockLayerGetReleaser) Get(layer.ChainID) (layer.Layer, error) {
   295  	return nil, nil
   296  }
   297  
   298  func (ls *mockLayerGetReleaser) Release(layer.Layer) ([]layer.Metadata, error) {
   299  	return nil, nil
   300  }