@@ -19,12 +19,15 @@ import (
1919 "runtime"
2020 "slices"
2121 "strings"
22+ "sync/atomic"
2223 "testing"
2324 "time"
2425
2526 cacheimporttypes "github.com/moby/buildkit/cache/remotecache/v1/types"
2627 "github.com/tonistiigi/fsutil"
2728 "golang.org/x/sync/errgroup"
29+ "google.golang.org/grpc"
30+ grpcgzip "google.golang.org/grpc/encoding/gzip"
2831 "google.golang.org/grpc/status"
2932 "google.golang.org/protobuf/proto"
3033 "google.golang.org/protobuf/types/known/anypb"
@@ -44,6 +47,7 @@ import (
4447 "github.com/moby/buildkit/frontend/dockerfile/builder"
4548 "github.com/moby/buildkit/frontend/dockerui"
4649 gateway "github.com/moby/buildkit/frontend/gateway/client"
50+ gatewayapi "github.com/moby/buildkit/frontend/gateway/pb"
4751 "github.com/moby/buildkit/frontend/subrequests"
4852 "github.com/moby/buildkit/identity"
4953 "github.com/moby/buildkit/session"
@@ -141,6 +145,7 @@ var allTests = integration.TestFuncs(
141145 testFrontendUseForwardedSolveResults ,
142146 testFrontendEvaluate ,
143147 testFrontendInputs ,
148+ testFrontendInputsCompressed ,
144149 testErrorsSourceMap ,
145150 testMultiArgs ,
146151 testFrontendSubrequests ,
@@ -7340,6 +7345,72 @@ COPY foo foo2
73407345 require .Equal (t , expected , actual )
73417346}
73427347
7348+ type inputsCompressionInterceptor struct {
7349+ calls atomic.Int64
7350+ compressed atomic.Bool
7351+ }
7352+
7353+ func (i * inputsCompressionInterceptor ) unary (ctx context.Context , method string , req any , reply any , cc * grpc.ClientConn , invoker grpc.UnaryInvoker , opts ... grpc.CallOption ) error {
7354+ if method == gatewayapi .LLBBridge_Inputs_FullMethodName {
7355+ i .calls .Add (1 )
7356+ for _ , opt := range opts {
7357+ if compressor , ok := opt .(grpc.CompressorCallOption ); ok && compressor .CompressorType == grpcgzip .Name {
7358+ i .compressed .Store (true )
7359+ }
7360+ }
7361+ }
7362+ return invoker (ctx , method , req , reply , cc , opts ... )
7363+ }
7364+
7365+ func testFrontendInputsCompressed (t * testing.T , sb integration.Sandbox ) {
7366+ integration .SkipOnPlatform (t , "windows" )
7367+ f := getFrontend (t , sb )
7368+ if _ , ok := f .(* clientFrontend ); ! ok {
7369+ t .Skip ("only test with client frontend" )
7370+ }
7371+
7372+ inputsInterceptor := & inputsCompressionInterceptor {}
7373+ c , err := client .New (sb .Context (), sb .Address (), client .WithGRPCDialOption (grpc .WithChainUnaryInterceptor (inputsInterceptor .unary )))
7374+ require .NoError (t , err )
7375+ defer c .Close ()
7376+
7377+ payload := bytes .Repeat ([]byte ("a" ), 64 << 10 )
7378+ input := llb .Scratch ().File (llb .Mkfile ("/payload" , 0600 , payload ))
7379+
7380+ destDir := t .TempDir ()
7381+ dockerfile := []byte (`
7382+ FROM scratch
7383+ COPY payload payload
7384+ ` )
7385+ dir := integration .Tmpdir (
7386+ t ,
7387+ fstest .CreateFile ("Dockerfile" , dockerfile , 0600 ),
7388+ )
7389+
7390+ _ , err = f .Solve (sb .Context (), c , client.SolveOpt {
7391+ Exports : []client.ExportEntry {
7392+ {
7393+ Type : client .ExporterLocal ,
7394+ OutputDir : destDir ,
7395+ },
7396+ },
7397+ LocalMounts : map [string ]fsutil.FS {
7398+ dockerui .DefaultLocalNameDockerfile : dir ,
7399+ },
7400+ FrontendInputs : map [string ]llb.State {
7401+ dockerui .DefaultLocalNameContext : input ,
7402+ },
7403+ }, nil )
7404+ require .NoError (t , err )
7405+
7406+ actual , err := os .ReadFile (filepath .Join (destDir , "payload" ))
7407+ require .NoError (t , err )
7408+ require .Equal (t , payload , actual )
7409+
7410+ require .NotZero (t , inputsInterceptor .calls .Load (), "expected an Inputs request" )
7411+ require .True (t , inputsInterceptor .compressed .Load (), "expected Inputs request to use gzip compression" )
7412+ }
7413+
73437414func testFrontendSubrequests (t * testing.T , sb integration.Sandbox ) {
73447415 f := getFrontend (t , sb )
73457416 if _ , ok := f .(* clientFrontend ); ! ok {
0 commit comments