github.com/moby/docker@v26.1.3+incompatible/integration/build/build_session_test.go (about) 1 package build 2 3 import ( 4 "context" 5 "io" 6 "net" 7 "net/http" 8 "strings" 9 "testing" 10 11 "github.com/docker/docker/api/types" 12 dclient "github.com/docker/docker/client" 13 "github.com/docker/docker/testutil" 14 "github.com/docker/docker/testutil/fakecontext" 15 "github.com/docker/docker/testutil/request" 16 "github.com/moby/buildkit/session" 17 "github.com/moby/buildkit/session/filesync" 18 "github.com/tonistiigi/fsutil" 19 "golang.org/x/sync/errgroup" 20 "gotest.tools/v3/assert" 21 is "gotest.tools/v3/assert/cmp" 22 "gotest.tools/v3/skip" 23 ) 24 25 func TestBuildWithSession(t *testing.T) { 26 t.Skip("TODO: BuildKit") 27 skip.If(t, testEnv.DaemonInfo.OSType == "windows") 28 29 ctx := testutil.StartSpan(baseContext, t) 30 31 client := testEnv.APIClient() 32 33 dockerfile := ` 34 FROM busybox 35 COPY file / 36 RUN cat /file 37 ` 38 39 fctx := fakecontext.New(t, "", 40 fakecontext.WithFile("file", "some content"), 41 ) 42 defer fctx.Close() 43 44 out := testBuildWithSession(ctx, t, client, client.DaemonHost(), fctx.Dir, dockerfile) 45 assert.Check(t, is.Contains(out, "some content")) 46 47 fctx.Add("second", "contentcontent") 48 49 dockerfile += ` 50 COPY second / 51 RUN cat /second 52 ` 53 54 out = testBuildWithSession(ctx, t, client, client.DaemonHost(), fctx.Dir, dockerfile) 55 assert.Check(t, is.Equal(strings.Count(out, "Using cache"), 2)) 56 assert.Check(t, is.Contains(out, "contentcontent")) 57 58 du, err := client.DiskUsage(ctx, types.DiskUsageOptions{}) 59 assert.Check(t, err) 60 assert.Check(t, du.BuilderSize > 10) 61 62 out = testBuildWithSession(ctx, t, client, client.DaemonHost(), fctx.Dir, dockerfile) 63 assert.Check(t, is.Equal(strings.Count(out, "Using cache"), 4)) 64 65 du2, err := client.DiskUsage(ctx, types.DiskUsageOptions{}) 66 assert.Check(t, err) 67 assert.Check(t, is.Equal(du.BuilderSize, du2.BuilderSize)) 68 69 // rebuild with regular tar, confirm cache still applies 70 fctx.Add("Dockerfile", dockerfile) 71 // FIXME(vdemeester) use sock here 72 res, body, err := request.Do(ctx, 73 "/build", 74 request.Host(client.DaemonHost()), 75 request.Method(http.MethodPost), 76 request.RawContent(fctx.AsTarReader(t)), 77 request.ContentType("application/x-tar")) 78 assert.NilError(t, err) 79 assert.Check(t, is.DeepEqual(http.StatusOK, res.StatusCode)) 80 81 outBytes, err := request.ReadBody(body) 82 assert.NilError(t, err) 83 assert.Check(t, is.Contains(string(outBytes), "Successfully built")) 84 assert.Check(t, is.Equal(strings.Count(string(outBytes), "Using cache"), 4)) 85 86 _, err = client.BuildCachePrune(ctx, types.BuildCachePruneOptions{All: true}) 87 assert.Check(t, err) 88 89 du, err = client.DiskUsage(ctx, types.DiskUsageOptions{}) 90 assert.Check(t, err) 91 assert.Check(t, is.Equal(du.BuilderSize, int64(0))) 92 } 93 94 //nolint:unused // false positive: linter detects this as "unused" 95 func testBuildWithSession(ctx context.Context, t *testing.T, client dclient.APIClient, daemonHost string, dir, dockerfile string) (outStr string) { 96 sess, err := session.NewSession(ctx, "foo1", "foo") 97 assert.Check(t, err) 98 99 fs, err := fsutil.NewFS(dir) 100 assert.NilError(t, err) 101 102 fsProvider := filesync.NewFSSyncProvider(filesync.StaticDirSource{ 103 "": fs, 104 }) 105 sess.Allow(fsProvider) 106 107 g, ctx := errgroup.WithContext(ctx) 108 109 g.Go(func() error { 110 return sess.Run(ctx, func(ctx context.Context, proto string, meta map[string][]string) (net.Conn, error) { 111 return client.DialHijack(ctx, "/session", "h2c", meta) 112 }) 113 }) 114 115 g.Go(func() error { 116 // FIXME use sock here 117 res, body, err := request.Do(ctx, 118 "/build?remote=client-session&session="+sess.ID(), 119 request.Host(daemonHost), 120 request.Method(http.MethodPost), 121 request.With(func(req *http.Request) error { 122 req.Body = io.NopCloser(strings.NewReader(dockerfile)) 123 return nil 124 }), 125 ) 126 if err != nil { 127 return err 128 } 129 assert.Check(t, is.DeepEqual(res.StatusCode, http.StatusOK)) 130 out, err := request.ReadBody(body) 131 assert.NilError(t, err) 132 assert.Check(t, is.Contains(string(out), "Successfully built")) 133 sess.Close() 134 outStr = string(out) 135 return nil 136 }) 137 138 err = g.Wait() 139 assert.Check(t, err) 140 return 141 }