From d2d8e477d94715424dede0252e5fc850fe7315fd Mon Sep 17 00:00:00 2001 From: Laurent Goderre Date: Thu, 28 Nov 2024 17:11:32 -0500 Subject: [PATCH] wip --- cmd/buildctl/build_test.go | 172 +++++++++++++++++++++++++------------ 1 file changed, 115 insertions(+), 57 deletions(-) diff --git a/cmd/buildctl/build_test.go b/cmd/buildctl/build_test.go index d85ceb688a01..be8ba7013345 100644 --- a/cmd/buildctl/build_test.go +++ b/cmd/buildctl/build_test.go @@ -114,70 +114,128 @@ func testBuildContainerdExporter(t *testing.T, sb integration.Sandbox) { func testBuildMetadataFile(t *testing.T, sb integration.Sandbox) { integration.SkipOnPlatform(t, "windows") - st := llb.Image("busybox"). - Run(llb.Shlex("sh -c 'echo -n bar > /foo'")) - - rdr, err := marshal(sb.Context(), st.Root()) - require.NoError(t, err) tmpDir := t.TempDir() imageName := "example.com/moby/metadata:test" metadataFile := filepath.Join(tmpDir, "metadata.json") - - buildCmd := []string{ - "build", "--progress=plain", - "--output type=image,name=" + imageName + ",push=false", - "--metadata-file", metadataFile, + output := filepath.Join(tmpDir, "output.tar") + + cases := []struct { + name string + buildCmd []string + // TODO: Add descriptors counts + }{ + { + name: "single architecture", + buildCmd: []string{ + "build", + "--progress=plain", + "--output type=image,name=" + imageName + ",push=false", + }, + }, + { + name: "multiple architecture", + buildCmd: []string{ + "build", + "--progress=plain", + "--output type=oci,name=" + imageName + ",dest=" + output, + "--opt", "platform=linux/amd64,linux/arm64v8", + }, + }, + { + name: "single architecture attestation", + buildCmd: []string{ + "build", + "--progress=plain", + "--output type=oci,name=" + imageName + ",dest=" + output, + "--opt", "attest:provenance=mode=max", + }, + }, + { + name: "multi architecture attestations", + buildCmd: []string{ + "build", + "--progress=plain", + "--output type=oci,name=" + imageName + ",dest=" + output, + "--opt", "platform=linux/amd64,linux/arm64v8", + "--opt", "attest:provenance=mode=max", + }, + }, } - cmd := sb.Cmd(strings.Join(buildCmd, " ")) - cmd.Stdin = rdr - err = cmd.Run() - require.NoError(t, err) - - require.FileExists(t, metadataFile) - metadataBytes, err := os.ReadFile(metadataFile) - require.NoError(t, err) - - var metadata map[string]json.RawMessage - err = json.Unmarshal(metadataBytes, &metadata) - require.NoError(t, err) - - require.Contains(t, metadata, "image.name") - require.Equal(t, imageName, metadata["image.name"]) - - require.Contains(t, metadata, exptypes.ExporterImageDigestKey) - digest := metadata[exptypes.ExporterImageDigestKey] - require.NotEmpty(t, digest) - - require.Contains(t, metadata, exptypes.ExporterImageDescriptorKey) - var desc *ocispecs.Descriptor - err = json.Unmarshal(metadata[exptypes.ExporterImageDescriptorKey], &desc) - require.NoError(t, err) - require.NotEmpty(t, desc.MediaType) - require.NotEmpty(t, desc.Digest.String()) - - require.Contains(t, metadata, exptypes.ExporterImageDescriptorsKey) - var descList []*ocispecs.Descriptor - require.NoError(t, err) - err = json.Unmarshal(metadata[exptypes.ExporterImageDescriptorsKey], &descList) - require.NoError(t, err) - - cdAddress := sb.ContainerdAddress() - if cdAddress == "" { - t.Log("no containerd worker, skipping digest verification") - } else { - client, err := containerd.New(cdAddress, containerd.WithTimeout(60*time.Second)) - require.NoError(t, err) - defer client.Close() - - ctx := namespaces.WithNamespace(context.Background(), "buildkit") - - img, err := client.GetImage(ctx, imageName) - require.NoError(t, err) - - require.Equal(t, img.Metadata().Target.Digest.String(), digest) + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + st := llb.Image("busybox"). + Run(llb.Shlex("sh -c 'echo -n bar > /foo'")) + + rdr, err := marshal(sb.Context(), st.Root()) + require.NoError(t, err) + + buildCmd := append( + tt.buildCmd, + "--metadata-file", metadataFile, + ) + cmd := sb.Cmd(strings.Join(buildCmd, " ")) + cmd.Stdin = rdr + err = cmd.Run() + require.NoError(t, err) + + require.FileExists(t, metadataFile) + metadataBytes, err := os.ReadFile(metadataFile) + require.NoError(t, err) + + var metadata map[string]json.RawMessage + err = json.Unmarshal(metadataBytes, &metadata) + require.NoError(t, err) + + require.Contains(t, metadata, "image.name") + var name string + err = json.Unmarshal(metadata["image.name"], &name) + require.NoError(t, err) + require.Equal(t, imageName, string(name)) + + var digest string + require.Contains(t, metadata, exptypes.ExporterImageDigestKey) + err = json.Unmarshal(metadata[exptypes.ExporterImageDigestKey], &digest) + require.NoError(t, err) + require.NotEmpty(t, digest) + + require.Contains(t, metadata, exptypes.ExporterImageDescriptorKey) + var desc *ocispecs.Descriptor + err = json.Unmarshal(metadata[exptypes.ExporterImageDescriptorKey], &desc) + require.NoError(t, err) + require.NotEmpty(t, desc.MediaType) + require.NotEmpty(t, desc.Digest.String()) + + require.Contains(t, metadata, exptypes.ExporterImageDescriptorsKey) + var descList []*ocispecs.Descriptor + require.NoError(t, err) + err = json.Unmarshal(metadata[exptypes.ExporterImageDescriptorsKey], &descList) + require.NoError(t, err) + for _, desc := range descList { + require.NotEmpty(t, desc.MediaType) + require.NotEmpty(t, desc.Digest.String()) + } + + if tt.name == "single architecture" { + cdAddress := sb.ContainerdAddress() + if cdAddress == "" { + t.Log("no containerd worker, skipping digest verification") + } else { + client, err := containerd.New(cdAddress, containerd.WithTimeout(60*time.Second)) + require.NoError(t, err) + defer client.Close() + + ctx := namespaces.WithNamespace(context.Background(), "buildkit") + + img, err := client.GetImage(ctx, imageName) + require.NoError(t, err) + + require.Equal(t, img.Metadata().Target.Digest.String(), digest) + } + } + }) } }