dte test coverage


Directory: ./
File: src/trace.c
Date: 2025-05-08 15:05:54
Exec Total Coverage
Lines: 33 44 75.0%
Functions: 5 6 83.3%
Branches: 12 18 66.7%

Line Branch Exec Source
1 #include <string.h>
2 #include "trace.h"
3 #include "util/array.h"
4 #include "util/debug.h"
5 #include "util/str-util.h"
6 #include "util/xstring.h"
7
8 #if TRACE_LOGGING_ENABLED
9
10 // NOLINTNEXTLINE(*-avoid-non-const-global-variables)
11 static TraceLoggingFlags trace_flags = 0;
12
13 static const char trace_names[][8] = {
14 "command",
15 "input",
16 "output",
17 };
18
19 // Example valid input: "command"
20 286 static TraceLoggingFlags trace_flags_from_single_str(const char *name)
21 {
22
2/2
✓ Branch 0 (6→3) taken 748 times.
✓ Branch 1 (6→7) taken 176 times.
924 for (size_t i = 0; i < ARRAYLEN(trace_names); i++) {
23
2/2
✓ Branch 0 (3→4) taken 110 times.
✓ Branch 1 (3→5) taken 638 times.
748 if (streq(name, trace_names[i])) {
24 110 return 1u << i;
25 }
26 }
27
28 176 LOG_WARNING("unrecognized trace flag: '%s'", name);
29 176 return 0;
30 }
31
32 // Example valid input: "command,status,input"
33 154 static TraceLoggingFlags trace_flags_from_str(const char *flag_str)
34 {
35
3/4
✓ Branch 0 (2→3) taken 154 times.
✗ Branch 1 (2→17) not taken.
✓ Branch 2 (3→4) taken 132 times.
✓ Branch 3 (3→17) taken 22 times.
154 if (!flag_str || flag_str[0] == '\0') {
36 return 0;
37 }
38
39
1/2
✓ Branch 0 (4→5) taken 132 times.
✗ Branch 1 (4→17) not taken.
132 if (streq(flag_str, "all")) {
40 return TRACEFLAGS_ALL;
41 }
42
43 // Copy flag_str into a mutable buffer, so that get_delim_str() can be
44 // used to split (and null-terminate) the comma-delimited substrings
45 132 char buf[128];
46 132 const char *end = memccpy(buf, flag_str, '\0', sizeof(buf));
47
1/2
✗ Branch 0 (6→7) not taken.
✓ Branch 1 (6→9) taken 132 times.
132 if (!end) {
48 LOG_ERROR("trace flags string too long");
49 return 0;
50 }
51
52 132 BUG_ON(end <= buf);
53 132 TraceLoggingFlags flags = 0;
54
55
2/2
✓ Branch 0 (15→12) taken 286 times.
✓ Branch 1 (15→16) taken 132 times.
418 for (size_t pos = 0, len = end - buf - 1; pos < len; ) {
56 286 const char *piece = get_delim_str(buf, &pos, len, ',');
57 286 flags |= trace_flags_from_single_str(piece);
58 }
59
60 132 return flags;
61 }
62
63 22 UNITTEST {
64 22 CHECK_STRING_ARRAY(trace_names);
65 // NOLINTBEGIN(bugprone-assert-side-effect)
66 22 BUG_ON(trace_flags_from_str("output") != TRACEFLAG_OUTPUT);
67 22 BUG_ON(trace_flags_from_str(",x,, ,output,,") != TRACEFLAG_OUTPUT);
68 22 BUG_ON(trace_flags_from_str("command,input") != (TRACEFLAG_COMMAND | TRACEFLAG_INPUT));
69 22 BUG_ON(trace_flags_from_str("command,inpu") != TRACEFLAG_COMMAND);
70 22 BUG_ON(trace_flags_from_str("") != 0);
71 22 BUG_ON(trace_flags_from_str(",") != 0);
72 22 BUG_ON(trace_flags_from_str("a") != 0);
73 // NOLINTEND(bugprone-assert-side-effect)
74 22 }
75
76 bool set_trace_logging_flags(const char *flag_str)
77 {
78 if (!log_level_enabled(LOG_LEVEL_TRACE)) {
79 return false;
80 }
81
82 BUG_ON(trace_flags); // Should only be called once
83 trace_flags = trace_flags_from_str(flag_str);
84 return (trace_flags != 0);
85 }
86
87 // Return true if *any* 1 bits in `flags` are enabled in `trace_flags`
88 18 bool log_trace_enabled(TraceLoggingFlags flags)
89 {
90 18 return !!(trace_flags & flags);
91 }
92
93 18 void log_trace(TraceLoggingFlags flags, const char *file, int line, const char *fmt, ...)
94 {
95
1/2
✓ Branch 0 (2→3) taken 18 times.
✗ Branch 1 (2→4) not taken.
18 if (!log_trace_enabled(flags)) {
96 18 return;
97 }
98 va_list ap;
99 va_start(ap, fmt);
100 log_msgv(LOG_LEVEL_TRACE, file, line, fmt, ap);
101 va_end(ap);
102 }
103
104 #endif // TRACE_LOGGING_ENABLED
105