Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F171146087
D59369.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D59369.id.diff
View Options
diff --git a/tools/regression/pmc/Makefile b/tools/regression/pmc/Makefile
--- a/tools/regression/pmc/Makefile
+++ b/tools/regression/pmc/Makefile
@@ -36,10 +36,12 @@
# Kernel ABI tests (need hwpmc(4) loaded and root to run).
KTESTS= pmc_group_test pmc_mux_test pmc_mux_works_test \
- pmc_mux_rotation_test pmc_mux_drain_test pmc_group_fuzz
+ pmc_mux_drain_test pmc_mux_rotation_test pmc_group_fuzz
# Userland-only tests (no PMU access).
-UTESTS= test_libpmcstat_group \
+UTESTS= test_libpmcstat_group test_pmclog_group_inherit_miss \
+ test_pmclog_group_inherit_miss_json \
+ pmcstat_group_inherit_miss_fixture \
pmcstat_mux_warning_shim.so
PMCSTAT?= /usr/sbin/pmcstat
@@ -59,12 +61,6 @@
pmc_mux_works_test: ${.CURDIR}/pmc_mux_works_test.c
${CC} ${CFLAGS} -o ${.TARGET} ${.ALLSRC} -lpmc
-# libpmcstat is INTERNALLIB. It has no .so file installed. Build the
-# parser TU directly into the test binary.
-test_libpmcstat_group: ${.CURDIR}/test_libpmcstat_group.c \
- ${LIBPMCSTAT_SRC}/libpmcstat_group.c
- ${CC} ${CFLAGS} ${LIBPMCSTAT_INC} -o ${.TARGET} ${.ALLSRC} -lpmc
-
pmc_mux_rotation_test: ${.CURDIR}/pmc_mux_rotation_test.c
${CC} ${CFLAGS} -o ${.TARGET} ${.ALLSRC} -lpmc
@@ -77,6 +73,27 @@
pmc_group_fuzz: ${.CURDIR}/pmc_group_fuzz.c
${CC} ${CFLAGS} -o ${.TARGET} ${.ALLSRC} -lpmc
+# libpmcstat is INTERNALLIB. It has no .so file installed. Build the
+# parser TU directly into the test binary.
+test_libpmcstat_group: ${.CURDIR}/test_libpmcstat_group.c \
+ ${LIBPMCSTAT_SRC}/libpmcstat_group.c
+ ${CC} ${CFLAGS} ${LIBPMCSTAT_INC} -o ${.TARGET} ${.ALLSRC} -lpmc
+
+test_pmclog_group_inherit_miss: \
+ ${.CURDIR}/test_pmclog_group_inherit_miss.c \
+ ${LIBPMC_SRC}/pmclog.c
+ ${CC} ${CFLAGS} -Wno-pointer-sign ${LIBPMC_INC} -o ${.TARGET} ${.ALLSRC}
+
+test_pmclog_group_inherit_miss_json: \
+ ${.CURDIR}/test_pmclog_group_inherit_miss_json.cc \
+ ${LIBPMC_SRC}/libpmc_json.cc
+ ${CXX} ${CXXFLAGS} -I${LIBPMC_SRC} ${CURRENT_PMCLOG_INC} \
+ -o ${.TARGET} ${.ALLSRC}
+
+pmcstat_group_inherit_miss_fixture: \
+ ${.CURDIR}/pmcstat_group_inherit_miss_fixture.c
+ ${CC} ${CFLAGS} ${CURRENT_PMCLOG_INC} -o ${.TARGET} ${.ALLSRC}
+
pmcstat_mux_warning_shim.so: ${.CURDIR}/pmcstat_mux_warning_shim.c
${CC} ${CFLAGS} -fPIC -shared ${LIBPMCSTAT_INC} \
-I${SRCROOT}/sys -o ${.TARGET} ${.ALLSRC}
@@ -84,6 +101,11 @@
# These are userland-only checks: parsers and pmcstat warning policy.
check: ${UTESTS}
./test_libpmcstat_group
+ ./test_pmclog_group_inherit_miss
+ ./test_pmclog_group_inherit_miss_json
+ PMCSTAT=${PMCSTAT} \
+ PMCGROUP_MISS_FIXTURE=${.CURDIR}/pmcstat_group_inherit_miss_fixture \
+ sh ${.CURDIR}/pmcstat_group_inherit_miss_test.sh
PMCSTAT=${PMCSTAT} \
PMCSTAT_WARNING_SHIM=${.CURDIR}/pmcstat_mux_warning_shim.so \
sh ${.CURDIR}/pmcstat_mux_warning_test.sh
@@ -102,6 +124,10 @@
./pmc_mux_drain_test
@echo "==> pmc_group_fuzz"
./pmc_group_fuzz 20000
+ @if [ -r ${.CURDIR}/pmcstat_test.sh ]; then \
+ echo "==> pmcstat(8) shell tests"; \
+ sh ${.CURDIR}/pmcstat_test.sh; \
+ fi
clean:
rm -f ${ALL} *.o *.core
diff --git a/tools/regression/pmc/pmcstat_group_inherit_miss_fixture.c b/tools/regression/pmc/pmcstat_group_inherit_miss_fixture.c
new file mode 100644
--- /dev/null
+++ b/tools/regression/pmc/pmcstat_group_inherit_miss_fixture.c
@@ -0,0 +1,39 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Emit one deterministic grouped fork-inheritance miss record.
+ */
+
+#include <sys/types.h>
+#include <sys/pmclog.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#define TEST_PMCID 0x10203040U
+#define TEST_PID 4242U
+#define TEST_TSC 0x0102030405060708ULL
+
+int
+main(void)
+{
+ struct pmclog_pmcgroupinheritmiss record;
+
+ memset(&record, 0, sizeof(record));
+ record.pl_header = (PMCLOG_HEADER_MAGIC << 24) |
+ (PMCLOG_TYPE_PMCGROUPINHERITMISS << 16) | sizeof(record);
+ record.pl_tsc = TEST_TSC;
+ record.pl_pmcid = TEST_PMCID;
+ record.pl_pid = TEST_PID;
+
+ if (fwrite(&record, sizeof(record), 1, stdout) != 1) {
+ perror("fwrite");
+ return (1);
+ }
+ if (fflush(stdout) != 0) {
+ perror("fflush");
+ return (1);
+ }
+ return (0);
+}
diff --git a/tools/regression/pmc/pmcstat_group_inherit_miss_test.sh b/tools/regression/pmc/pmcstat_group_inherit_miss_test.sh
new file mode 100644
--- /dev/null
+++ b/tools/regression/pmc/pmcstat_group_inherit_miss_test.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+set -eu
+
+pmcstat=${PMCSTAT:-/usr/sbin/pmcstat}
+fixture=${PMCGROUP_MISS_FIXTURE:-./pmcstat_group_inherit_miss_fixture}
+tmpdir=$(mktemp -d -t pmcstat_group_miss) || {
+ echo "FAIL: mktemp -d"
+ echo "Results: 0 pass, 1 fail"
+ exit 1
+}
+logfile="${tmpdir}/input.log"
+stdout="${tmpdir}/stdout"
+stderr="${tmpdir}/stderr"
+
+cleanup()
+{
+ rm -f "${logfile}" "${stdout}" "${stderr}"
+ rmdir "${tmpdir}" 2>/dev/null || :
+}
+trap cleanup EXIT
+trap 'exit 1' HUP INT TERM
+
+if ! "${fixture}" >"${logfile}"; then
+ echo "FAIL: fixture failed"
+ echo "Results: 0 pass, 1 fail"
+ exit 1
+fi
+
+set +e
+"${pmcstat}" -R "${logfile}" >"${stdout}" 2>"${stderr}"
+rc=$?
+set -e
+
+if [ "${rc}" -ne 0 ]; then
+ echo "FAIL: pmcstat -R exited ${rc}, expected 0"
+ sed 's/^/stderr: /' "${stderr}"
+ echo "Results: 0 pass, 1 fail"
+ exit 1
+fi
+if [ -s "${stderr}" ]; then
+ echo "FAIL: pmcstat -R wrote unexpected stderr"
+ sed 's/^/stderr: /' "${stderr}"
+ echo "Results: 0 pass, 1 fail"
+ exit 1
+fi
+
+expected='group-inherit-miss 0x10203040 4242 72623859790382856'
+line_count=$(wc -l <"${stdout}" | tr -d ' ')
+actual=$(sed -n '1p' "${stdout}")
+if [ "${line_count}" -ne 1 ] || [ "${actual}" != "${expected}" ]; then
+ printf "FAIL: output='%s', expected='%s'\n" "${actual}" "${expected}"
+ echo "Results: 0 pass, 1 fail"
+ exit 1
+fi
+
+echo "PASS: group-inherit-miss text matches"
+echo "Results: 1 pass, 0 fail"
diff --git a/tools/regression/pmc/test_pmclog_group_inherit_miss.c b/tools/regression/pmc/test_pmclog_group_inherit_miss.c
new file mode 100644
--- /dev/null
+++ b/tools/regression/pmc/test_pmclog_group_inherit_miss.c
@@ -0,0 +1,119 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Regression test for parsing a grouped fork-inheritance miss record.
+ */
+
+#include <sys/types.h>
+
+#include <pmc.h>
+#include <pmclog.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libpmcinternal.h"
+
+#define TEST_RECORD_TYPE 21
+#define TEST_PMCID 0x10203040U
+#define TEST_PID 4242U
+#define TEST_TSC 0x0102030405060708ULL
+
+#define TEST_RECORD_HEADER(type, length) \
+ ((PMCLOG_HEADER_MAGIC << 24) | ((type) << 16) | \
+ ((length) & 0xFFFF))
+
+static int n_pass;
+static int n_fail;
+
+#define CHECK(condition, fmt, ...) do { \
+ if (condition) { \
+ printf("PASS: " fmt "\n", ##__VA_ARGS__); \
+ n_pass++; \
+ } else { \
+ printf("FAIL: " fmt " (line %d)\n", ##__VA_ARGS__, \
+ __LINE__); \
+ n_fail++; \
+ } \
+} while (0)
+
+/*
+ * These are stub event-name helpers.
+ * pmclog.c references these helpers, but this test never calls them.
+ * The stubs let this test link the real parser file without the rest
+ * of libpmc.
+ */
+const char *
+_pmc_name_of_event(enum pmc_event event, enum pmc_cputype cpu)
+{
+
+ (void)event;
+ (void)cpu;
+ return (NULL);
+}
+
+const char *
+pmc_pmu_event_get_by_idx(const char *cpuid, int index)
+{
+
+ (void)cpuid;
+ (void)index;
+ return (NULL);
+}
+
+int
+main(void)
+{
+ struct pmclog_pmcgroupinheritmiss record;
+ struct pmclog_ev event;
+ void *parser;
+ int rc;
+
+ memset(&record, 0, sizeof(record));
+ record.pl_header = TEST_RECORD_HEADER(TEST_RECORD_TYPE, sizeof(record));
+ record.pl_tsc = TEST_TSC;
+ record.pl_pmcid = TEST_PMCID;
+ record.pl_pid = TEST_PID;
+
+ parser = pmclog_open(PMCLOG_FD_NONE);
+ if (parser == NULL) {
+ printf("FAIL: pmclog_open returned NULL\n");
+ return (1);
+ }
+ rc = pmclog_feed(parser, (char *)(void *)&record, sizeof(record));
+ if (rc != 0) {
+ printf("FAIL: pmclog_feed returned %d, expected 0\n", rc);
+ pmclog_close(parser);
+ return (1);
+ }
+
+ memset(&event, 0, sizeof(event));
+ rc = pmclog_read(parser, &event);
+ if (rc != 0) {
+ printf("FAIL: group-inherit-miss parse returned %d state=%d, "
+ "expected 0/%d\n", rc, event.pl_state, PMCLOG_OK);
+ printf("Results: 0 pass, 1 fail\n");
+ pmclog_close(parser);
+ return (1);
+ }
+
+ CHECK(event.pl_state == PMCLOG_OK, "state=%d, expected %d",
+ event.pl_state, PMCLOG_OK);
+ CHECK(PMCLOG_TYPE_PMCGROUPINHERITMISS == TEST_RECORD_TYPE &&
+ event.pl_type == PMCLOG_TYPE_PMCGROUPINHERITMISS,
+ "type=%u enum=%u, expected %u", (u_int)event.pl_type,
+ PMCLOG_TYPE_PMCGROUPINHERITMISS, TEST_RECORD_TYPE);
+ CHECK(event.pl_len == sizeof(record), "length=%d, expected %zu",
+ event.pl_len, sizeof(record));
+ CHECK(event.pl_tsc == TEST_TSC, "TSC=%#jx, expected %#jx",
+ (uintmax_t)event.pl_tsc, (uintmax_t)TEST_TSC);
+ CHECK(event.pl_u.pl_gim.pl_pmcid == TEST_PMCID,
+ "leader pmcid=%#x, expected %#x", event.pl_u.pl_gim.pl_pmcid,
+ TEST_PMCID);
+ CHECK(event.pl_u.pl_gim.pl_pid == TEST_PID,
+ "child pid=%u, expected %u", event.pl_u.pl_gim.pl_pid, TEST_PID);
+
+ pmclog_close(parser);
+ printf("Results: %d pass, %d fail\n", n_pass, n_fail);
+ return (n_fail == 0 ? 0 : 1);
+}
diff --git a/tools/regression/pmc/test_pmclog_group_inherit_miss_json.cc b/tools/regression/pmc/test_pmclog_group_inherit_miss_json.cc
new file mode 100644
--- /dev/null
+++ b/tools/regression/pmc/test_pmclog_group_inherit_miss_json.cc
@@ -0,0 +1,125 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Regression test for JSON conversion of a group-inheritance miss record.
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <string>
+
+#include <pmc.h>
+#include <pmcformat.h>
+#include <pmclog.h>
+
+#include <cerrno>
+#include <cstdio>
+#include <cstring>
+#include <unistd.h>
+
+#define TEST_PMCID 0x10203040U
+#define TEST_PID 4242
+#define TEST_TSC 0x0102030405060708ULL
+
+static ssize_t
+write_full(int fd, const void *buffer, size_t length)
+{
+ const char *cursor;
+ ssize_t nwritten;
+ size_t remaining;
+
+ cursor = static_cast<const char *>(buffer);
+ remaining = length;
+ while (remaining != 0) {
+ nwritten = write(fd, cursor, remaining);
+ if (nwritten < 0) {
+ if (errno == EINTR)
+ continue;
+ return (-1);
+ }
+ cursor += nwritten;
+ remaining -= static_cast<size_t>(nwritten);
+ }
+ return (static_cast<ssize_t>(length));
+}
+
+int
+main()
+{
+ static const char expected[] =
+ "{\"type\": \"pmcgroupinheritmiss\", "
+ "\"tsc\": \"72623859790382856\", "
+ "\"pmcid\": \"0x10203040\", \"pid\": \"4242\"}\n";
+ struct pmclog_ev event;
+ char output[sizeof(expected) + 32];
+ std::string json;
+ pid_t child, waited;
+ ssize_t nread;
+ size_t used;
+ int pipefd[2], status;
+
+ if (pipe(pipefd) != 0) {
+ std::printf("FAIL: pipe: %s\n", std::strerror(errno));
+ return (1);
+ }
+
+ child = fork();
+ if (child < 0) {
+ std::printf("FAIL: fork: %s\n", std::strerror(errno));
+ return (1);
+ }
+ if (child == 0) {
+ (void)close(pipefd[0]);
+ std::memset(&event, 0, sizeof(event));
+ event.pl_type = PMCLOG_TYPE_PMCGROUPINHERITMISS;
+ event.pl_tsc = TEST_TSC;
+ event.pl_u.pl_gim.pl_pmcid = TEST_PMCID;
+ event.pl_u.pl_gim.pl_pid = TEST_PID;
+ json = event_to_json(&event);
+ if (write_full(pipefd[1], json.data(), json.size()) < 0)
+ _exit(2);
+ (void)close(pipefd[1]);
+ _exit(0);
+ }
+
+ (void)close(pipefd[1]);
+ used = 0;
+ while (used < sizeof(output) - 1) {
+ nread = read(pipefd[0], output + used, sizeof(output) - 1 - used);
+ if (nread == 0)
+ break;
+ if (nread < 0) {
+ if (errno == EINTR)
+ continue;
+ std::printf("FAIL: read: %s\n", std::strerror(errno));
+ return (1);
+ }
+ used += static_cast<size_t>(nread);
+ }
+ output[used] = '\0';
+ (void)close(pipefd[0]);
+
+ do {
+ waited = waitpid(child, &status, 0);
+ } while (waited < 0 && errno == EINTR);
+ if (waited != child) {
+ std::printf("FAIL: waitpid: %s\n", std::strerror(errno));
+ return (1);
+ }
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+ std::printf("FAIL: event_to_json child status=%d, expected 0\n",
+ status);
+ std::printf("Results: 0 pass, 1 fail\n");
+ return (1);
+ }
+ if (std::strcmp(output, expected) != 0) {
+ std::printf("FAIL: JSON=%s, expected=%s", output, expected);
+ std::printf("Results: 0 pass, 1 fail\n");
+ return (1);
+ }
+
+ std::printf("PASS: group-inherit-miss JSON matches\n");
+ std::printf("Results: 1 pass, 0 fail\n");
+ return (0);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Sep 10, 12:15 AM (5 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38482108
Default Alt Text
D59369.id.diff (12 KB)
Attached To
Mode
D59369: tools/regression/pmc: test inherit-miss logging
Attached
Detach File
Event Timeline
Log In to Comment