blob: 14b33b239665589587ece61fcd186054df36f500 [file] [log] [blame]
Chih-Hung Hsieh104f51f2022-04-20 15:48:41 -07001// Copyright 2022 Google Inc. All rights reserved.
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
15package cc
16
17import (
18 "fmt"
Chih-Hung Hsieh80e3e032022-06-02 19:55:15 -070019 "strings"
Chih-Hung Hsieh104f51f2022-04-20 15:48:41 -070020 "testing"
21
22 "android/soong/android"
23)
24
Chih-Hung Hsieh80e3e032022-06-02 19:55:15 -070025func TestTidyChecks(t *testing.T) {
26 // The "tidy_checks" property defines additional checks appended
27 // to global default. But there are some checks disabled after
28 // the local tidy_checks.
29 bp := `
30 cc_library_shared { // has global checks + extraGlobalChecks
31 name: "libfoo_1",
32 srcs: ["foo.c"],
33 }
34 cc_library_shared { // has only local checks + extraGlobalChecks
35 name: "libfoo_2",
36 srcs: ["foo.c"],
37 tidy_checks: ["-*", "xyz-*"],
38 }
39 cc_library_shared { // has global checks + local checks + extraGlobalChecks
40 name: "libfoo_3",
41 srcs: ["foo.c"],
42 tidy_checks: ["-abc*", "xyz-*", "mycheck"],
43 }
44 cc_library_shared { // has only local checks after "-*" + extraGlobalChecks
45 name: "libfoo_4",
46 srcs: ["foo.c"],
47 tidy_checks: ["-abc*", "xyz-*", "mycheck", "-*", "xyz-*"],
48 }`
49 ctx := testCc(t, bp)
50
51 globalChecks := "-checks=${config.TidyDefaultGlobalChecks},"
52 firstXyzChecks := "-checks='-*','xyz-*',"
53 localXyzChecks := "'-*','xyz-*'"
54 localAbcChecks := "'-abc*','xyz-*',mycheck"
55 extraGlobalChecks := ",-bugprone-easily-swappable-parameters,"
56 testCases := []struct {
57 libNumber int // 1,2,3,...
58 checks []string // must have substrings in -checks
59 noChecks []string // must not have substrings in -checks
60 }{
61 {1, []string{globalChecks, extraGlobalChecks}, []string{localXyzChecks, localAbcChecks}},
62 {2, []string{firstXyzChecks, extraGlobalChecks}, []string{globalChecks, localAbcChecks}},
63 {3, []string{globalChecks, localAbcChecks, extraGlobalChecks}, []string{localXyzChecks}},
64 {4, []string{firstXyzChecks, extraGlobalChecks}, []string{globalChecks, localAbcChecks}},
65 }
66 t.Run("caseTidyChecks", func(t *testing.T) {
67 variant := "android_arm64_armv8-a_shared"
68 for _, test := range testCases {
69 libName := fmt.Sprintf("libfoo_%d", test.libNumber)
70 flags := ctx.ModuleForTests(libName, variant).Rule("clangTidy").Args["tidyFlags"]
71 splitFlags := strings.Split(flags, " ")
72 foundCheckFlag := false
73 for _, flag := range splitFlags {
74 if strings.HasPrefix(flag, "-checks=") {
75 foundCheckFlag = true
76 for _, check := range test.checks {
77 if !strings.Contains(flag, check) {
78 t.Errorf("tidyFlags for %s does not contain %s.", libName, check)
79 }
80 }
81 for _, check := range test.noChecks {
82 if strings.Contains(flag, check) {
83 t.Errorf("tidyFlags for %s should not contain %s.", libName, check)
84 }
85 }
86 break
87 }
88 }
89 if !foundCheckFlag {
90 t.Errorf("tidyFlags for %s does not contain -checks=.", libName)
91 }
92 }
93 })
94}
95
Chih-Hung Hsieh104f51f2022-04-20 15:48:41 -070096func TestWithTidy(t *testing.T) {
97 // When WITH_TIDY=1 or (ALLOW_LOCAL_TIDY_TRUE=1 and local tidy:true)
98 // a C++ library should depend on .tidy files.
99 testCases := []struct {
100 withTidy, allowLocalTidyTrue string // "_" means undefined
101 needTidyFile []bool // for {libfoo_0, libfoo_1} and {libbar_0, libbar_1}
102 }{
103 {"_", "_", []bool{false, false, false}},
104 {"_", "0", []bool{false, false, false}},
105 {"_", "1", []bool{false, true, false}},
106 {"_", "true", []bool{false, true, false}},
107 {"0", "_", []bool{false, false, false}},
108 {"0", "1", []bool{false, true, false}},
109 {"1", "_", []bool{true, true, false}},
110 {"1", "false", []bool{true, true, false}},
111 {"1", "1", []bool{true, true, false}},
112 {"true", "_", []bool{true, true, false}},
113 }
114 bp := `
115 cc_library_shared {
116 name: "libfoo_0", // depends on .tidy if WITH_TIDY=1
117 srcs: ["foo.c"],
118 }
119 cc_library_shared { // depends on .tidy if WITH_TIDY=1 or ALLOW_LOCAL_TIDY_TRUE=1
120 name: "libfoo_1",
121 srcs: ["foo.c"],
122 tidy: true,
123 }
124 cc_library_shared { // no .tidy
125 name: "libfoo_2",
126 srcs: ["foo.c"],
127 tidy: false,
128 }
129 cc_library_static {
130 name: "libbar_0", // depends on .tidy if WITH_TIDY=1
131 srcs: ["bar.c"],
132 }
133 cc_library_static { // depends on .tidy if WITH_TIDY=1 or ALLOW_LOCAL_TIDY_TRUE=1
134 name: "libbar_1",
135 srcs: ["bar.c"],
136 tidy: true,
137 }
138 cc_library_static { // no .tidy
139 name: "libbar_2",
140 srcs: ["bar.c"],
141 tidy: false,
142 }`
143 for index, test := range testCases {
144 testName := fmt.Sprintf("case%d,%v,%v", index, test.withTidy, test.allowLocalTidyTrue)
145 t.Run(testName, func(t *testing.T) {
146 testEnv := map[string]string{}
147 if test.withTidy != "_" {
148 testEnv["WITH_TIDY"] = test.withTidy
149 }
150 if test.allowLocalTidyTrue != "_" {
151 testEnv["ALLOW_LOCAL_TIDY_TRUE"] = test.allowLocalTidyTrue
152 }
153 ctx := android.GroupFixturePreparers(prepareForCcTest, android.FixtureMergeEnv(testEnv)).RunTestWithBp(t, bp)
154 for n := 0; n < 3; n++ {
155 checkLibraryRule := func(foo, variant, ruleName string) {
156 libName := fmt.Sprintf("lib%s_%d", foo, n)
157 tidyFile := "out/soong/.intermediates/" + libName + "/" + variant + "/obj/" + foo + ".tidy"
158 depFiles := ctx.ModuleForTests(libName, variant).Rule(ruleName).Validations.Strings()
159 if test.needTidyFile[n] {
160 android.AssertStringListContains(t, libName+" needs .tidy file", depFiles, tidyFile)
161 } else {
162 android.AssertStringListDoesNotContain(t, libName+" does not need .tidy file", depFiles, tidyFile)
163 }
164 }
165 checkLibraryRule("foo", "android_arm64_armv8-a_shared", "ld")
166 checkLibraryRule("bar", "android_arm64_armv8-a_static", "ar")
167 }
168 })
169 }
170}