xref: /freebsd/contrib/pkgconf/tests/api/test-audit.c (revision 592efe252472a3385acf36b1f49ecf710a7f3d9c)
1*592efe25SPierre Pronchery /*
2*592efe25SPierre Pronchery  * test-audit.c
3*592efe25SPierre Pronchery  * Tests for the public libpkgconf audit API.
4*592efe25SPierre Pronchery  *
5*592efe25SPierre Pronchery  * SPDX-License-Identifier: pkgconf
6*592efe25SPierre Pronchery  *
7*592efe25SPierre Pronchery  * Copyright (c) 2026 pkgconf authors (see AUTHORS).
8*592efe25SPierre Pronchery  *
9*592efe25SPierre Pronchery  * Permission to use, copy, modify, and/or distribute this software for any
10*592efe25SPierre Pronchery  * purpose with or without fee is hereby granted, provided that the above
11*592efe25SPierre Pronchery  * copyright notice and this permission notice appear in all copies.
12*592efe25SPierre Pronchery  *
13*592efe25SPierre Pronchery  * This software is provided 'as is' and without any warranty, express or
14*592efe25SPierre Pronchery  * implied.  In no event shall the authors be liable for any damages arising
15*592efe25SPierre Pronchery  * from the use of this software.
16*592efe25SPierre Pronchery  */
17*592efe25SPierre Pronchery 
18*592efe25SPierre Pronchery #include "test-api.h"
19*592efe25SPierre Pronchery 
20*592efe25SPierre Pronchery /*
21*592efe25SPierre Pronchery  * Read the entire contents of f (from the start) into buf.
22*592efe25SPierre Pronchery  * buf must be large enough; we keep test inputs small.
23*592efe25SPierre Pronchery  */
24*592efe25SPierre Pronchery static void
slurp(FILE * f,char * buf,size_t bufsz)25*592efe25SPierre Pronchery slurp(FILE *f, char *buf, size_t bufsz)
26*592efe25SPierre Pronchery {
27*592efe25SPierre Pronchery 	rewind(f);
28*592efe25SPierre Pronchery 	size_t n = fread(buf, 1, bufsz - 1, f);
29*592efe25SPierre Pronchery 	buf[n] = '\0';
30*592efe25SPierre Pronchery }
31*592efe25SPierre Pronchery 
32*592efe25SPierre Pronchery static void
test_audit_log_no_logfile_is_noop(void)33*592efe25SPierre Pronchery test_audit_log_no_logfile_is_noop(void)
34*592efe25SPierre Pronchery {
35*592efe25SPierre Pronchery 	pkgconf_client_t *client = test_client_new();
36*592efe25SPierre Pronchery 
37*592efe25SPierre Pronchery 	// With no audit log set, logging must be a silent no-op and must not crash.
38*592efe25SPierre Pronchery 	pkgconf_audit_log(client, "should go nowhere\n");
39*592efe25SPierre Pronchery 
40*592efe25SPierre Pronchery 	pkgconf_client_free(client);
41*592efe25SPierre Pronchery }
42*592efe25SPierre Pronchery 
43*592efe25SPierre Pronchery static void
test_audit_set_log_and_write(void)44*592efe25SPierre Pronchery test_audit_set_log_and_write(void)
45*592efe25SPierre Pronchery {
46*592efe25SPierre Pronchery 	pkgconf_client_t *client = test_client_new();
47*592efe25SPierre Pronchery 	FILE *logf = tmpfile();
48*592efe25SPierre Pronchery 	TEST_ASSERT_NONNULL(logf);
49*592efe25SPierre Pronchery 
50*592efe25SPierre Pronchery 	pkgconf_audit_set_log(client, logf);
51*592efe25SPierre Pronchery 	pkgconf_audit_log(client, "hello %s\n", "world");
52*592efe25SPierre Pronchery 
53*592efe25SPierre Pronchery 	char buf[256];
54*592efe25SPierre Pronchery 	slurp(logf, buf, sizeof(buf));
55*592efe25SPierre Pronchery 	TEST_ASSERT_STRCMP_EQ(buf, "hello world\n");
56*592efe25SPierre Pronchery 
57*592efe25SPierre Pronchery 	fclose(logf);
58*592efe25SPierre Pronchery 	pkgconf_client_free(client);
59*592efe25SPierre Pronchery }
60*592efe25SPierre Pronchery 
61*592efe25SPierre Pronchery static void
test_audit_log_multiple_writes(void)62*592efe25SPierre Pronchery test_audit_log_multiple_writes(void)
63*592efe25SPierre Pronchery {
64*592efe25SPierre Pronchery 	pkgconf_client_t *client = test_client_new();
65*592efe25SPierre Pronchery 	FILE *logf = tmpfile();
66*592efe25SPierre Pronchery 	TEST_ASSERT_NONNULL(logf);
67*592efe25SPierre Pronchery 
68*592efe25SPierre Pronchery 	pkgconf_audit_set_log(client, logf);
69*592efe25SPierre Pronchery 	pkgconf_audit_log(client, "first\n");
70*592efe25SPierre Pronchery 	pkgconf_audit_log(client, "second %d\n", 2);
71*592efe25SPierre Pronchery 
72*592efe25SPierre Pronchery 	char buf[256];
73*592efe25SPierre Pronchery 	slurp(logf, buf, sizeof(buf));
74*592efe25SPierre Pronchery 	TEST_ASSERT_STRCMP_EQ(buf, "first\nsecond 2\n");
75*592efe25SPierre Pronchery 
76*592efe25SPierre Pronchery 	fclose(logf);
77*592efe25SPierre Pronchery 	pkgconf_client_free(client);
78*592efe25SPierre Pronchery }
79*592efe25SPierre Pronchery 
80*592efe25SPierre Pronchery static void
test_audit_log_dependency_versionless(void)81*592efe25SPierre Pronchery test_audit_log_dependency_versionless(void)
82*592efe25SPierre Pronchery {
83*592efe25SPierre Pronchery 	pkgconf_client_t *client = test_client_new();
84*592efe25SPierre Pronchery 	FILE *logf = tmpfile();
85*592efe25SPierre Pronchery 	TEST_ASSERT_NONNULL(logf);
86*592efe25SPierre Pronchery 
87*592efe25SPierre Pronchery 	pkgconf_audit_set_log(client, logf);
88*592efe25SPierre Pronchery 
89*592efe25SPierre Pronchery 	// A minimal package: only the fields the logger reads
90*592efe25SPierre Pronchery 	pkgconf_pkg_t pkg = { 0 };
91*592efe25SPierre Pronchery 	pkg.id = (char *) "foo";
92*592efe25SPierre Pronchery 	pkg.version = (char *) "1.2.3";
93*592efe25SPierre Pronchery 
94*592efe25SPierre Pronchery 	/* A dependency with PKGCONF_CMP_ANY and no version: the logger
95*592efe25SPierre Pronchery 	 * should emit only "id [version]", skipping the comparator */
96*592efe25SPierre Pronchery 	pkgconf_dependency_t dep = { 0 };
97*592efe25SPierre Pronchery 	dep.compare = PKGCONF_CMP_ANY;
98*592efe25SPierre Pronchery 	dep.version = NULL;
99*592efe25SPierre Pronchery 
100*592efe25SPierre Pronchery 	pkgconf_audit_log_dependency(client, &pkg, &dep);
101*592efe25SPierre Pronchery 
102*592efe25SPierre Pronchery 	char buf[256];
103*592efe25SPierre Pronchery 	slurp(logf, buf, sizeof(buf));
104*592efe25SPierre Pronchery 	TEST_ASSERT_STRCMP_EQ(buf, "foo [1.2.3]\n");
105*592efe25SPierre Pronchery 
106*592efe25SPierre Pronchery 	fclose(logf);
107*592efe25SPierre Pronchery 	pkgconf_client_free(client);
108*592efe25SPierre Pronchery }
109*592efe25SPierre Pronchery 
110*592efe25SPierre Pronchery static void
test_audit_log_dependency_versioned(void)111*592efe25SPierre Pronchery test_audit_log_dependency_versioned(void)
112*592efe25SPierre Pronchery {
113*592efe25SPierre Pronchery 	pkgconf_client_t *client = test_client_new();
114*592efe25SPierre Pronchery 	FILE *logf = tmpfile();
115*592efe25SPierre Pronchery 	TEST_ASSERT_NONNULL(logf);
116*592efe25SPierre Pronchery 
117*592efe25SPierre Pronchery 	pkgconf_audit_set_log(client, logf);
118*592efe25SPierre Pronchery 
119*592efe25SPierre Pronchery 	pkgconf_pkg_t pkg = { 0 };
120*592efe25SPierre Pronchery 	pkg.id = (char *) "bar";
121*592efe25SPierre Pronchery 	pkg.version = (char *) "2.0";
122*592efe25SPierre Pronchery 
123*592efe25SPierre Pronchery 	/* version set AND compare != ANY: the logger emits the
124*592efe25SPierre Pronchery 	 * comparator and required version between id and [version] */
125*592efe25SPierre Pronchery 	pkgconf_dependency_t dep = { 0 };
126*592efe25SPierre Pronchery 	dep.compare = PKGCONF_CMP_GREATER_THAN_EQUAL;
127*592efe25SPierre Pronchery 	dep.version = (char *) "1.5";
128*592efe25SPierre Pronchery 
129*592efe25SPierre Pronchery 	pkgconf_audit_log_dependency(client, &pkg, &dep);
130*592efe25SPierre Pronchery 
131*592efe25SPierre Pronchery 	char buf[256];
132*592efe25SPierre Pronchery 	slurp(logf, buf, sizeof(buf));
133*592efe25SPierre Pronchery 	TEST_ASSERT_STRCMP_EQ(buf, "bar >= 1.5 [2.0]\n");
134*592efe25SPierre Pronchery 
135*592efe25SPierre Pronchery 	fclose(logf);
136*592efe25SPierre Pronchery 	pkgconf_client_free(client);
137*592efe25SPierre Pronchery }
138*592efe25SPierre Pronchery 
139*592efe25SPierre Pronchery static void
test_audit_log_dependency_no_logfile_is_noop(void)140*592efe25SPierre Pronchery test_audit_log_dependency_no_logfile_is_noop(void)
141*592efe25SPierre Pronchery {
142*592efe25SPierre Pronchery 	pkgconf_client_t *client = test_client_new();
143*592efe25SPierre Pronchery 
144*592efe25SPierre Pronchery 	pkgconf_pkg_t pkg = { 0 };
145*592efe25SPierre Pronchery 	pkg.id = (char *) "foo";
146*592efe25SPierre Pronchery 	pkg.version = (char *) "1.0";
147*592efe25SPierre Pronchery 
148*592efe25SPierre Pronchery 	pkgconf_dependency_t dep = { 0 };
149*592efe25SPierre Pronchery 	dep.compare = PKGCONF_CMP_ANY;
150*592efe25SPierre Pronchery 
151*592efe25SPierre Pronchery 	// No log set: must be a silent no-op
152*592efe25SPierre Pronchery 	pkgconf_audit_log_dependency(client, &pkg, &dep);
153*592efe25SPierre Pronchery 
154*592efe25SPierre Pronchery 	pkgconf_client_free(client);
155*592efe25SPierre Pronchery }
156*592efe25SPierre Pronchery 
157*592efe25SPierre Pronchery int
main(int argc,char * argv[])158*592efe25SPierre Pronchery main(int argc, char *argv[])
159*592efe25SPierre Pronchery {
160*592efe25SPierre Pronchery 	(void) argc;
161*592efe25SPierre Pronchery 	const char *basename = pkgconf_path_find_basename(argv[0]);
162*592efe25SPierre Pronchery 
163*592efe25SPierre Pronchery 	TEST_RUN(basename, test_audit_log_no_logfile_is_noop);
164*592efe25SPierre Pronchery 	TEST_RUN(basename, test_audit_set_log_and_write);
165*592efe25SPierre Pronchery 	TEST_RUN(basename, test_audit_log_multiple_writes);
166*592efe25SPierre Pronchery 	TEST_RUN(basename, test_audit_log_dependency_versionless);
167*592efe25SPierre Pronchery 	TEST_RUN(basename, test_audit_log_dependency_versioned);
168*592efe25SPierre Pronchery 	TEST_RUN(basename, test_audit_log_dependency_no_logfile_is_noop);
169*592efe25SPierre Pronchery 
170*592efe25SPierre Pronchery 	return EXIT_SUCCESS;
171*592efe25SPierre Pronchery }
172