xref: /aosp_15_r20/build/soong/cc/afdo_test.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1// 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	"runtime"
19	"strings"
20	"testing"
21
22	"android/soong/android"
23
24	"github.com/google/blueprint"
25)
26
27type visitDirectDepsInterface interface {
28	VisitDirectDeps(blueprint.Module, func(dep blueprint.Module))
29}
30
31func hasDirectDep(ctx visitDirectDepsInterface, m android.Module, wantDep android.Module) bool {
32	var found bool
33	ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
34		if dep == wantDep {
35			found = true
36		}
37	})
38	return found
39}
40
41func TestAfdoDeps(t *testing.T) {
42	t.Parallel()
43	bp := `
44	cc_library_shared {
45		name: "libTest",
46		host_supported: true,
47		srcs: ["test.c"],
48		static_libs: ["libFoo"],
49		afdo: true,
50		lto: {
51			thin: true,
52		},
53	}
54
55	cc_library_static {
56		name: "libFoo",
57		host_supported: true,
58		srcs: ["foo.c"],
59		static_libs: ["libBar"],
60	}
61
62	cc_library_static {
63		name: "libBar",
64		host_supported: true,
65		srcs: ["bar.c"],
66	}
67	`
68
69	result := android.GroupFixturePreparers(
70		PrepareForTestWithFdoProfile,
71		prepareForCcTest,
72		android.FixtureAddTextFile("afdo_profiles_package/libTest.afdo", ""),
73		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
74			variables.AfdoProfiles = []string{
75				"libTest://afdo_profiles_package:libTest_afdo",
76			}
77		}),
78		android.MockFS{
79			"afdo_profiles_package/Android.bp": []byte(`
80				fdo_profile {
81					name: "libTest_afdo",
82					arch: {
83						arm64: {
84							profile: "libTest.afdo",
85						},
86					},
87				}
88			`),
89		}.AddToFixture(),
90	).RunTestWithBp(t, bp)
91
92	profileSampleCFlag := "-fprofile-sample-use=afdo_profiles_package/libTest.afdo"
93	uniqueInternalLinkageNamesCFlag := "-funique-internal-linkage-names"
94	afdoLtoLdFlag := "-Wl,-plugin-opt,-import-instr-limit=40"
95	noAfdoLtoLdFlag := "-Wl,-plugin-opt,-import-instr-limit=5"
96
97	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
98	libFooAfdoVariant := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest")
99	libBarAfdoVariant := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_afdo-libTest")
100
101	// Check cFlags of afdo-enabled module and the afdo-variant of its static deps
102	cFlags := libTest.Rule("cc").Args["cFlags"]
103	if !strings.Contains(cFlags, profileSampleCFlag) {
104		t.Errorf("Expected 'libTest' to enable afdo profile, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
105	}
106	if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
107		t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
108	}
109
110	ldFlags := libTest.Rule("ld").Args["ldFlags"]
111	if !strings.Contains(ldFlags, afdoLtoLdFlag) {
112		t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in ldflags %q", afdoLtoLdFlag, ldFlags)
113	}
114
115	cFlags = libFooAfdoVariant.Rule("cc").Args["cFlags"]
116	if !strings.Contains(cFlags, profileSampleCFlag) {
117		t.Errorf("Expected 'libFooAfdoVariant' to enable afdo profile, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
118	}
119	if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
120		t.Errorf("Expected 'libFooAfdoVariant' to enable afdo, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
121	}
122
123	cFlags = libBarAfdoVariant.Rule("cc").Args["cFlags"]
124	if !strings.Contains(cFlags, profileSampleCFlag) {
125		t.Errorf("Expected 'libBarAfdoVariant' to enable afdo profile, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
126	}
127	if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
128		t.Errorf("Expected 'libBarAfdoVariant' to enable afdo, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
129	}
130
131	// Check dependency edge from afdo-enabled module to static deps
132	if !hasDirectDep(result, libTest.Module(), libFooAfdoVariant.Module()) {
133		t.Errorf("libTest missing dependency on afdo variant of libFoo")
134	}
135
136	if !hasDirectDep(result, libFooAfdoVariant.Module(), libBarAfdoVariant.Module()) {
137		t.Errorf("libTest missing dependency on afdo variant of libBar")
138	}
139
140	// Verify non-afdo variant exists and doesn't contain afdo
141	libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
142	libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
143
144	cFlags = libFoo.Rule("cc").Args["cFlags"]
145	if strings.Contains(cFlags, profileSampleCFlag) {
146		t.Errorf("Expected 'libFoo' to not enable afdo profile, but found %q in cflags %q", profileSampleCFlag, cFlags)
147	}
148	if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
149		t.Errorf("Expected 'libFoo' to not enable afdo, but found %q in cflags %q", profileSampleCFlag, cFlags)
150	}
151	cFlags = libBar.Rule("cc").Args["cFlags"]
152	if strings.Contains(cFlags, profileSampleCFlag) {
153		t.Errorf("Expected 'libBar' to not enable afdo profile, but found %q in cflags %q", profileSampleCFlag, cFlags)
154	}
155	if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
156		t.Errorf("Expected 'libBar' to not enable afdo, but found %q in cflags %q", profileSampleCFlag, cFlags)
157	}
158
159	// Check dependency edges of static deps
160	if hasDirectDep(result, libTest.Module(), libFoo.Module()) {
161		t.Errorf("libTest should not depend on non-afdo variant of libFoo")
162	}
163
164	if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
165		t.Errorf("libFoo missing dependency on non-afdo variant of libBar")
166	}
167
168	// Verify that the arm variant does not have FDO since the fdo_profile module only has a profile for arm64
169	libTest32 := result.ModuleForTests("libTest", "android_arm_armv7-a-neon_shared")
170	libFooAfdoVariant32 := result.ModuleForTests("libFoo", "android_arm_armv7-a-neon_static_afdo-libTest_lto-thin")
171	libBarAfdoVariant32 := result.ModuleForTests("libBar", "android_arm_armv7-a-neon_static_afdo-libTest_lto-thin")
172
173	cFlags = libTest32.Rule("cc").Args["cFlags"]
174	if strings.Contains(cFlags, profileSampleCFlag) {
175		t.Errorf("Expected arm32 'libTest' not to enable afdo, but found %q in cflags %q", profileSampleCFlag, cFlags)
176	}
177
178	// TODO(b/324141705): when the fdo_profile module doesn't provide a source file the dependencies don't get
179	//  -funique-internal-linkage-names but the module does.
180	if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
181		t.Errorf("Expected arm32 'libTest' to enable -funique-internal-linkage-names but did not find %q in cflags %q",
182			uniqueInternalLinkageNamesCFlag, cFlags)
183	}
184
185	ldFlags = libTest32.Rule("ld").Args["ldFlags"]
186	if !strings.Contains(ldFlags, noAfdoLtoLdFlag) {
187		t.Errorf("Expected arm32 'libTest' to not enable afdo, but did not find %q in ldflags %q", noAfdoLtoLdFlag, ldFlags)
188	}
189	if strings.Contains(ldFlags, afdoLtoLdFlag) {
190		t.Errorf("Expected arm32 'libTest' to not enable afdo, but found %q in ldflags %q", afdoLtoLdFlag, ldFlags)
191	}
192
193	// Check dependency edge from afdo-enabled module to static deps
194	if !hasDirectDep(result, libTest32.Module(), libFooAfdoVariant32.Module()) {
195		t.Errorf("arm32 libTest missing dependency on afdo variant of libFoo")
196	}
197
198	if !hasDirectDep(result, libFooAfdoVariant32.Module(), libBarAfdoVariant32.Module()) {
199		t.Errorf("arm32 libTest missing dependency on afdo variant of libBar")
200	}
201
202	cFlags = libFooAfdoVariant32.Rule("cc").Args["cFlags"]
203	if strings.Contains(cFlags, profileSampleCFlag) {
204		t.Errorf("Expected arm32 'libFoo' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
205	}
206	if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
207		t.Errorf("Expected arm32 'libFoo' to enable afdo, but did not find %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
208	}
209	cFlags = libBarAfdoVariant32.Rule("cc").Args["cFlags"]
210	if strings.Contains(cFlags, profileSampleCFlag) {
211		t.Errorf("Expected arm32 'libBar' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
212	}
213	if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
214		t.Errorf("Expected arm32 'libBar' to enable afdo, but did not find %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
215	}
216
217	// Verify that the host variants don't enable afdo
218	libTestHost := result.ModuleForTests("libTest", result.Config.BuildOSTarget.String()+"_shared")
219	libFooHost := result.ModuleForTests("libFoo", result.Config.BuildOSTarget.String()+"_static_lto-thin")
220	libBarHost := result.ModuleForTests("libBar", result.Config.BuildOSTarget.String()+"_static_lto-thin")
221
222	cFlags = libTestHost.Rule("cc").Args["cFlags"]
223	if strings.Contains(cFlags, profileSampleCFlag) {
224		t.Errorf("Expected host 'libTest' to not enable afdo profile, but found %q in cflags %q", profileSampleCFlag, cFlags)
225	}
226
227	if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
228		t.Errorf("Expected host 'libTest' to not enable afdo but found %q in cflags %q",
229			uniqueInternalLinkageNamesCFlag, cFlags)
230	}
231
232	if runtime.GOOS != "darwin" {
233		ldFlags := libTestHost.Rule("ld").Args["ldFlags"]
234		if !strings.Contains(ldFlags, noAfdoLtoLdFlag) {
235			t.Errorf("Expected host 'libTest' to not enable afdo, but did not find %q in ldflags %q", noAfdoLtoLdFlag, ldFlags)
236		}
237		if strings.Contains(ldFlags, afdoLtoLdFlag) {
238			t.Errorf("Expected host 'libTest' to not enable afdo, but found %q in ldflags %q", afdoLtoLdFlag, ldFlags)
239		}
240	}
241
242	// Check dependency edge from afdo-enabled module to static deps
243	if !hasDirectDep(result, libTestHost.Module(), libFooHost.Module()) {
244		t.Errorf("host libTest missing dependency on non-afdo variant of libFoo")
245	}
246
247	if !hasDirectDep(result, libFooHost.Module(), libBarHost.Module()) {
248		t.Errorf("host libTest missing dependency on non-afdo variant of libBar")
249	}
250
251	cFlags = libFooHost.Rule("cc").Args["cFlags"]
252	if strings.Contains(cFlags, profileSampleCFlag) {
253		t.Errorf("Expected host 'libFoo' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
254	}
255	if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
256		t.Errorf("Expected host 'libFoo' to not enable afdo, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
257	}
258	cFlags = libBarHost.Rule("cc").Args["cFlags"]
259	if strings.Contains(cFlags, profileSampleCFlag) {
260		t.Errorf("Expected host 'libBar' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
261	}
262	if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
263		t.Errorf("Expected host 'libBar' to not enable afdo, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
264	}
265}
266
267func TestAfdoEnabledOnStaticDepNoAfdo(t *testing.T) {
268	t.Parallel()
269	bp := `
270	cc_library_shared {
271		name: "libTest",
272		srcs: ["foo.c"],
273		static_libs: ["libFoo"],
274	}
275
276	cc_library_static {
277		name: "libFoo",
278		srcs: ["foo.c"],
279		static_libs: ["libBar"],
280		afdo: true, // TODO(b/256670524): remove support for enabling afdo from static only libraries, this can only propagate from shared libraries/binaries
281	}
282
283	cc_library_static {
284		name: "libBar",
285	}
286	`
287
288	result := android.GroupFixturePreparers(
289		prepareForCcTest,
290		PrepareForTestWithFdoProfile,
291		android.FixtureAddTextFile("toolchain/pgo-profiles/sampling/libFoo.afdo", ""),
292		android.MockFS{
293			"afdo_profiles_package/Android.bp": []byte(`
294				soong_namespace {
295				}
296				fdo_profile {
297					name: "libFoo_afdo",
298					profile: "libFoo.afdo",
299				}
300			`),
301		}.AddToFixture(),
302	).RunTestWithBp(t, bp)
303
304	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared").Module()
305	libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
306	libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static").Module()
307
308	if !hasDirectDep(result, libTest, libFoo.Module()) {
309		t.Errorf("libTest missing dependency on non-afdo variant of libFoo")
310	}
311
312	if !hasDirectDep(result, libFoo.Module(), libBar) {
313		t.Errorf("libFoo missing dependency on non-afdo variant of libBar")
314	}
315
316	fooVariants := result.ModuleVariantsForTests("foo")
317	for _, v := range fooVariants {
318		if strings.Contains(v, "afdo-") {
319			t.Errorf("Expected no afdo variant of 'foo', got %q", v)
320		}
321	}
322
323	cFlags := libFoo.Rule("cc").Args["cFlags"]
324	if w := "-fprofile-sample-accurate"; strings.Contains(cFlags, w) {
325		t.Errorf("Expected 'foo' to not enable afdo, but found %q in cflags %q", w, cFlags)
326	}
327
328	barVariants := result.ModuleVariantsForTests("bar")
329	for _, v := range barVariants {
330		if strings.Contains(v, "afdo-") {
331			t.Errorf("Expected no afdo variant of 'bar', got %q", v)
332		}
333	}
334}
335
336func TestAfdoEnabledWithRuntimeDepNoAfdo(t *testing.T) {
337	bp := `
338	cc_library {
339		name: "libTest",
340		srcs: ["foo.c"],
341		runtime_libs: ["libFoo"],
342		afdo: true,
343	}
344
345	cc_library {
346		name: "libFoo",
347	}
348	`
349
350	result := android.GroupFixturePreparers(
351		prepareForCcTest,
352		PrepareForTestWithFdoProfile,
353		android.FixtureAddTextFile("afdo_profiles_package/libTest.afdo", ""),
354		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
355			variables.AfdoProfiles = []string{
356				"libTest://afdo_profiles_package:libTest_afdo",
357			}
358		}),
359		android.MockFS{
360			"afdo_profiles_package/Android.bp": []byte(`
361				fdo_profile {
362					name: "libTest_afdo",
363					profile: "libTest.afdo",
364				}
365			`),
366		}.AddToFixture(),
367	).RunTestWithBp(t, bp)
368
369	libFooVariants := result.ModuleVariantsForTests("libFoo")
370	for _, v := range libFooVariants {
371		if strings.Contains(v, "afdo-") {
372			t.Errorf("Expected no afdo variant of 'foo', got %q", v)
373		}
374	}
375}
376
377func TestAfdoEnabledWithMultiArchs(t *testing.T) {
378	bp := `
379	cc_library_shared {
380		name: "foo",
381		srcs: ["test.c"],
382		afdo: true,
383		compile_multilib: "both",
384	}
385`
386	result := android.GroupFixturePreparers(
387		PrepareForTestWithFdoProfile,
388		prepareForCcTest,
389		android.FixtureAddTextFile("afdo_profiles_package/foo_arm.afdo", ""),
390		android.FixtureAddTextFile("afdo_profiles_package/foo_arm64.afdo", ""),
391		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
392			variables.AfdoProfiles = []string{
393				"foo://afdo_profiles_package:foo_afdo",
394			}
395		}),
396		android.MockFS{
397			"afdo_profiles_package/Android.bp": []byte(`
398				soong_namespace {
399				}
400				fdo_profile {
401					name: "foo_afdo",
402					arch: {
403						arm: {
404							profile: "foo_arm.afdo",
405						},
406						arm64: {
407							profile: "foo_arm64.afdo",
408						}
409					}
410				}
411			`),
412		}.AddToFixture(),
413	).RunTestWithBp(t, bp)
414
415	fooArm := result.ModuleForTests("foo", "android_arm_armv7-a-neon_shared")
416	fooArmCFlags := fooArm.Rule("cc").Args["cFlags"]
417	if w := "-fprofile-sample-use=afdo_profiles_package/foo_arm.afdo"; !strings.Contains(fooArmCFlags, w) {
418		t.Errorf("Expected 'foo' to enable afdo, but did not find %q in cflags %q", w, fooArmCFlags)
419	}
420
421	fooArm64 := result.ModuleForTests("foo", "android_arm64_armv8-a_shared")
422	fooArm64CFlags := fooArm64.Rule("cc").Args["cFlags"]
423	if w := "-fprofile-sample-use=afdo_profiles_package/foo_arm64.afdo"; !strings.Contains(fooArm64CFlags, w) {
424		t.Errorf("Expected 'foo' to enable afdo, but did not find %q in cflags %q", w, fooArm64CFlags)
425	}
426}
427
428func TestMultipleAfdoRDeps(t *testing.T) {
429	t.Parallel()
430	bp := `
431	cc_library_shared {
432		name: "libTest",
433		srcs: ["test.c"],
434		static_libs: ["libFoo"],
435		afdo: true,
436	}
437
438	cc_library_shared {
439		name: "libBar",
440		srcs: ["bar.c"],
441		static_libs: ["libFoo"],
442		afdo: true,
443	}
444
445	cc_library_static {
446		name: "libFoo",
447		srcs: ["foo.c"],
448	}
449	`
450
451	result := android.GroupFixturePreparers(
452		PrepareForTestWithFdoProfile,
453		prepareForCcTest,
454		android.FixtureAddTextFile("afdo_profiles_package/libTest.afdo", ""),
455		android.FixtureAddTextFile("afdo_profiles_package/libBar.afdo", ""),
456		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
457			variables.AfdoProfiles = []string{
458				"libTest://afdo_profiles_package:libTest_afdo",
459				"libBar://afdo_profiles_package:libBar_afdo",
460			}
461		}),
462		android.MockFS{
463			"afdo_profiles_package/Android.bp": []byte(`
464				fdo_profile {
465					name: "libTest_afdo",
466					profile: "libTest.afdo",
467				}
468				fdo_profile {
469					name: "libBar_afdo",
470					profile: "libBar.afdo",
471				}
472			`),
473		}.AddToFixture(),
474	).RunTestWithBp(t, bp)
475
476	expectedCFlagLibTest := "-fprofile-sample-use=afdo_profiles_package/libTest.afdo"
477	expectedCFlagLibBar := "-fprofile-sample-use=afdo_profiles_package/libBar.afdo"
478
479	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
480	libFooAfdoVariantWithLibTest := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest")
481
482	libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_shared")
483	libFooAfdoVariantWithLibBar := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libBar")
484
485	// Check cFlags of afdo-enabled module and the afdo-variant of its static deps
486	cFlags := libTest.Rule("cc").Args["cFlags"]
487	if !strings.Contains(cFlags, expectedCFlagLibTest) {
488		t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibTest, cFlags)
489	}
490	cFlags = libBar.Rule("cc").Args["cFlags"]
491	if !strings.Contains(cFlags, expectedCFlagLibBar) {
492		t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibBar, cFlags)
493	}
494
495	cFlags = libFooAfdoVariantWithLibTest.Rule("cc").Args["cFlags"]
496	if !strings.Contains(cFlags, expectedCFlagLibTest) {
497		t.Errorf("Expected 'libFooAfdoVariantWithLibTest' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibTest, cFlags)
498	}
499
500	cFlags = libFooAfdoVariantWithLibBar.Rule("cc").Args["cFlags"]
501	if !strings.Contains(cFlags, expectedCFlagLibBar) {
502		t.Errorf("Expected 'libBarAfdoVariant' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibBar, cFlags)
503	}
504
505	// Check dependency edges of static deps
506	if !hasDirectDep(result, libTest.Module(), libFooAfdoVariantWithLibTest.Module()) {
507		t.Errorf("libTest missing dependency on afdo variant of libFoo")
508	}
509
510	if !hasDirectDep(result, libBar.Module(), libFooAfdoVariantWithLibBar.Module()) {
511		t.Errorf("libFoo missing dependency on non-afdo variant of libBar")
512	}
513}
514
515func TestAfdoDepsWithoutProfile(t *testing.T) {
516	t.Parallel()
517	bp := `
518	cc_library_shared {
519		name: "libTest",
520		srcs: ["test.c"],
521		static_libs: ["libFoo"],
522		afdo: true,
523	}
524
525	cc_library_static {
526		name: "libFoo",
527		srcs: ["foo.c"],
528		static_libs: ["libBar"],
529	}
530
531	cc_library_static {
532		name: "libBar",
533		srcs: ["bar.c"],
534	}
535	`
536
537	result := android.GroupFixturePreparers(
538		PrepareForTestWithFdoProfile,
539		prepareForCcTest,
540	).RunTestWithBp(t, bp)
541
542	// Even without a profile path, the afdo enabled libraries should be built with
543	// -funique-internal-linkage-names.
544	expectedCFlag := "-funique-internal-linkage-names"
545
546	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
547	libFooAfdoVariant := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest")
548	libBarAfdoVariant := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_afdo-libTest")
549
550	// Check cFlags of afdo-enabled module and the afdo-variant of its static deps
551	cFlags := libTest.Rule("cc").Args["cFlags"]
552	if !strings.Contains(cFlags, expectedCFlag) {
553		t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags)
554	}
555
556	cFlags = libFooAfdoVariant.Rule("cc").Args["cFlags"]
557	if !strings.Contains(cFlags, expectedCFlag) {
558		t.Errorf("Expected 'libFooAfdoVariant' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags)
559	}
560
561	cFlags = libBarAfdoVariant.Rule("cc").Args["cFlags"]
562	if !strings.Contains(cFlags, expectedCFlag) {
563		t.Errorf("Expected 'libBarAfdoVariant' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags)
564	}
565	// Check dependency edge from afdo-enabled module to static deps
566	if !hasDirectDep(result, libTest.Module(), libFooAfdoVariant.Module()) {
567		t.Errorf("libTest missing dependency on afdo variant of libFoo")
568	}
569
570	if !hasDirectDep(result, libFooAfdoVariant.Module(), libBarAfdoVariant.Module()) {
571		t.Errorf("libTest missing dependency on afdo variant of libBar")
572	}
573
574	// Verify non-afdo variant exists and doesn't contain afdo
575	libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
576	libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
577
578	cFlags = libFoo.Rule("cc").Args["cFlags"]
579	if strings.Contains(cFlags, expectedCFlag) {
580		t.Errorf("Expected 'libFoo' to not enable afdo, but found %q in cflags %q", expectedCFlag, cFlags)
581	}
582	cFlags = libBar.Rule("cc").Args["cFlags"]
583	if strings.Contains(cFlags, expectedCFlag) {
584		t.Errorf("Expected 'libBar' to not enable afdo, but found %q in cflags %q", expectedCFlag, cFlags)
585	}
586
587	// Check dependency edges of static deps
588	if hasDirectDep(result, libTest.Module(), libFoo.Module()) {
589		t.Errorf("libTest should not depend on non-afdo variant of libFoo")
590	}
591
592	if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
593		t.Errorf("libFoo missing dependency on non-afdo variant of libBar")
594	}
595}
596