Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc179bc4 authored by Paul Duffin's avatar Paul Duffin Committed by Gerrit Code Review
Browse files

Merge "Add tests for exported generated headers"

parents d4b9d045 3cb603eb
Loading
Loading
Loading
Loading
+292 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import (
	"os"
	"path/filepath"
	"reflect"
	"regexp"
	"strings"
	"testing"

@@ -3910,3 +3911,294 @@ func TestSanitizeMemtagHeapWithSanitizeDeviceDiag(t *testing.T) {
	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async)
	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync)
}

func TestIncludeDirsExporting(t *testing.T) {

	// Trim spaces from the beginning, end and immediately after any newline characters. Leaves
	// embedded newline characters alone.
	trimIndentingSpaces := func(s string) string {
		return strings.TrimSpace(regexp.MustCompile("(^|\n)\\s+").ReplaceAllString(s, "$1"))
	}

	checkPaths := func(t *testing.T, message string, expected string, paths android.Paths) {
		t.Helper()
		expected = trimIndentingSpaces(expected)
		actual := trimIndentingSpaces(strings.Join(android.FirstUniqueStrings(android.NormalizePathsForTesting(paths)), "\n"))
		if expected != actual {
			t.Errorf("%s: expected:\n%s\n actual:\n%s\n", message, expected, actual)
		}
	}

	type exportedChecker func(t *testing.T, name string, exported FlagExporterInfo)

	checkIncludeDirs := func(t *testing.T, ctx *android.TestContext, module android.Module, checkers ...exportedChecker) {
		t.Helper()
		exported := ctx.ModuleProvider(module, FlagExporterInfoProvider).(FlagExporterInfo)
		name := module.Name()

		for _, checker := range checkers {
			checker(t, name, exported)
		}
	}

	expectedIncludeDirs := func(expectedPaths string) exportedChecker {
		return func(t *testing.T, name string, exported FlagExporterInfo) {
			t.Helper()
			checkPaths(t, fmt.Sprintf("%s: include dirs", name), expectedPaths, exported.IncludeDirs)
		}
	}

	expectedSystemIncludeDirs := func(expectedPaths string) exportedChecker {
		return func(t *testing.T, name string, exported FlagExporterInfo) {
			t.Helper()
			checkPaths(t, fmt.Sprintf("%s: system include dirs", name), expectedPaths, exported.SystemIncludeDirs)
		}
	}

	expectedGeneratedHeaders := func(expectedPaths string) exportedChecker {
		return func(t *testing.T, name string, exported FlagExporterInfo) {
			t.Helper()
			checkPaths(t, fmt.Sprintf("%s: generated headers", name), expectedPaths, exported.GeneratedHeaders)
		}
	}

	expectedOrderOnlyDeps := func(expectedPaths string) exportedChecker {
		return func(t *testing.T, name string, exported FlagExporterInfo) {
			t.Helper()
			checkPaths(t, fmt.Sprintf("%s: order only deps", name), expectedPaths, exported.Deps)
		}
	}

	genRuleModules := `
		genrule {
			name: "genrule_foo",
			cmd: "generate-foo",
			out: [
				"generated_headers/foo/generated_header.h",
			],
			export_include_dirs: [
				"generated_headers",
			],
		}

		genrule {
			name: "genrule_bar",
			cmd: "generate-bar",
			out: [
				"generated_headers/bar/generated_header.h",
			],
			export_include_dirs: [
				"generated_headers",
			],
		}
	`

	t.Run("ensure exported include dirs are not automatically re-exported from shared_libs", func(t *testing.T) {
		ctx := testCc(t, genRuleModules+`
		cc_library {
			name: "libfoo",
			srcs: ["foo.c"],
			export_include_dirs: ["foo/standard"],
			export_system_include_dirs: ["foo/system"],
			generated_headers: ["genrule_foo"],
			export_generated_headers: ["genrule_foo"],
		}

		cc_library {
			name: "libbar",
			srcs: ["bar.c"],
			shared_libs: ["libfoo"],
			export_include_dirs: ["bar/standard"],
			export_system_include_dirs: ["bar/system"],
			generated_headers: ["genrule_bar"],
			export_generated_headers: ["genrule_bar"],
		}
		`)
		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
		checkIncludeDirs(t, ctx, foo,
			expectedIncludeDirs(`
				foo/standard
				.intermediates/genrule_foo/gen/generated_headers
			`),
			expectedSystemIncludeDirs(`foo/system`),
			expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
			expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
		)

		bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
		checkIncludeDirs(t, ctx, bar,
			expectedIncludeDirs(`
				bar/standard
				.intermediates/genrule_bar/gen/generated_headers
			`),
			expectedSystemIncludeDirs(`bar/system`),
			expectedGeneratedHeaders(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
			expectedOrderOnlyDeps(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
		)
	})

	t.Run("ensure exported include dirs are automatically re-exported from whole_static_libs", func(t *testing.T) {
		ctx := testCc(t, genRuleModules+`
		cc_library {
			name: "libfoo",
			srcs: ["foo.c"],
			export_include_dirs: ["foo/standard"],
			export_system_include_dirs: ["foo/system"],
			generated_headers: ["genrule_foo"],
			export_generated_headers: ["genrule_foo"],
		}

		cc_library {
			name: "libbar",
			srcs: ["bar.c"],
			whole_static_libs: ["libfoo"],
			export_include_dirs: ["bar/standard"],
			export_system_include_dirs: ["bar/system"],
			generated_headers: ["genrule_bar"],
			export_generated_headers: ["genrule_bar"],
		}
		`)
		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
		checkIncludeDirs(t, ctx, foo,
			expectedIncludeDirs(`
				foo/standard
				.intermediates/genrule_foo/gen/generated_headers
			`),
			expectedSystemIncludeDirs(`foo/system`),
			expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
			expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
		)

		bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
		checkIncludeDirs(t, ctx, bar,
			expectedIncludeDirs(`
				bar/standard
				foo/standard
				.intermediates/genrule_foo/gen/generated_headers
				.intermediates/genrule_bar/gen/generated_headers
			`),
			expectedSystemIncludeDirs(`
				bar/system
				foo/system
			`),
			expectedGeneratedHeaders(`
				.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
				.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
			`),
			expectedOrderOnlyDeps(`
				.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
				.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
			`),
		)
	})

	// TODO: fix this test as it exports all generated headers.
	t.Run("ensure only aidl headers are exported", func(t *testing.T) {
		ctx := testCc(t, genRuleModules+`
		cc_library_shared {
			name: "libfoo",
			srcs: [
				"foo.c",
				"b.aidl",
				"a.proto",
			],
			aidl: {
				export_aidl_headers: true,
			}
		}
		`)
		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
		checkIncludeDirs(t, ctx, foo,
			expectedIncludeDirs(`
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl
			`),
			expectedSystemIncludeDirs(``),
			expectedGeneratedHeaders(`
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
			`),
			expectedOrderOnlyDeps(`
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
			`),
		)
	})

	// TODO: fix this test as it exports all generated headers.
	t.Run("ensure only proto headers are exported", func(t *testing.T) {
		ctx := testCc(t, genRuleModules+`
		cc_library_shared {
			name: "libfoo",
			srcs: [
				"foo.c",
				"b.aidl",
				"a.proto",
			],
			proto: {
				export_proto_headers: true,
			}
		}
		`)
		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
		checkIncludeDirs(t, ctx, foo,
			expectedIncludeDirs(`
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto
			`),
			expectedSystemIncludeDirs(``),
			expectedGeneratedHeaders(`
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
			`),
			expectedOrderOnlyDeps(`
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
			`),
		)
	})

	// TODO: fix this test as it exports all generated headers including public and non-public.
	t.Run("ensure only non-public sysprop headers are exported", func(t *testing.T) {
		ctx := testCc(t, genRuleModules+`
		cc_library_shared {
			name: "libfoo",
			srcs: [
				"foo.c",
				"a.sysprop",
				"b.aidl",
				"a.proto",
			],
		}
		`)
		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
		checkIncludeDirs(t, ctx, foo,
			expectedIncludeDirs(`
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include
			`),
			expectedSystemIncludeDirs(``),
			expectedGeneratedHeaders(`
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/a.sysprop.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/public/include/a.sysprop.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
			`),
			expectedOrderOnlyDeps(`
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/a.sysprop.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/public/include/a.sysprop.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
			`),
		)
	})
}