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