github.com/distbuild/reclient@v0.0.0-20240401075343-3de72e395564/internal/pkg/inputprocessor/action/javac/preprocessor_test.go (about) 1 // Copyright 2023 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package javac 16 17 import ( 18 "context" 19 "path/filepath" 20 "testing" 21 22 "github.com/bazelbuild/reclient/internal/pkg/execroot" 23 "github.com/bazelbuild/reclient/internal/pkg/inputprocessor" 24 25 "github.com/bazelbuild/remote-apis-sdks/go/pkg/command" 26 "github.com/google/go-cmp/cmp" 27 "github.com/google/go-cmp/cmp/cmpopts" 28 ) 29 30 var ( 31 strSliceCmp = cmpopts.SortSlices(func(a, b string) bool { return a < b }) 32 ) 33 34 func TestJavacPreprocessor(t *testing.T) { 35 er, cleanup := execroot.Setup(t, []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "lib", "javac"}) 36 defer cleanup() 37 execroot.AddFileWithContent(t, filepath.Join(er, "test.rsp"), []byte("h i\nj")) 38 execroot.AddFileWithContent(t, filepath.Join(er, "javac_remote_toolchain_inputs"), []byte("lib")) 39 cmd := []string{"javac", "-J-Xmx2048M", "-bootclasspath", "a:b:c", "-classpath", "d:e:f", "-processorpath", "g", "--system=j", "-Aroom.schemaLocation=k", "-d", "out1/", "-s", "out2/", "@test.rsp"} 40 ctx := context.Background() 41 pp := &Preprocessor{ 42 &inputprocessor.BasePreprocessor{ 43 Ctx: ctx, 44 }, 45 } 46 gotSpec, err := inputprocessor.Compute(pp, inputprocessor.Options{ 47 ExecRoot: er, 48 ToolchainInputs: []string{"javac"}, 49 Cmd: cmd, 50 }) 51 if err != nil { 52 t.Errorf("Compute() returned error: %v", err) 53 } 54 wantSpec := &inputprocessor.ActionSpec{ 55 InputSpec: &command.InputSpec{ 56 Inputs: []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "test.rsp", "lib", "javac"}, 57 EnvironmentVariables: map[string]string{ 58 "PATH": ".:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 59 }, 60 }, 61 OutputDirectories: []string{"out1", "out2"}, 62 } 63 if diff := cmp.Diff(wantSpec, gotSpec, strSliceCmp); diff != "" { 64 t.Errorf("GetActionSpec() returned diff in ActionSpec, (-want +got): %s", diff) 65 } 66 } 67 68 func TestJavacArgumentFilesPreprocessor(t *testing.T) { 69 er, cleanup := execroot.Setup(t, []string{"MyClass1.java", "MyClass2.java", "MyClass3.java", "MyClass4.java", "MyClass5.java", "MyClass6.java", "a", "b", "c", "d", "e", "f", "g", "j", "k", "lib", "javac"}) 70 defer cleanup() 71 // See Example here: https://docs.oracle.com/en/java/javase/17/docs/specs/man/javac.html#examples-of-using-javac-filename 72 // 1) Use of the @<filename> to recursively interpret files is not supported. 73 // 2) The arguments within a file can be separated by spaces or new line characters. 74 // TODO(b/324585908): Support flag value with embedded spaces enclosed by double quotation marks. 75 // 3) If a file name contains embedded spaces, then put the whole file name in double quotation marks. 76 execroot.AddFileWithContent(t, filepath.Join(er, "options"), []byte("-bootclasspath a:b:c\n-classpath d:e:f\n-processorpath g\n--system=j\n-Aroom.schemaLocation=k\n-d out1/\n-s out2/")) 77 execroot.AddFileWithContent(t, filepath.Join(er, "foo/bar/baz/classes"), []byte("MyClass1.java\nMyClass2.java\nMyClass3.java")) 78 execroot.AddFileWithContent(t, filepath.Join(er, "classes_seperated_by_space"), []byte("MyClass4.java MyClass5.java\n\"MyClass6.java\"")) 79 execroot.AddFileWithContent(t, filepath.Join(er, "javac_remote_toolchain_inputs"), []byte("lib")) 80 cmd := []string{"javac", "@options", "@foo/bar/baz/classes", "@classes_seperated_by_space"} 81 ctx := context.Background() 82 pp := &Preprocessor{ 83 &inputprocessor.BasePreprocessor{ 84 Ctx: ctx, 85 }, 86 } 87 gotSpec, err := inputprocessor.Compute(pp, inputprocessor.Options{ 88 ExecRoot: er, 89 ToolchainInputs: []string{"javac"}, 90 Cmd: cmd, 91 }) 92 if err != nil { 93 t.Errorf("Compute() returned error: %v", err) 94 } 95 wantSpec := &inputprocessor.ActionSpec{ 96 InputSpec: &command.InputSpec{ 97 Inputs: []string{ 98 "options", 99 filepath.Join("foo", "bar", "baz", "classes"), 100 "MyClass1.java", 101 "MyClass2.java", 102 "MyClass3.java", 103 "classes_seperated_by_space", 104 "MyClass4.java", 105 "MyClass5.java", 106 "MyClass6.java", 107 "a", "b", "c", "d", "e", "f", "g", "j", "k", 108 "lib", 109 "javac"}, 110 EnvironmentVariables: map[string]string{ 111 "PATH": ".:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 112 }, 113 }, 114 OutputDirectories: []string{"out1", "out2"}, 115 } 116 if diff := cmp.Diff(wantSpec, gotSpec, strSliceCmp); diff != "" { 117 t.Errorf("GetActionSpec() returned diff in ActionSpec, (-want +got): %s", diff) 118 } 119 }