Allows layers to be partially pulled and resumed
Adds a sort of contrived test for resumable pulls
This commit is contained in:
parent
73d6e8af84
commit
50d64ac63a
4 changed files with 271 additions and 59 deletions
|
@ -117,6 +117,7 @@ func TestPush(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
writer.SetSize(len(blob.contents))
|
||||
writer.Write(blob.contents)
|
||||
writer.Close()
|
||||
}
|
||||
|
@ -235,3 +236,133 @@ func TestPull(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPullResume(t *testing.T) {
|
||||
name := "hello/world"
|
||||
tag := "sometag"
|
||||
testBlobs := []testBlob{
|
||||
{
|
||||
digest: "12345",
|
||||
contents: []byte("some contents"),
|
||||
},
|
||||
{
|
||||
digest: "98765",
|
||||
contents: []byte("some other contents"),
|
||||
},
|
||||
}
|
||||
layers := make([]registry.FSLayer, len(testBlobs))
|
||||
history := make([]registry.ManifestHistory, len(testBlobs))
|
||||
|
||||
for i, layer := range testBlobs {
|
||||
layers[i] = registry.FSLayer{BlobSum: layer.digest}
|
||||
history[i] = registry.ManifestHistory{V1Compatibility: layer.digest.String()}
|
||||
}
|
||||
|
||||
manifest := ®istry.ImageManifest{
|
||||
Name: name,
|
||||
Tag: tag,
|
||||
Architecture: "x86",
|
||||
FSLayers: layers,
|
||||
History: history,
|
||||
SchemaVersion: 1,
|
||||
}
|
||||
manifestBytes, err := json.Marshal(manifest)
|
||||
|
||||
layerRequestResponseMappings := make([]testutil.RequestResponseMapping, 2*len(testBlobs))
|
||||
for i, blob := range testBlobs {
|
||||
layerRequestResponseMappings[2*i] = testutil.RequestResponseMapping{
|
||||
Request: testutil.Request{
|
||||
Method: "GET",
|
||||
Route: "/v2/" + name + "/blob/" + blob.digest.String(),
|
||||
},
|
||||
Response: testutil.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: blob.contents[:len(blob.contents)/2],
|
||||
Headers: http.Header(map[string][]string{
|
||||
"Content-Length": {fmt.Sprint(len(blob.contents))},
|
||||
}),
|
||||
},
|
||||
}
|
||||
layerRequestResponseMappings[2*i+1] = testutil.RequestResponseMapping{
|
||||
Request: testutil.Request{
|
||||
Method: "GET",
|
||||
Route: "/v2/" + name + "/blob/" + blob.digest.String(),
|
||||
},
|
||||
Response: testutil.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: blob.contents[len(blob.contents)/2:],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
layerRequestResponseMappings = append(layerRequestResponseMappings, testutil.RequestResponseMap{
|
||||
testutil.RequestResponseMapping{
|
||||
Request: testutil.Request{
|
||||
Method: "GET",
|
||||
Route: "/v2/" + name + "/manifest/" + tag,
|
||||
},
|
||||
Response: testutil.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: manifestBytes,
|
||||
},
|
||||
},
|
||||
}...)
|
||||
}
|
||||
|
||||
handler := testutil.NewHandler(layerRequestResponseMappings)
|
||||
server := httptest.NewServer(handler)
|
||||
client := New(server.URL)
|
||||
objectStore := &memoryObjectStore{
|
||||
mutex: new(sync.Mutex),
|
||||
manifestStorage: make(map[string]*registry.ImageManifest),
|
||||
layerStorage: make(map[digest.Digest]Layer),
|
||||
}
|
||||
|
||||
for attempts := 0; attempts < 3; attempts++ {
|
||||
err = Pull(client, objectStore, name, tag)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m, err := objectStore.Manifest(name, tag)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mBytes, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if string(mBytes) != string(manifestBytes) {
|
||||
t.Fatal("Incorrect manifest")
|
||||
}
|
||||
|
||||
for _, blob := range testBlobs {
|
||||
l, err := objectStore.Layer(blob.digest)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
reader, err := l.Reader()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
layerBytes, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if string(layerBytes) != string(blob.contents) {
|
||||
t.Fatal("Incorrect blob")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue