1 // Copyright (c) 2024 Apple Inc. All rights reserved.
2
3 #pragma once
4
5 #include <stdint.h>
6 #include <stdbool.h>
7 #include <stdarg.h>
8 #include <stdlib.h>
9
10 #include <darwintest.h>
11 #include <darwintest_utils.h>
12
13 static void
sched_policy_speak(char * message)14 sched_policy_speak(char *message)
15 {
16 char *fun_level = getenv("SCHED_FUN");
17 if ((fun_level != NULL) && (strcmp(fun_level, "MAX") == 0)) {
18 char *say_args[] = {"/usr/local/bin/say_anything", "-v", "damon", "-r 210", T_NAME, message, NULL};
19 pid_t pid;
20 dt_launch_tool(&pid, say_args, false, NULL, NULL);
21 }
22 }
23
24 static int sched_policy_passed_subtests = 0;
25
26 static void
sched_policy_final_pass(void)27 sched_policy_final_pass(void)
28 {
29 if (T_FAILCOUNT == 0) {
30 T_PASS(" All %d subtests passed! ", sched_policy_passed_subtests);
31 sched_policy_speak("Passed! Awesome job!");
32 } else {
33 sched_policy_speak("Failed, awww.");
34 }
35 }
36
37 #define PASTER(a, b) a##_##b
38 #define SCHED_POLICY_TEST_NAME(policy_name, test_name) PASTER(policy_name, test_name)
39 #define SCHED_POLICY_T_DECL(test_name, description, ...) T_DECL(SCHED_POLICY_TEST_NAME(TEST_RUNQ_POLICY, test_name), description, T_META_TAG_VM_PREFERRED, ##__VA_ARGS__)
40
41 static unsigned int sched_policy_fails_so_far = 0;
42 static unsigned int sched_policy_passes_so_far = 0;
43 static bool sched_policy_setup_final_pass = false;
44 #define SCHED_PASS_MSG " {️ ️ %d passed expects ✅}"
45 #define SCHED_FAIL_MSG " { %d/%d failed expects ❌}"
46 /* BEGIN IGNORE CODESTYLE */
47 #define SCHED_POLICY_PASS(message, ...) ({ \
48 char expanded_message[256] = ""; \
49 if (T_FAILCOUNT <= sched_policy_fails_so_far) { \
50 strcat(expanded_message, message); \
51 strcat(expanded_message, SCHED_PASS_MSG); \
52 T_PASS(expanded_message, ##__VA_ARGS__, (T_PASSCOUNT - sched_policy_passes_so_far)); \
53 sched_policy_passed_subtests++; \
54 } else { \
55 strcat(expanded_message, message); \
56 strcat(expanded_message, SCHED_FAIL_MSG); \
57 T_FAIL(expanded_message, ##__VA_ARGS__, (T_FAILCOUNT - sched_policy_fails_so_far), \
58 (T_PASSCOUNT - sched_policy_passes_so_far + T_FAILCOUNT - sched_policy_fails_so_far)); \
59 } \
60 sched_policy_fails_so_far = T_FAILCOUNT; \
61 sched_policy_passes_so_far = T_PASSCOUNT; \
62 if (sched_policy_setup_final_pass == false) { \
63 T_ATEND(sched_policy_final_pass); \
64 sched_policy_setup_final_pass = true; \
65 } \
66 })
67 /* END IGNORE CODESTYLE */
68
69 /* Test scenario metadata printing utilities */
70
71 #define MAX_METADATA 64
72 #define MAX_METADATA_STR 256
73 static char metadata_log[MAX_METADATA][MAX_METADATA_STR];
74 static int metadata_ind = 0;
75
76 static void
sched_policy_push_metadata(char * metada_name,uint64_t value)77 sched_policy_push_metadata(char *metada_name, uint64_t value)
78 {
79 snprintf(metadata_log[metadata_ind++], 256, "%s %llu", metada_name, value);
80 }
81
82 static void
sched_policy_pop_metadata(void)83 sched_policy_pop_metadata(void)
84 {
85 T_QUIET; T_EXPECT_GT(metadata_ind, 0, "no metadata left to pop");
86 metadata_ind--;
87 }
88
89 #define MAX_METADA_DUMP_STR (MAX_METADATA_STR * MAX_METADATA)
90 static char metadata_dump[MAX_METADA_DUMP_STR];
91 static char *
sched_policy_dump_metadata(void)92 sched_policy_dump_metadata(void)
93 {
94 metadata_dump[0] = '(';
95 for (int i = 0; i < metadata_ind; i++) {
96 if (i == 0) {
97 snprintf(&metadata_dump[1], MAX_METADATA_STR, metadata_log[i]);
98 } else {
99 strcat(metadata_dump, ", ");
100 strcat(metadata_dump, metadata_log[i]);
101 }
102 }
103 strcat(metadata_dump, ") ️ ");
104 return metadata_dump;
105 }
106