@@ -846,3 +846,137 @@ func TestBuild_EnvfileCacheInvalidation(t *testing.T) {
846846 t .Errorf ("expected cache miss on changed envfile, got %d hits" , forge2 .cacheHit ())
847847 }
848848}
849+
850+ func TestForgeConfigArtifactsDir (t * testing.T ) {
851+ config := & ForgeConfig {ArtifactsDir : "/custom/artifacts" , WorkDir : "/work" }
852+ if got := config .ArtifactsDir ; got != "/custom/artifacts" {
853+ t .Errorf ("ArtifactsDir = %q, want %q" , got , "/custom/artifacts" )
854+ }
855+ }
856+
857+ func TestBuild_WithArtifacts_exact (t * testing.T ) {
858+ tmpDir := t .TempDir ()
859+ artifactsDir := filepath .Join (tmpDir , "artifacts" )
860+
861+ config := & ForgeConfig {
862+ WorkDir : "testdata" ,
863+ NamePrefix : "cr.ray.io/rayproject/" ,
864+ ArtifactsDir : artifactsDir ,
865+ }
866+
867+ if err := Build ("testdata/artifact-exact.wanda.yaml" , config ); err != nil {
868+ t .Fatalf ("build: %v" , err )
869+ }
870+
871+ extractedFile := filepath .Join (artifactsDir , "bin/myapp" )
872+ content , err := os .ReadFile (extractedFile )
873+ if err != nil {
874+ t .Fatalf ("read extracted file: %v" , err )
875+ }
876+
877+ want := "binary-content\n "
878+ if got := string (content ); got != want {
879+ t .Errorf ("extracted content = %q, want %q" , got , want )
880+ }
881+ }
882+
883+ func TestBuild_WithArtifacts_optional (t * testing.T ) {
884+ tmpDir := t .TempDir ()
885+ artifactsDir := filepath .Join (tmpDir , "artifacts" )
886+
887+ config := & ForgeConfig {
888+ WorkDir : "testdata" ,
889+ NamePrefix : "cr.ray.io/rayproject/" ,
890+ ArtifactsDir : artifactsDir ,
891+ }
892+
893+ // Build should succeed even though the optional artifact doesn't exist
894+ if err := Build ("testdata/artifact-optional.wanda.yaml" , config ); err != nil {
895+ t .Fatalf ("build: %v" , err )
896+ }
897+
898+ // Required artifact should be extracted
899+ extractedFile := filepath .Join (artifactsDir , "bin/myapp" )
900+ content , err := os .ReadFile (extractedFile )
901+ if err != nil {
902+ t .Fatalf ("read extracted file: %v" , err )
903+ }
904+
905+ want := "binary-content\n "
906+ if got := string (content ); got != want {
907+ t .Errorf ("extracted content = %q, want %q" , got , want )
908+ }
909+
910+ // Optional artifact should not exist (since source doesn't exist)
911+ optionalFile := filepath .Join (artifactsDir , "optional.txt" )
912+ if _ , err := os .Stat (optionalFile ); ! os .IsNotExist (err ) {
913+ t .Errorf ("optional file should not exist, but got err: %v" , err )
914+ }
915+ }
916+
917+ func TestBuild_WithArtifacts_rootOnly (t * testing.T ) {
918+ wandaSpecs := filepath .Join (t .TempDir (), ".wandaspecs" )
919+ absTestdata , err := filepath .Abs ("testdata" )
920+ if err != nil {
921+ t .Fatalf ("abs testdata: %v" , err )
922+ }
923+ if err := os .WriteFile (wandaSpecs , []byte (absTestdata ), 0644 ); err != nil {
924+ t .Fatalf ("write wandaspecs: %v" , err )
925+ }
926+
927+ tmpDir := t .TempDir ()
928+ artifactsDir := filepath .Join (tmpDir , "artifacts" )
929+
930+ config := & ForgeConfig {
931+ WorkDir : "testdata" ,
932+ NamePrefix : "cr.ray.io/rayproject/" ,
933+ WandaSpecsFile : wandaSpecs ,
934+ ArtifactsDir : artifactsDir ,
935+ }
936+
937+ if err := Build ("testdata/artifact-dep-top.wanda.yaml" , config ); err != nil {
938+ t .Fatalf ("build with deps: %v" , err )
939+ }
940+
941+ topFile := filepath .Join (artifactsDir , "top.txt" )
942+ if _ , err := os .Stat (topFile ); os .IsNotExist (err ) {
943+ t .Error ("root spec artifact should have been extracted" )
944+ }
945+
946+ depDocsFile := filepath .Join (artifactsDir , "docs/readme.md" )
947+ if _ , err := os .Stat (depDocsFile ); ! os .IsNotExist (err ) {
948+ t .Error ("dependency artifact should NOT have been extracted" )
949+ }
950+ }
951+
952+ func TestBuild_WithArtifacts_cacheHit (t * testing.T ) {
953+ tmpDir := t .TempDir ()
954+ artifactsDir1 := filepath .Join (tmpDir , "artifacts1" )
955+ artifactsDir2 := filepath .Join (tmpDir , "artifacts2" )
956+
957+ config := & ForgeConfig {
958+ WorkDir : "testdata" ,
959+ NamePrefix : "cr.ray.io/rayproject/" ,
960+ ArtifactsDir : artifactsDir1 ,
961+ }
962+
963+ if err := Build ("testdata/artifact-exact.wanda.yaml" , config ); err != nil {
964+ t .Fatalf ("first build: %v" , err )
965+ }
966+
967+ extractedFile1 := filepath .Join (artifactsDir1 , "bin/myapp" )
968+ if _ , err := os .Stat (extractedFile1 ); os .IsNotExist (err ) {
969+ t .Fatal ("first build should have extracted artifact" )
970+ }
971+
972+ config .ArtifactsDir = artifactsDir2
973+
974+ if err := Build ("testdata/artifact-exact.wanda.yaml" , config ); err != nil {
975+ t .Fatalf ("second build: %v" , err )
976+ }
977+
978+ extractedFile2 := filepath .Join (artifactsDir2 , "bin/myapp" )
979+ if _ , err := os .Stat (extractedFile2 ); os .IsNotExist (err ) {
980+ t .Error ("artifact should be extracted even on cache hit" )
981+ }
982+ }
0 commit comments