package depot import ( "os" "path/filepath" "testing" ) func TestValidSHA(t *testing.T) { tests := []struct { input string want bool }{ {"0b1d1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab", true}, {"0000000000000000000000000000000000000000000000000000000000000000", true}, {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", true}, {"0b1d1234567890ABCDEF1234567890abcdef1234567890abcdef1234567890ab", false}, // uppercase {"0b1d1234567890abcde", false}, // too short {"0b1d1234567890abcdef1234567890abcdef1234567890abcdef1234567890abff", false}, // too long {"0b1d1234567890abcdef1234567890abcdef1234567890abcdef1234567890ag", false}, // invalid hex {"", false}, } for _, tc := range tests { got := ValidSHA(tc.input) if got != tc.want { t.Errorf("ValidSHA(%q): got %v, want %v", tc.input, got, tc.want) } } } func TestBlobKey(t *testing.T) { tests := []struct { sha string want string }{ {"0b1d1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab", "sha256/0b/1d/0b1d1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab"}, {"abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789", "sha256/ab/cd/abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"}, } for _, tc := range tests { got := BlobKey(tc.sha) if got != tc.want { t.Errorf("BlobKey(%q): got %q, want %q", tc.sha, got, tc.want) } } } func TestReferencedSHAs(t *testing.T) { // Test: temp dir with two yml files sharing one sha → dedup tmpdir := t.TempDir() // First manifest with sha1 and sha2 manifest1 := `assets: - path: file1.txt sha256: 0b1d1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab size: 100 - path: file2.txt sha256: abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789 size: 200 ` if err := os.WriteFile(filepath.Join(tmpdir, "manifest1.yml"), []byte(manifest1), 0644); err != nil { t.Fatalf("write manifest1: %v", err) } // Second manifest with sha2 and sha3 manifest2 := `assets: - path: file3.txt sha256: abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789 size: 300 - path: file4.txt sha256: fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210 size: 400 ` if err := os.WriteFile(filepath.Join(tmpdir, "manifest2.yml"), []byte(manifest2), 0644); err != nil { t.Fatalf("write manifest2: %v", err) } result, err := ReferencedSHAs(tmpdir) if err != nil { t.Fatalf("ReferencedSHAs: %v", err) } // Should have 3 unique SHAs if len(result) != 3 { t.Errorf("ReferencedSHAs: got %d unique SHAs, want 3", len(result)) } expectedSizes := map[string]int64{ "0b1d1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab": 100, "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789": 300, // Largest size for duplicated sha "fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210": 400, } for sha, expectedSize := range expectedSizes { size, exists := result[sha] if !exists { t.Errorf("ReferencedSHAs: sha %q missing", sha) } if size != expectedSize { t.Errorf("ReferencedSHAs: sha %q size: got %d, want %d", sha, size, expectedSize) } } // Test: bad sha → error naming the file badManifest := `assets: - path: file5.txt sha256: not_a_valid_sha size: 500 ` if err := os.WriteFile(filepath.Join(tmpdir, "badsha.yml"), []byte(badManifest), 0644); err != nil { t.Fatalf("write badsha: %v", err) } _, err = ReferencedSHAs(tmpdir) if err == nil { t.Errorf("ReferencedSHAs with bad sha: got nil error, want error naming file") } if err != nil && err.Error() != "badsha.yml: invalid sha256 hash" { t.Errorf("ReferencedSHAs error message: got %q, should mention badsha.yml", err.Error()) } } func TestReferencedSHAsEmpty(t *testing.T) { // Test: empty dir → error tmpdir := t.TempDir() _, err := ReferencedSHAs(tmpdir) if err == nil { t.Errorf("ReferencedSHAs on empty dir: got nil error, want error") } }