github.com/dctrud/umoci@v0.4.3-0.20191016193643-05a1d37de015/oci/casext/json_dir_test.go (about) 1 /* 2 * umoci: Umoci Modifies Open Containers' Images 3 * Copyright (C) 2016, 2017, 2018 SUSE LLC. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package casext 19 20 import ( 21 "encoding/json" 22 "io/ioutil" 23 "os" 24 "path/filepath" 25 "reflect" 26 "testing" 27 28 "github.com/openSUSE/umoci/oci/cas/dir" 29 "github.com/pkg/errors" 30 "golang.org/x/net/context" 31 ) 32 33 func TestEngineBlobJSON(t *testing.T) { 34 ctx := context.Background() 35 36 root, err := ioutil.TempDir("", "umoci-TestEngineBlobJSON") 37 if err != nil { 38 t.Fatal(err) 39 } 40 defer os.RemoveAll(root) 41 42 image := filepath.Join(root, "image") 43 if err := dir.Create(image); err != nil { 44 t.Fatalf("unexpected error creating image: %+v", err) 45 } 46 47 engine, err := dir.Open(image) 48 if err != nil { 49 t.Fatalf("unexpected error opening image: %+v", err) 50 } 51 engineExt := NewEngine(engine) 52 defer engine.Close() 53 54 type object struct { 55 A string `json:"A"` 56 B int64 `json:"B,omitempty"` 57 } 58 59 for _, test := range []struct { 60 object object 61 }{ 62 {object{}}, 63 {object{"a value", 100}}, 64 {object{"another value", 200}}, 65 } { 66 digest, _, err := engineExt.PutBlobJSON(ctx, test.object) 67 if err != nil { 68 t.Errorf("PutBlobJSON: unexpected error: %+v", err) 69 } 70 71 blobReader, err := engine.GetBlob(ctx, digest) 72 if err != nil { 73 t.Errorf("GetBlob: unexpected error: %+v", err) 74 } 75 defer blobReader.Close() 76 77 gotBytes, err := ioutil.ReadAll(blobReader) 78 if err != nil { 79 t.Errorf("GetBlob: failed to ReadAll: %+v", err) 80 } 81 82 var gotObject object 83 if err := json.Unmarshal(gotBytes, &gotObject); err != nil { 84 t.Errorf("GetBlob: got an invalid JSON blob: %+v", err) 85 } 86 if !reflect.DeepEqual(test.object, gotObject) { 87 t.Errorf("GetBlob: got different object to original JSON. expected=%v got=%v gotBytes=%v", test.object, gotObject, gotBytes) 88 } 89 90 if err := engine.DeleteBlob(ctx, digest); err != nil { 91 t.Errorf("DeleteBlob: unexpected error: %+v", err) 92 } 93 94 if br, err := engine.GetBlob(ctx, digest); !os.IsNotExist(errors.Cause(err)) { 95 if err == nil { 96 br.Close() 97 t.Errorf("GetBlob: still got blob contents after DeleteBlob!") 98 } else { 99 t.Errorf("GetBlob: unexpected error: %+v", err) 100 } 101 } 102 103 // DeleteBlob is idempotent. It shouldn't cause an error. 104 if err := engine.DeleteBlob(ctx, digest); err != nil { 105 t.Errorf("DeleteBlob: unexpected error on double-delete: %+v", err) 106 } 107 } 108 109 // Should be no blobs left. 110 if blobs, err := engine.ListBlobs(ctx); err != nil { 111 t.Errorf("unexpected error getting list of blobs: %+v", err) 112 } else if len(blobs) > 0 { 113 t.Errorf("got blobs in a clean image: %v", blobs) 114 } 115 } 116 117 func TestEngineBlobJSONReadonly(t *testing.T) { 118 ctx := context.Background() 119 120 root, err := ioutil.TempDir("", "umoci-TestEngineBlobJSONReadonly") 121 if err != nil { 122 t.Fatal(err) 123 } 124 defer os.RemoveAll(root) 125 126 image := filepath.Join(root, "image") 127 if err := dir.Create(image); err != nil { 128 t.Fatalf("unexpected error creating image: %+v", err) 129 } 130 131 type object struct { 132 A string `json:"A"` 133 B int64 `json:"B,omitempty"` 134 } 135 136 for _, test := range []struct { 137 object object 138 }{ 139 {object{}}, 140 {object{"a value", 100}}, 141 {object{"another value", 200}}, 142 } { 143 engine, err := dir.Open(image) 144 if err != nil { 145 t.Fatalf("unexpected error opening image: %+v", err) 146 } 147 engineExt := NewEngine(engine) 148 149 digest, _, err := engineExt.PutBlobJSON(ctx, test.object) 150 if err != nil { 151 t.Errorf("PutBlobJSON: unexpected error: %+v", err) 152 } 153 154 if err := engine.Close(); err != nil { 155 t.Errorf("Close: unexpected error encountered: %+v", err) 156 } 157 158 // make it readonly 159 readonly(t, image) 160 161 newEngine, err := dir.Open(image) 162 if err != nil { 163 t.Errorf("unexpected error opening ro image: %+v", err) 164 } 165 newEngineExt := NewEngine(newEngine) 166 167 blobReader, err := newEngineExt.GetBlob(ctx, digest) 168 if err != nil { 169 t.Errorf("GetBlob: unexpected error: %+v", err) 170 } 171 defer blobReader.Close() 172 173 gotBytes, err := ioutil.ReadAll(blobReader) 174 if err != nil { 175 t.Errorf("GetBlob: failed to ReadAll: %+v", err) 176 } 177 178 var gotObject object 179 if err := json.Unmarshal(gotBytes, &gotObject); err != nil { 180 t.Errorf("GetBlob: got an invalid JSON blob: %+v", err) 181 } 182 if !reflect.DeepEqual(test.object, gotObject) { 183 t.Errorf("GetBlob: got different object to original JSON. expected=%v got=%v gotBytes=%v", test.object, gotObject, gotBytes) 184 } 185 186 // Make sure that writing again will FAIL. 187 _, _, err = newEngineExt.PutBlobJSON(ctx, test.object) 188 if err == nil { 189 t.Errorf("PutBlob: expected error on ro image!") 190 } 191 192 if err := newEngine.Close(); err != nil { 193 t.Errorf("Close: unexpected error encountered on ro: %+v", err) 194 } 195 196 // make it readwrite again. 197 readwrite(t, image) 198 } 199 }