1 package testutil
2
3 import (
4 "archive/tar"
5 "bytes"
6 crand "crypto/rand"
7 "fmt"
8 "io"
9 mrand "math/rand"
10 "time"
11
12 "github.com/docker/distribution"
13 "github.com/docker/distribution/context"
14 "github.com/opencontainers/go-digest"
15 )
16
17
18
19
20 func CreateRandomTarFile() (rs io.ReadSeeker, dgst digest.Digest, err error) {
21 nFiles := mrand.Intn(10) + 10
22 target := &bytes.Buffer{}
23 wr := tar.NewWriter(target)
24
25
26 header := &tar.Header{
27 Mode: 0644,
28 ModTime: time.Now(),
29 Typeflag: tar.TypeReg,
30 Uname: "randocalrissian",
31 Gname: "cloudcity",
32 AccessTime: time.Now(),
33 ChangeTime: time.Now(),
34 }
35
36 for fileNumber := 0; fileNumber < nFiles; fileNumber++ {
37 fileSize := mrand.Int63n(1<<20) + 1<<20
38
39 header.Name = fmt.Sprint(fileNumber)
40 header.Size = fileSize
41
42 if err := wr.WriteHeader(header); err != nil {
43 return nil, "", err
44 }
45
46 randomData := make([]byte, fileSize)
47
48
49 n, err := crand.Read(randomData)
50
51 if n != len(randomData) {
52 return nil, "", fmt.Errorf("short read creating random reader: %v bytes != %v bytes", n, len(randomData))
53 }
54
55 if err != nil {
56 return nil, "", err
57 }
58
59 nn, err := io.Copy(wr, bytes.NewReader(randomData))
60 if nn != fileSize {
61 return nil, "", fmt.Errorf("short copy writing random file to tar")
62 }
63
64 if err != nil {
65 return nil, "", err
66 }
67
68 if err := wr.Flush(); err != nil {
69 return nil, "", err
70 }
71 }
72
73 if err := wr.Close(); err != nil {
74 return nil, "", err
75 }
76
77 dgst = digest.FromBytes(target.Bytes())
78
79 return bytes.NewReader(target.Bytes()), dgst, nil
80 }
81
82
83
84 func CreateRandomLayers(n int) (map[digest.Digest]io.ReadSeeker, error) {
85 digestMap := map[digest.Digest]io.ReadSeeker{}
86 for i := 0; i < n; i++ {
87 rs, ds, err := CreateRandomTarFile()
88 if err != nil {
89 return nil, fmt.Errorf("unexpected error generating test layer file: %v", err)
90 }
91
92 digestMap[ds] = rs
93 }
94 return digestMap, nil
95 }
96
97
98 func UploadBlobs(repository distribution.Repository, layers map[digest.Digest]io.ReadSeeker) error {
99 ctx := context.Background()
100 for digest, rs := range layers {
101 wr, err := repository.Blobs(ctx).Create(ctx)
102 if err != nil {
103 return fmt.Errorf("unexpected error creating upload: %v", err)
104 }
105
106 if _, err := io.Copy(wr, rs); err != nil {
107 return fmt.Errorf("unexpected error copying to upload: %v", err)
108 }
109
110 if _, err := wr.Commit(ctx, distribution.Descriptor{Digest: digest}); err != nil {
111 return fmt.Errorf("unexpected error committinng upload: %v", err)
112 }
113 }
114 return nil
115 }
116
View as plain text