github.com/distbuild/reclient@v0.0.0-20240401075343-3de72e395564/internal/pkg/inputprocessor/action/nacl/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 nacl 16 17 import ( 18 "context" 19 "os" 20 "regexp" 21 "testing" 22 23 spb "github.com/bazelbuild/reclient/api/scandeps" 24 "github.com/bazelbuild/reclient/internal/pkg/inputprocessor" 25 "github.com/bazelbuild/reclient/internal/pkg/inputprocessor/action/cppcompile" 26 ) 27 28 func TestComputeSpec(t *testing.T) { 29 tests := []struct { 30 name string 31 execPath string 32 extraArgs []string 33 wantFlagRegex string 34 wantErr bool 35 }{ 36 { 37 name: "nacl toolchain x86_64", 38 execPath: "fake/native_client/toolchain/mac_x86/x86_64-nacl-clang", 39 wantFlagRegex: "--target=x86_64-nacl", 40 }, 41 { 42 name: "nacl toolchain mipsel", 43 execPath: "native_client/toolchain/foo/bar/fake_os/mipsel-nacl-clang", 44 wantFlagRegex: "--target=mipsel-nacl", 45 }, 46 { 47 name: "nacl toolchain pnacl", 48 execPath: "native_client/toolchain/pnacl-clang", 49 extraArgs: []string{"-pnacl=foo", "--pnacl=bar"}, 50 wantFlagRegex: "--target=i686-nacl", 51 }, 52 { 53 name: "nacl toolchain pnacl, already has target", 54 execPath: "native_client/toolchain/pnacl", 55 extraArgs: []string{"-target", "i686-nacl"}, 56 wantFlagRegex: "-target", 57 }, 58 { 59 name: "no nacl toolchain, failure", 60 execPath: "clang", 61 wantErr: true, 62 }, 63 } 64 65 for _, tc := range tests { 66 t.Run(tc.name, func(t *testing.T) { 67 ctx := context.Background() 68 s := &stubCPPDepScanner{ 69 res: []string{"foo.h"}, 70 err: nil, 71 } 72 cc := &cppcompile.Preprocessor{ 73 CPPDepScanner: s, 74 BasePreprocessor: &inputprocessor.BasePreprocessor{Ctx: ctx}, 75 } 76 c := &Preprocessor{cc} 77 78 pwd, err := os.Getwd() 79 if err != nil { 80 t.Fatalf("Unable to get current working directory: %v", err) 81 } 82 cc.Options = inputprocessor.Options{ 83 ExecRoot: pwd, 84 Cmd: []string{tc.execPath, "-o", "foo.o", "foo.cpp"}, 85 } 86 cc.Options.Cmd = append(cc.Options.Cmd, tc.extraArgs...) 87 88 err = c.ParseFlags() 89 if !tc.wantErr && err != nil { 90 t.Fatalf("ParseFlags() failed: %v", err) 91 } 92 err = c.ComputeSpec() 93 if !tc.wantErr && err != nil { 94 t.Fatalf("ComputeSpec() failed: %v", err) 95 } else if tc.wantErr && err == nil { 96 t.Fatalf("ComputeSpec() did not fail: %v", err) 97 } 98 if containsRegexCount(s.gotCmd, "-pnacl") > 0 { 99 t.Errorf("ComputeSpec() must remove '-pnacl' flag when calling clang-scan-deps for nacl toolchain: %v", s.gotCmd) 100 } 101 if tc.wantFlagRegex != "" && containsRegexCount(s.gotCmd, tc.wantFlagRegex) != 1 { 102 t.Errorf("ComputeSpec() must append %s when calling clang-scan-deps for nacl toolchains: %v", tc.wantFlagRegex, s.gotCmd) 103 } else if tc.wantFlagRegex == "" && containsRegexCount(s.gotCmd, "-target") > 0 { 104 t.Errorf("ComputeSpec() must _not_ append %s when calling clang-scan-deps for non nacl toolchains: %v", tc.wantFlagRegex, s.gotCmd) 105 } 106 }) 107 } 108 } 109 110 type stubCPPDepScanner struct { 111 gotCmd []string 112 gotFileName string 113 gotDirectory string 114 115 res []string 116 err error 117 } 118 119 func (s *stubCPPDepScanner) ProcessInputs(_ context.Context, _ string, command []string, filename, directory string, _ []string) ([]string, bool, error) { 120 s.gotCmd = command 121 s.gotFileName = filename 122 s.gotDirectory = directory 123 124 return s.res, false, s.err 125 } 126 127 func (s *stubCPPDepScanner) Capabilities() *spb.CapabilitiesResponse { 128 return nil 129 } 130 131 func containsRegexCount(src []string, pattern string) int { 132 total := 0 133 for _, v := range src { 134 if ok, err := regexp.Match(pattern, []byte(v)); err == nil && ok { 135 total = total + 1 136 } 137 } 138 return total 139 }