xref: /aosp_15_r20/external/toolchain-utils/compiler_wrapper/cros_hardened_config_test.go (revision 760c253c1ed00ce9abd48f8546f08516e57485fe)
1// Copyright 2019 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package main
6
7import (
8	"fmt"
9	"path"
10	"path/filepath"
11	"strings"
12	"testing"
13)
14
15const crosHardenedGoldenDir = "testdata/cros_hardened_golden"
16const crosHardenedNoCCacheGoldenDir = "testdata/cros_hardened_noccache_golden"
17const crosHardenedLlvmNextGoldenDir = "testdata/cros_hardened_llvmnext_golden"
18
19func withGoldenTestContext(t *testing.T, f func(ctx *testContext)) {
20	withTestContext(t, func(ctx *testContext) {
21		ctx.NoteTestWritesToUmask()
22		f(ctx)
23	})
24}
25
26func TestCrosHardenedConfig(t *testing.T) {
27	withGoldenTestContext(t, func(ctx *testContext) {
28		useLlvmNext := false
29		useCCache := true
30		cfg, err := getConfig("cros.hardened", useCCache, useLlvmNext, "123")
31		if err != nil {
32			t.Fatal(err)
33		}
34		ctx.updateConfig(cfg)
35
36		runGoldenRecords(ctx, crosHardenedGoldenDir, createSyswrapperGoldenInputs(ctx))
37	})
38}
39
40func TestCrosHardenedConfigWithoutCCache(t *testing.T) {
41	withGoldenTestContext(t, func(ctx *testContext) {
42		useLlvmNext := false
43		useCCache := false
44		cfg, err := getConfig("cros.hardened", useCCache, useLlvmNext, "123")
45		if err != nil {
46			t.Fatal(err)
47		}
48		ctx.updateConfig(cfg)
49
50		// Only run the subset of the sysroot wrapper tests that execute commands.
51		gomaPath := path.Join(ctx.tempDir, "gomacc")
52		ctx.writeFile(gomaPath, "")
53		gomaEnv := "GOMACC_PATH=" + gomaPath
54		runGoldenRecords(ctx, crosHardenedNoCCacheGoldenDir, []goldenFile{
55			createGccPathGoldenInputs(ctx, gomaEnv),
56			createClangPathGoldenInputs(ctx, gomaEnv),
57			createClangSyntaxGoldenInputs(gomaEnv),
58			createBisectGoldenInputs(clangX86_64),
59			createForceDisableWErrorGoldenInputs(),
60			createClangTidyGoldenInputs(gomaEnv),
61		})
62	})
63}
64
65func TestCrosHardenedConfigWithLlvmNext(t *testing.T) {
66	withGoldenTestContext(t, func(ctx *testContext) {
67		useLlvmNext := true
68		useCCache := true
69		cfg, err := getConfig("cros.hardened", useCCache, useLlvmNext, "123")
70		if err != nil {
71			t.Fatal(err)
72		}
73		ctx.updateConfig(cfg)
74
75		// Only run the subset of the sysroot wrapper tests that execute commands.
76		gomaPath := path.Join(ctx.tempDir, "gomacc")
77		ctx.writeFile(gomaPath, "")
78		gomaEnv := "GOMACC_PATH=" + gomaPath
79		runGoldenRecords(ctx, crosHardenedLlvmNextGoldenDir, []goldenFile{
80			createGccPathGoldenInputs(ctx, gomaEnv),
81			createClangPathGoldenInputs(ctx, gomaEnv),
82			createClangSyntaxGoldenInputs(gomaEnv),
83			createBisectGoldenInputs(clangX86_64),
84			createForceDisableWErrorGoldenInputs(),
85			createClangTidyGoldenInputs(gomaEnv),
86		})
87	})
88}
89
90func createSyswrapperGoldenInputs(ctx *testContext) []goldenFile {
91	gomaPath := path.Join(ctx.tempDir, "gomacc")
92	ctx.writeFile(gomaPath, "")
93	gomaEnv := "GOMACC_PATH=" + gomaPath
94
95	return []goldenFile{
96		createGccPathGoldenInputs(ctx, gomaEnv),
97		createGoldenInputsForAllTargets("gcc", mainCc),
98		createSysrootWrapperCommonGoldenInputs("gcc", gomaEnv),
99		createSanitizerGoldenInputs("gcc"),
100		createGccArgsGoldenInputs(),
101		createClangSyntaxGoldenInputs(gomaEnv),
102		createClangPathGoldenInputs(ctx, gomaEnv),
103		createGoldenInputsForAllTargets("clang", mainCc),
104		createGoldenInputsForAllTargets("clang", "-ftrapv", mainCc),
105		createSysrootWrapperCommonGoldenInputs("clang", gomaEnv),
106		createSanitizerGoldenInputs("clang"),
107		createClangArgsGoldenInputs(),
108		createBisectGoldenInputs(clangX86_64),
109		createForceDisableWErrorGoldenInputs(),
110		createClangTidyGoldenInputs(gomaEnv),
111	}
112}
113
114func createGoldenInputsForAllTargets(compiler string, args ...string) goldenFile {
115	argsReplacer := strings.NewReplacer(".", "", "-", "")
116	return goldenFile{
117		Name: fmt.Sprintf("%s_%s_target_specific.json", compiler, argsReplacer.Replace(strings.Join(args, "_"))),
118		Records: []goldenRecord{
119			{
120				WrapperCmd: newGoldenCmd("./x86_64-cros-linux-gnu-"+compiler, args...),
121				Cmds:       okResults,
122			},
123			{
124				WrapperCmd: newGoldenCmd("./x86_64-cros-eabi-"+compiler, args...),
125				Cmds:       okResults,
126			},
127			{
128				WrapperCmd: newGoldenCmd("./x86_64-cros-win-gnu-"+compiler, args...),
129				Cmds:       okResults,
130			},
131			{
132				WrapperCmd: newGoldenCmd("./armv7m-cros-linux-gnu-"+compiler, args...),
133				Cmds:       okResults,
134			},
135			{
136				WrapperCmd: newGoldenCmd("./armv7m-cros-eabi-"+compiler, args...),
137				Cmds:       okResults,
138			},
139			{
140				WrapperCmd: newGoldenCmd("./armv7m-cros-win-gnu-"+compiler, args...),
141				Cmds:       okResults,
142			},
143			{
144				WrapperCmd: newGoldenCmd("./armv8m-cros-linux-gnu-"+compiler, args...),
145				Cmds:       okResults,
146			},
147			{
148				WrapperCmd: newGoldenCmd("./armv8m-cros-eabi-"+compiler, args...),
149				Cmds:       okResults,
150			},
151			{
152				WrapperCmd: newGoldenCmd("./armv8m-cros-win-gnu-"+compiler, args...),
153				Cmds:       okResults,
154			},
155		},
156	}
157}
158
159func createBisectGoldenInputs(compiler string) goldenFile {
160	return goldenFile{
161		Name: "bisect.json",
162		Records: []goldenRecord{
163			{
164				WrapperCmd: newGoldenCmd(compiler, mainCc),
165				Env: []string{
166					"BISECT_STAGE=someBisectStage",
167					"HOME=/user/home",
168				},
169				Cmds: okResults,
170			},
171			{
172				WrapperCmd: newGoldenCmd(compiler, mainCc),
173				Env: []string{
174					"BISECT_STAGE=someBisectStage",
175					"BISECT_DIR=someBisectDir",
176					"HOME=/user/home",
177				},
178				Cmds: okResults,
179			},
180			{
181				WrapperCmd: newGoldenCmd(compiler, mainCc),
182				Env: []string{
183					"BISECT_STAGE=someBisectStage",
184					"BISECT_DIR=someBisectDir",
185					"HOME=/user/home",
186				},
187				Cmds: errorResults,
188			},
189		},
190	}
191}
192
193func createForceDisableWErrorGoldenInputs() goldenFile {
194	return goldenFile{
195		Name: "force_disable_werror.json",
196		Records: []goldenRecord{
197			{
198				WrapperCmd: newGoldenCmd(clangX86_64, mainCc),
199				Env:        []string{"FORCE_DISABLE_WERROR=1"},
200				Cmds:       okResults,
201			},
202			{
203				WrapperCmd: newGoldenCmd(clangX86_64, mainCc),
204				Env:        []string{"FORCE_DISABLE_WERROR=1"},
205				Cmds: []commandResult{
206					{
207						Stderr:   arbitraryWerrorStderr,
208						ExitCode: 1,
209					},
210					okResult,
211				},
212			},
213			{
214				WrapperCmd: newGoldenCmd(clangX86_64, mainCc),
215				Env:        []string{"FORCE_DISABLE_WERROR=1"},
216				Cmds: []commandResult{
217					{
218						Stderr:   arbitraryWerrorStderr,
219						ExitCode: 1,
220					},
221					errorResult,
222				},
223			},
224		},
225	}
226}
227
228func createGccPathGoldenInputs(ctx *testContext, gomaEnv string) goldenFile {
229	deepPath := "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc"
230	linkedDeepPath := "./symlinked/x86_64-cros-linux-gnu-gcc"
231	ctx.writeFile(filepath.Join(ctx.tempDir, "/pathenv/x86_64-cros-linux-gnu-gcc"), "")
232	ctx.symlink(deepPath, linkedDeepPath)
233	return goldenFile{
234		Name: "gcc_path.json",
235		Records: []goldenRecord{
236			{
237				WrapperCmd: newGoldenCmd("./x86_64-cros-linux-gnu-gcc", mainCc),
238				Cmds:       okResults,
239			},
240			{
241				WrapperCmd: newGoldenCmd("./x86_64-cros-linux-gnu-gcc", mainCc),
242				Cmds:       errorResults,
243			},
244			{
245				WrapperCmd: newGoldenCmd(filepath.Join(ctx.tempDir, "x86_64-cros-linux-gnu-gcc"), mainCc),
246				Cmds:       okResults,
247			},
248			{
249				WrapperCmd: newGoldenCmd(deepPath, mainCc),
250				Cmds:       okResults,
251			},
252			{
253				WrapperCmd: newGoldenCmd(linkedDeepPath, mainCc),
254				Cmds:       okResults,
255			},
256			{
257				Env:        []string{"PATH=" + filepath.Join(ctx.tempDir, "/pathenv")},
258				WrapperCmd: newGoldenCmd("x86_64-cros-linux-gnu-gcc", mainCc),
259				Cmds:       okResults,
260			},
261		},
262	}
263}
264
265func createClangPathGoldenInputs(ctx *testContext, gomaEnv string) goldenFile {
266	deepPath := "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-clang"
267	linkedDeepPath := "./symlinked/x86_64-cros-linux-gnu-clang"
268	ctx.writeFile(filepath.Join(ctx.tempDir, "/pathenv/x86_64-cros-linux-gnu-clang"), "")
269	ctx.symlink(deepPath, linkedDeepPath)
270	return goldenFile{
271		Name: "clang_path.json",
272		Records: []goldenRecord{
273			{
274				WrapperCmd: newGoldenCmd("./x86_64-cros-linux-gnu-clang", mainCc),
275				Cmds:       okResults,
276			},
277			{
278				WrapperCmd: newGoldenCmd("./x86_64-cros-linux-gnu-clang", mainCc),
279				Cmds:       errorResults,
280			},
281			{
282				WrapperCmd: newGoldenCmd("./x86_64-cros-linux-gnu-clang++", mainCc),
283				Cmds:       okResults,
284			},
285			{
286				WrapperCmd: newGoldenCmd(clangX86_64, mainCc),
287				Env:        []string{"CLANG=somepath/clang"},
288				Cmds:       okResults,
289			},
290			{
291				WrapperCmd: newGoldenCmd(clangX86_64, "-Xclang-path=/somedir", mainCc),
292				Cmds: []commandResult{
293					{Stdout: "someResourceDir"},
294					okResult,
295				},
296			},
297			{
298				WrapperCmd: newGoldenCmd(clangX86_64, "-Xclang-path=/somedir", mainCc),
299				Env:        []string{gomaEnv},
300				Cmds: []commandResult{
301					{Stdout: "someResourceDir"},
302					okResult,
303				},
304			},
305			{
306				WrapperCmd: newGoldenCmd(clangX86_64, "-Xclang-path=/somedir", mainCc),
307				Cmds: []commandResult{
308					{Stdout: "someResourceDir"},
309					errorResult,
310				},
311			},
312			{
313				WrapperCmd: newGoldenCmd(filepath.Join(ctx.tempDir, "x86_64-cros-linux-gnu-clang"), mainCc),
314				Cmds:       okResults,
315			},
316			{
317				WrapperCmd: newGoldenCmd(deepPath, mainCc),
318				Cmds:       okResults,
319			},
320			{
321				WrapperCmd: newGoldenCmd(linkedDeepPath, mainCc),
322				Cmds:       okResults,
323			},
324			{
325				WrapperCmd: newGoldenCmd("somedir/x86_64-cros-linux-gnu-clang", mainCc),
326				Cmds:       okResults,
327			},
328			{
329				Env:        []string{"PATH=" + filepath.Join(ctx.tempDir, "/pathenv")},
330				WrapperCmd: newGoldenCmd("x86_64-cros-linux-gnu-clang", mainCc),
331				Cmds:       okResults,
332			},
333		},
334	}
335}
336
337func createClangTidyGoldenInputs(gomaEnv string) goldenFile {
338	tidyEnv := "WITH_TIDY=1"
339	return goldenFile{
340		Name: "clangtidy.json",
341		Records: []goldenRecord{
342			{
343				WrapperCmd: newGoldenCmd(clangX86_64, mainCc),
344				Env:        []string{tidyEnv},
345				Cmds: []commandResult{
346					{Stdout: "someResourceDir"},
347					okResult,
348					okResult,
349				},
350			},
351			{
352				WrapperCmd: newGoldenCmd(clangX86_64, mainCc),
353				Env:        []string{tidyEnv, gomaEnv},
354				Cmds: []commandResult{
355					{Stdout: "someResourceDir"},
356					okResult,
357					okResult,
358				},
359			},
360			{
361				WrapperCmd: newGoldenCmd(clangX86_64, mainCc),
362				Env:        []string{tidyEnv, gomaEnv},
363				Cmds: []commandResult{
364					{Stdout: "someResourceDir"},
365					errorResult,
366					// TODO: we don't fail the compilation due to clang-tidy, as that
367					// is the behavior in the old wrapper. Consider changing this in
368					// the future.
369					okResult,
370				},
371			},
372			{
373				WrapperCmd: newGoldenCmd(clangX86_64, mainCc),
374				Env:        []string{tidyEnv, gomaEnv},
375				Cmds: []commandResult{
376					{Stdout: "someResourceDir"},
377					okResult,
378					errorResult,
379				},
380			},
381		},
382	}
383}
384
385func createClangSyntaxGoldenInputs(gomaEnv string) goldenFile {
386	return goldenFile{
387		Name: "gcc_clang_syntax.json",
388		Records: []goldenRecord{
389			{
390				WrapperCmd: newGoldenCmd(gccX86_64, "-clang-syntax", mainCc),
391				Cmds: []commandResult{
392					okResult,
393					okResult,
394				},
395			},
396			{
397				WrapperCmd: newGoldenCmd(gccX86_64, "-clang-syntax", mainCc),
398				Env:        []string{gomaEnv},
399				Cmds: []commandResult{
400					okResult,
401					okResult,
402				},
403			},
404			{
405				WrapperCmd: newGoldenCmd(gccX86_64, "-clang-syntax", mainCc),
406				Cmds:       errorResults,
407			},
408			{
409				WrapperCmd: newGoldenCmd(gccX86_64, "-clang-syntax", mainCc),
410				Cmds: []commandResult{
411					okResult,
412					errorResult,
413				},
414			},
415		},
416	}
417}
418
419func createSysrootWrapperCommonGoldenInputs(compiler string, gomaEnv string) goldenFile {
420	// We are using a fixed target as all of the following args are target independent.
421	wrapperPath := "./x86_64-cros-linux-gnu-" + compiler
422	return goldenFile{
423		Name: compiler + "_sysroot_wrapper_common.json",
424		Records: []goldenRecord{
425			{
426				WrapperCmd: newGoldenCmd(gccX86_64, "-noccache", mainCc),
427				Cmds:       okResults,
428			},
429			{
430				WrapperCmd: newGoldenCmd(wrapperPath, mainCc),
431				Env:        []string{"GOMACC_PATH=someNonExistingPath"},
432				Cmds:       okResults,
433			},
434			{
435				WrapperCmd: newGoldenCmd(wrapperPath, mainCc),
436				Env:        []string{gomaEnv},
437				Cmds:       okResults,
438			},
439			{
440				WrapperCmd: newGoldenCmd(wrapperPath, "-nopie", mainCc),
441				Cmds:       okResults,
442			},
443			{
444				WrapperCmd: newGoldenCmd(wrapperPath, "-D__KERNEL__", mainCc),
445				Cmds:       okResults,
446			},
447			{
448				WrapperCmd: newGoldenCmd("./armv7a-cros-linux-gnueabihf-"+compiler,
449					"-D__KERNEL__", mainCc),
450				Cmds: okResults,
451			},
452			{
453				WrapperCmd: newGoldenCmd(wrapperPath, "--sysroot=xyz", mainCc),
454				Cmds:       okResults,
455			},
456		},
457	}
458}
459
460func createSanitizerGoldenInputs(compiler string) goldenFile {
461	// We are using a fixed target as all of the following args are target independent.
462	wrapperPath := "./x86_64-cros-linux-gnu-" + compiler
463	return goldenFile{
464		Name: compiler + "_sanitizer_args.json",
465		Records: []goldenRecord{
466			{
467				WrapperCmd: newGoldenCmd(wrapperPath, "-fsanitize=kernel-address", "-Wl,--no-undefined", mainCc),
468				Cmds:       okResults,
469			},
470			{
471				WrapperCmd: newGoldenCmd(wrapperPath, "-fsanitize=kernel-address", "-Wl,-z,defs", mainCc),
472				Cmds:       okResults,
473			},
474			{
475				WrapperCmd: newGoldenCmd(wrapperPath, "-fsanitize=kernel-address", "-D_FORTIFY_SOURCE=1", mainCc),
476				Cmds:       okResults,
477			},
478			{
479				WrapperCmd: newGoldenCmd(wrapperPath, "-fsanitize=kernel-address", "-D_FORTIFY_SOURCE=2", mainCc),
480				Cmds:       okResults,
481			},
482			{
483				WrapperCmd: newGoldenCmd(wrapperPath, "-fsanitize=fuzzer", mainCc),
484				Cmds:       okResults,
485			},
486			{
487				WrapperCmd: newGoldenCmd(wrapperPath, "-fsanitize=address", "-fprofile-instr-generate", mainCc),
488				Cmds:       okResults,
489			},
490			{
491				WrapperCmd: newGoldenCmd(wrapperPath, "-fsanitize=address", mainCc),
492				Cmds:       okResults,
493			},
494			{
495				WrapperCmd: newGoldenCmd(wrapperPath, "-fprofile-instr-generate", mainCc),
496				Cmds:       okResults,
497			},
498		},
499	}
500}
501
502func createGccArgsGoldenInputs() goldenFile {
503	return goldenFile{
504		Name: "gcc_specific_args.json",
505		Records: []goldenRecord{
506			{
507				WrapperCmd: newGoldenCmd(gccX86_64, "-march=goldmont", mainCc),
508				Cmds:       okResults,
509			},
510			{
511				WrapperCmd: newGoldenCmd(gccX86_64, "-march=goldmont-plus", mainCc),
512				Cmds:       okResults,
513			},
514			{
515				WrapperCmd: newGoldenCmd(gccX86_64, "-march=skylake", mainCc),
516				Cmds:       okResults,
517			},
518		},
519	}
520}
521
522func createClangArgsGoldenInputs() goldenFile {
523	return goldenFile{
524		Name: "clang_specific_args.json",
525		Records: []goldenRecord{
526			{
527				WrapperCmd: newGoldenCmd(clangX86_64, "-mno-movbe", "-Wclobbered", "-Wno-psabi", "-Wlogical-op",
528					"-Wmissing-parameter-type", "-Wold-style-declaration", "-Woverride-init", "-Wunsafe-loop-optimizations",
529					"-Wstrict-aliasing=abc", "-finline-limit=abc", mainCc),
530				Cmds: okResults,
531			},
532			{
533				WrapperCmd: newGoldenCmd(clangX86_64, "-Wno-error=cpp", mainCc),
534				Cmds:       okResults,
535			},
536			{
537				WrapperCmd: newGoldenCmd(clangX86_64, "-Wno-error=maybe-uninitialized", mainCc),
538				Cmds:       okResults,
539			},
540			{
541				WrapperCmd: newGoldenCmd(clangX86_64, "-Xclang-only=-someflag", mainCc),
542				Cmds:       okResults,
543			},
544		},
545	}
546}
547