Skip to content

Commit 252ae63

Browse files
authored
Merge pull request #3734 from tonistiigi/v0.11.5-picks
[0.11] cherry picks for v0.11.5
2 parents a0f2992 + 103bf22 commit 252ae63

File tree

9 files changed

+299
-81
lines changed

9 files changed

+299
-81
lines changed

client/build_test.go

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ func TestClientGatewayIntegration(t *testing.T) {
4545
testClientGatewayContainerPID1Exit,
4646
testClientGatewayContainerMounts,
4747
testClientGatewayContainerPID1Tty,
48+
testClientGatewayContainerCancelPID1Tty,
4849
testClientGatewayContainerExecTty,
50+
testClientGatewayContainerCancelExecTty,
4951
testClientSlowCacheRootfsRef,
5052
testClientGatewayContainerPlatformPATH,
5153
testClientGatewayExecError,
@@ -923,6 +925,77 @@ func testClientGatewayContainerPID1Tty(t *testing.T, sb integration.Sandbox) {
923925
checkAllReleasable(t, c, sb, true)
924926
}
925927

928+
// testClientGatewayContainerCancelPID1Tty is testing that the tty will cleanly
929+
// shutdown on context cancel
930+
func testClientGatewayContainerCancelPID1Tty(t *testing.T, sb integration.Sandbox) {
931+
requiresLinux(t)
932+
ctx := sb.Context()
933+
934+
c, err := New(ctx, sb.Address())
935+
require.NoError(t, err)
936+
defer c.Close()
937+
938+
product := "buildkit_test"
939+
940+
inputR, inputW := io.Pipe()
941+
output := bytes.NewBuffer(nil)
942+
943+
b := func(ctx context.Context, c client.Client) (*client.Result, error) {
944+
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
945+
defer cancel()
946+
947+
st := llb.Image("busybox:latest")
948+
949+
def, err := st.Marshal(ctx)
950+
if err != nil {
951+
return nil, errors.Wrap(err, "failed to marshal state")
952+
}
953+
954+
r, err := c.Solve(ctx, client.SolveRequest{
955+
Definition: def.ToPB(),
956+
})
957+
if err != nil {
958+
return nil, errors.Wrap(err, "failed to solve")
959+
}
960+
961+
ctr, err := c.NewContainer(ctx, client.NewContainerRequest{
962+
Mounts: []client.Mount{{
963+
Dest: "/",
964+
MountType: pb.MountType_BIND,
965+
Ref: r.Ref,
966+
}},
967+
})
968+
require.NoError(t, err)
969+
defer ctr.Release(ctx)
970+
971+
prompt := newTestPrompt(ctx, t, inputW, output)
972+
pid1, err := ctr.Start(ctx, client.StartRequest{
973+
Args: []string{"sh"},
974+
Tty: true,
975+
Stdin: inputR,
976+
Stdout: &nopCloser{output},
977+
Stderr: &nopCloser{output},
978+
Env: []string{fmt.Sprintf("PS1=%s", prompt.String())},
979+
})
980+
require.NoError(t, err)
981+
prompt.SendExpect("echo hi", "hi")
982+
cancel()
983+
984+
err = pid1.Wait()
985+
require.ErrorIs(t, err, context.Canceled)
986+
987+
return &client.Result{}, err
988+
}
989+
990+
_, err = c.Build(ctx, SolveOpt{}, product, b, nil)
991+
require.Error(t, err)
992+
993+
inputW.Close()
994+
inputR.Close()
995+
996+
checkAllReleasable(t, c, sb, true)
997+
}
998+
926999
type testPrompt struct {
9271000
ctx context.Context
9281001
t *testing.T
@@ -1071,6 +1144,87 @@ func testClientGatewayContainerExecTty(t *testing.T, sb integration.Sandbox) {
10711144
checkAllReleasable(t, c, sb, true)
10721145
}
10731146

1147+
// testClientGatewayContainerExecTty is testing the tty shuts down cleanly
1148+
// on context.Cancel
1149+
func testClientGatewayContainerCancelExecTty(t *testing.T, sb integration.Sandbox) {
1150+
requiresLinux(t)
1151+
ctx := sb.Context()
1152+
1153+
c, err := New(ctx, sb.Address())
1154+
require.NoError(t, err)
1155+
defer c.Close()
1156+
1157+
product := "buildkit_test"
1158+
1159+
inputR, inputW := io.Pipe()
1160+
output := bytes.NewBuffer(nil)
1161+
b := func(ctx context.Context, c client.Client) (*client.Result, error) {
1162+
ctx, timeout := context.WithTimeout(ctx, 10*time.Second)
1163+
defer timeout()
1164+
st := llb.Image("busybox:latest")
1165+
1166+
def, err := st.Marshal(ctx)
1167+
if err != nil {
1168+
return nil, errors.Wrap(err, "failed to marshal state")
1169+
}
1170+
1171+
r, err := c.Solve(ctx, client.SolveRequest{
1172+
Definition: def.ToPB(),
1173+
})
1174+
if err != nil {
1175+
return nil, errors.Wrap(err, "failed to solve")
1176+
}
1177+
1178+
ctr, err := c.NewContainer(ctx, client.NewContainerRequest{
1179+
Mounts: []client.Mount{{
1180+
Dest: "/",
1181+
MountType: pb.MountType_BIND,
1182+
Ref: r.Ref,
1183+
}},
1184+
})
1185+
require.NoError(t, err)
1186+
1187+
pid1, err := ctr.Start(ctx, client.StartRequest{
1188+
Args: []string{"sleep", "10"},
1189+
})
1190+
require.NoError(t, err)
1191+
1192+
defer pid1.Wait()
1193+
defer ctr.Release(ctx)
1194+
1195+
execCtx, cancel := context.WithCancel(ctx)
1196+
defer cancel()
1197+
1198+
prompt := newTestPrompt(execCtx, t, inputW, output)
1199+
pid2, err := ctr.Start(execCtx, client.StartRequest{
1200+
Args: []string{"sh"},
1201+
Tty: true,
1202+
Stdin: inputR,
1203+
Stdout: &nopCloser{output},
1204+
Stderr: &nopCloser{output},
1205+
Env: []string{fmt.Sprintf("PS1=%s", prompt.String())},
1206+
})
1207+
require.NoError(t, err)
1208+
1209+
prompt.SendExpect("echo hi", "hi")
1210+
cancel()
1211+
1212+
err = pid2.Wait()
1213+
require.ErrorIs(t, err, context.Canceled)
1214+
1215+
return &client.Result{}, err
1216+
}
1217+
1218+
_, err = c.Build(ctx, SolveOpt{}, product, b, nil)
1219+
require.Error(t, err)
1220+
require.Contains(t, err.Error(), context.Canceled.Error())
1221+
1222+
inputW.Close()
1223+
inputR.Close()
1224+
1225+
checkAllReleasable(t, c, sb, true)
1226+
}
1227+
10741228
func testClientSlowCacheRootfsRef(t *testing.T, sb integration.Sandbox) {
10751229
requiresLinux(t)
10761230

client/client_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ func TestIntegration(t *testing.T) {
195195
testMountStubsDirectory,
196196
testMountStubsTimestamp,
197197
testSourcePolicy,
198+
testLLBMountPerformance,
198199
)
199200
}
200201

@@ -8945,3 +8946,31 @@ func testSourcePolicy(t *testing.T, sb integration.Sandbox) {
89458946
require.ErrorContains(t, err, sourcepolicy.ErrSourceDenied.Error())
89468947
})
89478948
}
8949+
8950+
func testLLBMountPerformance(t *testing.T, sb integration.Sandbox) {
8951+
c, err := New(sb.Context(), sb.Address())
8952+
require.NoError(t, err)
8953+
defer c.Close()
8954+
8955+
mntInput := llb.Image("busybox:latest")
8956+
st := llb.Image("busybox:latest")
8957+
var mnts []llb.State
8958+
for i := 0; i < 20; i++ {
8959+
execSt := st.Run(
8960+
llb.Args([]string{"true"}),
8961+
)
8962+
mnts = append(mnts, mntInput)
8963+
for j := range mnts {
8964+
mnts[j] = execSt.AddMount(fmt.Sprintf("/tmp/bin%d", j), mnts[j], llb.SourcePath("/bin"))
8965+
}
8966+
st = execSt.Root()
8967+
}
8968+
8969+
def, err := st.Marshal(sb.Context())
8970+
require.NoError(t, err)
8971+
8972+
timeoutCtx, cancel := context.WithTimeout(sb.Context(), time.Minute)
8973+
defer cancel()
8974+
_, err = c.Solve(timeoutCtx, def, SolveOpt{}, nil)
8975+
require.NoError(t, err)
8976+
}

0 commit comments

Comments
 (0)