github.com/docker/engine@v22.0.0-20211208180946-d456264580cf+incompatible/image/store_test.go (about) 1 package image // import "github.com/docker/docker/image" 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/docker/docker/layer" 8 "gotest.tools/v3/assert" 9 "gotest.tools/v3/assert/cmp" 10 ) 11 12 func TestCreate(t *testing.T) { 13 is, cleanup := defaultImageStore(t) 14 defer cleanup() 15 16 _, err := is.Create([]byte(`{}`)) 17 assert.Check(t, cmp.Error(err, "invalid image JSON, no RootFS key")) 18 } 19 20 func TestRestore(t *testing.T) { 21 fs, cleanup := defaultFSStoreBackend(t) 22 defer cleanup() 23 24 id1, err := fs.Set([]byte(`{"comment": "abc", "rootfs": {"type": "layers"}}`)) 25 assert.NilError(t, err) 26 27 _, err = fs.Set([]byte(`invalid`)) 28 assert.NilError(t, err) 29 30 id2, err := fs.Set([]byte(`{"comment": "def", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`)) 31 assert.NilError(t, err) 32 33 err = fs.SetMetadata(id2, "parent", []byte(id1)) 34 assert.NilError(t, err) 35 36 is, err := NewImageStore(fs, &mockLayerGetReleaser{}) 37 assert.NilError(t, err) 38 39 assert.Check(t, cmp.Len(is.Map(), 2)) 40 41 img1, err := is.Get(ID(id1)) 42 assert.NilError(t, err) 43 assert.Check(t, cmp.Equal(ID(id1), img1.computedID)) 44 assert.Check(t, cmp.Equal(string(id1), img1.computedID.String())) 45 46 img2, err := is.Get(ID(id2)) 47 assert.NilError(t, err) 48 assert.Check(t, cmp.Equal("abc", img1.Comment)) 49 assert.Check(t, cmp.Equal("def", img2.Comment)) 50 51 _, err = is.GetParent(ID(id1)) 52 assert.ErrorContains(t, err, "failed to read metadata") 53 54 p, err := is.GetParent(ID(id2)) 55 assert.NilError(t, err) 56 assert.Check(t, cmp.Equal(ID(id1), p)) 57 58 children := is.Children(ID(id1)) 59 assert.Check(t, cmp.Len(children, 1)) 60 assert.Check(t, cmp.Equal(ID(id2), children[0])) 61 assert.Check(t, cmp.Len(is.Heads(), 1)) 62 63 sid1, err := is.Search(string(id1)[:10]) 64 assert.NilError(t, err) 65 assert.Check(t, cmp.Equal(ID(id1), sid1)) 66 67 sid1, err = is.Search(id1.Hex()[:6]) 68 assert.NilError(t, err) 69 assert.Check(t, cmp.Equal(ID(id1), sid1)) 70 71 invalidPattern := id1.Hex()[1:6] 72 _, err = is.Search(invalidPattern) 73 assert.ErrorContains(t, err, "No such image") 74 } 75 76 func TestAddDelete(t *testing.T) { 77 is, cleanup := defaultImageStore(t) 78 defer cleanup() 79 80 id1, err := is.Create([]byte(`{"comment": "abc", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`)) 81 assert.NilError(t, err) 82 assert.Check(t, cmp.Equal(ID("sha256:8d25a9c45df515f9d0fe8e4a6b1c64dd3b965a84790ddbcc7954bb9bc89eb993"), id1)) 83 84 img, err := is.Get(id1) 85 assert.NilError(t, err) 86 assert.Check(t, cmp.Equal("abc", img.Comment)) 87 88 id2, err := is.Create([]byte(`{"comment": "def", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`)) 89 assert.NilError(t, err) 90 91 err = is.SetParent(id2, id1) 92 assert.NilError(t, err) 93 94 pid1, err := is.GetParent(id2) 95 assert.NilError(t, err) 96 assert.Check(t, cmp.Equal(pid1, id1)) 97 98 _, err = is.Delete(id1) 99 assert.NilError(t, err) 100 101 _, err = is.Get(id1) 102 assert.ErrorContains(t, err, "failed to get digest") 103 104 _, err = is.Get(id2) 105 assert.NilError(t, err) 106 107 _, err = is.GetParent(id2) 108 assert.ErrorContains(t, err, "failed to read metadata") 109 } 110 111 func TestSearchAfterDelete(t *testing.T) { 112 is, cleanup := defaultImageStore(t) 113 defer cleanup() 114 115 id, err := is.Create([]byte(`{"comment": "abc", "rootfs": {"type": "layers"}}`)) 116 assert.NilError(t, err) 117 118 id1, err := is.Search(string(id)[:15]) 119 assert.NilError(t, err) 120 assert.Check(t, cmp.Equal(id1, id)) 121 122 _, err = is.Delete(id) 123 assert.NilError(t, err) 124 125 _, err = is.Search(string(id)[:15]) 126 assert.ErrorContains(t, err, "No such image") 127 } 128 129 func TestParentReset(t *testing.T) { 130 is, cleanup := defaultImageStore(t) 131 defer cleanup() 132 133 id, err := is.Create([]byte(`{"comment": "abc1", "rootfs": {"type": "layers"}}`)) 134 assert.NilError(t, err) 135 136 id2, err := is.Create([]byte(`{"comment": "abc2", "rootfs": {"type": "layers"}}`)) 137 assert.NilError(t, err) 138 139 id3, err := is.Create([]byte(`{"comment": "abc3", "rootfs": {"type": "layers"}}`)) 140 assert.NilError(t, err) 141 142 assert.Check(t, is.SetParent(id, id2)) 143 assert.Check(t, cmp.Len(is.Children(id2), 1)) 144 145 assert.Check(t, is.SetParent(id, id3)) 146 assert.Check(t, cmp.Len(is.Children(id2), 0)) 147 assert.Check(t, cmp.Len(is.Children(id3), 1)) 148 } 149 150 func defaultImageStore(t *testing.T) (Store, func()) { 151 fsBackend, cleanup := defaultFSStoreBackend(t) 152 153 store, err := NewImageStore(fsBackend, &mockLayerGetReleaser{}) 154 assert.NilError(t, err) 155 156 return store, cleanup 157 } 158 159 func TestGetAndSetLastUpdated(t *testing.T) { 160 store, cleanup := defaultImageStore(t) 161 defer cleanup() 162 163 id, err := store.Create([]byte(`{"comment": "abc1", "rootfs": {"type": "layers"}}`)) 164 assert.NilError(t, err) 165 166 updated, err := store.GetLastUpdated(id) 167 assert.NilError(t, err) 168 assert.Check(t, cmp.Equal(updated.IsZero(), true)) 169 170 assert.Check(t, store.SetLastUpdated(id)) 171 172 updated, err = store.GetLastUpdated(id) 173 assert.NilError(t, err) 174 assert.Check(t, cmp.Equal(updated.IsZero(), false)) 175 } 176 177 func TestStoreLen(t *testing.T) { 178 store, cleanup := defaultImageStore(t) 179 defer cleanup() 180 181 expected := 10 182 for i := 0; i < expected; i++ { 183 _, err := store.Create([]byte(fmt.Sprintf(`{"comment": "abc%d", "rootfs": {"type": "layers"}}`, i))) 184 assert.NilError(t, err) 185 } 186 numImages := store.Len() 187 assert.Equal(t, expected, numImages) 188 assert.Equal(t, len(store.Map()), numImages) 189 } 190 191 type mockLayerGetReleaser struct{} 192 193 func (ls *mockLayerGetReleaser) Get(layer.ChainID) (layer.Layer, error) { 194 return nil, nil 195 } 196 197 func (ls *mockLayerGetReleaser) Release(layer.Layer) ([]layer.Metadata, error) { 198 return nil, nil 199 }