Add protobuf for test data

It introduces `DeviceSelectionSample` and `SelectionSampleBundle`
in `device_selection.proto` to hold sample HWIDs to validate
the device selection matching mechanism.

In addition, it also revises the installation utilities to load the
test data from private overlays while building.

BUG=b:314654314
TEST=create a sample `device_selection_sample.textproto` \
     then run `emerge-<board> feature-management-bsp` \
     then run `emerge-<board> feature-management-data` \
     then manually verify the corresponding `_pb.h` file is installed

Cq-Depend: chromium:5076839
Change-Id: I193800f5788fbfa5fe7d4640557effaa86a73336
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/feature-management/+/5076838
Reviewed-by: Gwendal Grignou <gwendal@chromium.org>
Tested-by: Yong Hong <yhong@chromium.org>
Commit-Queue: Yong Hong <yhong@chromium.org>
diff --git a/Makefile b/Makefile
index 83da622..e6a6737 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,7 @@
 GENERATED = ${SRCDIR}/generated
 PROTO = ${SRCDIR}/proto
 DEVICES = ${SRCDIR}/devices
+DEVICES_TEST = ${SRCDIR}/devices_test
 
 # Protobuf binary code.
 GENERATED_DESCPB_BIN = ${GENERATED}/descpb.bin
@@ -23,12 +24,21 @@
 # protobuf describing the device selections.
 DEVICES_SELECTIONS = $(wildcard ${DEVICES}/*textproto)
 
+# protobuf describing the device selection samples.
+DEVICES_SELECTION_SAMPLES = $(wildcard ${DEVICES_TEST}/*textproto)
+
 # Binary version of the database with all feature descriptions.
 GENERATED_DEVICE_BIN = ${GENERATED}/devices_final.binary
 
+# Binary version of the device selection test data for libsegmentation.
+GENERATED_SELECTION_SAMPLE_BIN = ${GENERATED}/selection_sample_final.binary
+
 # Generated .h file from the database for libsegmentation.
 GENERATED_LIGSEGMENTATION_PB_H = ${GENERATED}/libsegmentation_pb.h
 
+# Generated .h file for test data for libsegmentation.
+GENERATED_LIGSEGMENTATION_TEST_PB_H  = ${GENERATED}/libsegmentation_test_pb.h
+
 # Verbose? Use V=1
 ifeq ($(filter-out 0,${V}),)
 Q := @
@@ -36,7 +46,7 @@
 
 # Default target.
 .PHONY: all
-all: ${GENERATED_LIGSEGMENTATION_PB_H}
+all: ${GENERATED_LIGSEGMENTATION_PB_H} ${GENERATED_LIGSEGMENTATION_TEST_PB_H}
 
 ${GENERATED_DESCPB_BIN} : $(wildcard ${PROTO}/*.proto) | ${GENERATED}
 	${Q}/usr/bin/protoc -I${PROTO} --descriptor_set_out=$@ $(filter-out $<,$^)
@@ -52,12 +62,26 @@
 	--encode=chromiumos.feature_management.api.software.SelectionBundle \
 	device_selection.proto > $@
 
+${GENERATED_SELECTION_SAMPLE_BIN} : ${DEVICES_SELECTION_SAMPLES} | ${GENERATED}
+	${Q}/bin/cat $^ | protoc -I "./proto" \
+	--encode=chromiumos.feature_management.api.software.SelectionSampleBundle \
+	device_selection.proto >$@
+
 ${GENERATED_LIGSEGMENTATION_PB_H} : ${GENERATED_FEATURE_BIN} \
 	                                  ${GENERATED_DEVICE_BIN}
-	${Q}${SRCDIR}/generate_include_file.sh $@ \
+	${Q}${SRCDIR}/generate_include_file.sh \
+		$(GENERATED) \
+		$(GENERATED_LIGSEGMENTATION_PB_H:$(GENERATED)/%=%) \
 	$(foreach f,$^, ${f} $(patsubst ${GENERATED}/%_final.binary, \
 			       protobuf_% ,${f}))
 
+${GENERATED_LIGSEGMENTATION_TEST_PB_H} : ${GENERATED_SELECTION_SAMPLE_BIN}
+	${Q}${SRCDIR}/generate_include_file.sh \
+		$(GENERATED) \
+		$(GENERATED_LIGSEGMENTATION_TEST_PB_H:$(GENERATED)/%=%) \
+		$(foreach f,$^, ${f} $(patsubst ${GENERATED}/%_final.binary, \
+				       protobuf_% ,${f}))
+
 .PHONY: clean
 clean:
 	${Q}/bin/rm -rf ${GENERATED}
diff --git a/devices_test/empty.textproto b/devices_test/empty.textproto
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/devices_test/empty.textproto
diff --git a/generate_include_file.sh b/generate_include_file.sh
index a56d49c..d9f61b5 100755
--- a/generate_include_file.sh
+++ b/generate_include_file.sh
@@ -4,12 +4,14 @@
 #
 # Generate .h containing configuration database for libsegmentation,
 # based on provided binary:
-#$1   : output file
-#$2+2*n : input binary file, generated from the .star configuration file.
-#$3+2*n : name of the variable used by libsegmentation to retrieve the
+#$1     : output dir
+#$2     : output file name
+#$3+2*n : input binary file, generated from the .star configuration file.
+#$4+2*n : name of the variable used by libsegmentation to retrieve the
 #         database.
 
-out=$1
+out="${1}/${2}"
+include_once_flag="$(echo -n "${2^^}" | tr -c "[:alnum:]" "_")"
 
 cat > "${out}" << EOF
 // Copyright 2023 The ChromiumOS Authors
@@ -19,13 +21,13 @@
 // Autogenerated file from feature-management that contains information needed
 // by libsegmentation.
 
-#ifndef LIBSEGMENTATION_FEATURE_MANAGEMENT_PB_H_
-#define LIBSEGMENTATION_FEATURE_MANAGEMENT_PB_H_
+#ifndef LIBSEGMENTATION_${include_once_flag}_
+#define LIBSEGMENTATION_${include_once_flag}_
 
 namespace segmentation {
 EOF
 
-i=2
+i=3
 while [ "${i}" -lt $# ]; do
   in=${!i}
   i=$((i + 1))
diff --git a/proto/device_selection.proto b/proto/device_selection.proto
index 585dae3..e0e2cca 100644
--- a/proto/device_selection.proto
+++ b/proto/device_selection.proto
@@ -27,3 +27,18 @@
 message SelectionBundle {
   repeated DeviceSelection selections = 1;
 }
+
+message DeviceSelectionSample {
+  // The target feature level
+  uint32 expected_feature_level = 1;
+
+  // The target scope
+  Feature.Scope expected_scope = 2;
+
+  // Some sample HWIDs.
+  repeated string sample_hwids = 3;
+}
+
+message SelectionSampleBundle {
+  repeated DeviceSelectionSample selection_samples = 1;
+}