Files

144 lines
4.8 KiB
Go

package handlers
import (
"testing"
"atcr.io/pkg/appview/db"
"atcr.io/pkg/appview/holdclient"
)
func TestBuildLayerDetails_NoHistory(t *testing.T) {
dbLayers := []db.Layer{
{Digest: "sha256:aaa", Size: 1024, MediaType: "application/vnd.oci.image.layer.v1.tar+gzip", LayerIndex: 0},
{Digest: "sha256:bbb", Size: 2048, MediaType: "application/vnd.oci.image.layer.v1.tar+gzip", LayerIndex: 1},
}
details := buildLayerDetails(nil, dbLayers)
if len(details) != 2 {
t.Fatalf("Expected 2 layer details, got %d", len(details))
}
if details[0].Command != "" {
t.Errorf("Expected empty command, got %q", details[0].Command)
}
if details[0].Digest != "sha256:aaa" {
t.Errorf("Expected digest sha256:aaa, got %q", details[0].Digest)
}
if details[0].Index != 1 {
t.Errorf("Expected Index 1, got %d", details[0].Index)
}
}
func TestBuildLayerDetails_WithHistory(t *testing.T) {
history := []holdclient.OCIHistoryEntry{
{CreatedBy: "ENV PATH=/usr/local/bin", EmptyLayer: true},
{CreatedBy: "RUN apt-get install curl", EmptyLayer: false},
{CreatedBy: "COPY . /app", EmptyLayer: false},
}
dbLayers := []db.Layer{
{Digest: "sha256:aaa", Size: 1024, MediaType: "application/vnd.oci.image.layer.v1.tar+gzip", LayerIndex: 0},
{Digest: "sha256:bbb", Size: 2048, MediaType: "application/vnd.oci.image.layer.v1.tar+gzip", LayerIndex: 1},
}
details := buildLayerDetails(history, dbLayers)
if len(details) != 3 {
t.Fatalf("Expected 3 details (1 empty + 2 real), got %d", len(details))
}
// First entry is empty layer (ENV)
if !details[0].EmptyLayer {
t.Error("Expected first detail to be empty layer")
}
if details[0].Command != "ENV PATH=/usr/local/bin" {
t.Errorf("Expected ENV command, got %q", details[0].Command)
}
if details[0].Digest != "" {
t.Errorf("Expected empty digest for empty layer, got %q", details[0].Digest)
}
// Second entry is real layer with digest
if details[1].EmptyLayer {
t.Error("Expected second detail to not be empty layer")
}
if details[1].Digest != "sha256:aaa" {
t.Errorf("Expected digest sha256:aaa, got %q", details[1].Digest)
}
if details[1].Command != "RUN apt-get install curl" {
t.Errorf("Expected RUN command, got %q", details[1].Command)
}
// Third entry is real layer
if details[2].Digest != "sha256:bbb" {
t.Errorf("Expected digest sha256:bbb, got %q", details[2].Digest)
}
if details[2].Command != "COPY . /app" {
t.Errorf("Expected COPY command, got %q", details[2].Command)
}
}
func TestBuildLayerDetails_DistrolessWithUserLayers(t *testing.T) {
// Simulates distroless base (many empty layers) + user COPY layers
history := []holdclient.OCIHistoryEntry{
{CreatedBy: "bazel build ...", EmptyLayer: false}, // distroless base layer
{CreatedBy: "LABEL maintainer=distroless", EmptyLayer: true}, // metadata
{CreatedBy: "ENV SSL_CERT_DIR=/etc/ssl/certs", EmptyLayer: true},
{CreatedBy: "COPY /app /app # buildkit", EmptyLayer: false}, // user layer
}
dbLayers := []db.Layer{
{Digest: "sha256:base", Size: 5000000, MediaType: "application/vnd.oci.image.layer.v1.tar+gzip", LayerIndex: 0},
{Digest: "sha256:user", Size: 1024, MediaType: "application/vnd.oci.image.layer.v1.tar+gzip", LayerIndex: 1},
}
details := buildLayerDetails(history, dbLayers)
if len(details) != 4 {
t.Fatalf("Expected 4 details (2 real + 2 empty), got %d", len(details))
}
// Real layer
if details[0].EmptyLayer || details[0].Digest != "sha256:base" {
t.Errorf("Layer 0: expected real layer with sha256:base, got empty=%v digest=%q", details[0].EmptyLayer, details[0].Digest)
}
// Empty layers
if !details[1].EmptyLayer || details[1].Command != "LABEL maintainer=distroless" {
t.Errorf("Layer 1: expected empty LABEL layer")
}
if !details[2].EmptyLayer || details[2].Command != "ENV SSL_CERT_DIR=/etc/ssl/certs" {
t.Errorf("Layer 2: expected empty ENV layer")
}
// User layer
if details[3].EmptyLayer || details[3].Digest != "sha256:user" {
t.Errorf("Layer 3: expected real layer with sha256:user, got empty=%v digest=%q", details[3].EmptyLayer, details[3].Digest)
}
if details[3].Command != "COPY /app /app # buildkit" {
t.Errorf("Layer 3: Command = %q, want COPY command", details[3].Command)
}
}
func TestBuildLayerDetails_AllEmptyLayers(t *testing.T) {
// Edge case: all history entries are empty layers (scratch-based with only metadata)
history := []holdclient.OCIHistoryEntry{
{CreatedBy: "ENV FOO=bar", EmptyLayer: true},
{CreatedBy: "LABEL version=1.0", EmptyLayer: true},
}
details := buildLayerDetails(history, nil)
if len(details) != 2 {
t.Fatalf("Expected 2 details, got %d", len(details))
}
for i, d := range details {
if !d.EmptyLayer {
t.Errorf("Layer %d: expected empty layer", i)
}
if d.Digest != "" {
t.Errorf("Layer %d: expected empty digest, got %q", i, d.Digest)
}
}
}