1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include <fwk_macros.h>
9 #include <fwk_status.h>
10 #include <fwk_test.h>
11 #include <fwk_trace.h>
12 
13 #include <assert.h>
14 #include <stddef.h>
15 
16 #define TRACE_ENTRY_COUNT (3)
17 
18 static fwk_trace_count_t current_trace_count = 0;
19 static fwk_trace_count_t expected_trace_entry_count = 0;
20 static fwk_trace_id_t expected_id = 0;
21 
get_trace_count(void)22 static fwk_trace_count_t get_trace_count(void)
23 {
24     return current_trace_count;
25 }
26 
report_trace_entry(const char * filename,const char * func,const unsigned int line,const fwk_trace_id_t id,const fwk_trace_count_t trace_count,const char * msg)27 void report_trace_entry(
28     const char *filename,
29     const char *func,
30     const unsigned int line,
31     const fwk_trace_id_t id,
32     const fwk_trace_count_t trace_count,
33     const char *msg)
34 {
35     assert(expected_id == id);
36     assert(expected_trace_entry_count == trace_count);
37 }
38 
39 static const struct fwk_trace_driver default_driver = {
40     .trace_entry_count = TRACE_ENTRY_COUNT,
41     .get_trace_count = get_trace_count,
42     .report_trace_entry = report_trace_entry,
43 };
44 
45 static struct fwk_trace_driver driver;
46 
fmw_trace_driver(void)47 struct fwk_trace_driver fmw_trace_driver(void)
48 {
49     return driver;
50 }
51 
test_suite_setup(void)52 static int test_suite_setup(void)
53 {
54     return FWK_SUCCESS;
55 }
56 
test_case_setup(void)57 static void test_case_setup(void)
58 {
59     driver = default_driver;
60     fwk_trace_init();
61 }
62 
test_fwk_trace_start_invalid_id(void)63 static void test_fwk_trace_start_invalid_id(void)
64 {
65     int status = FWK_TRACE_START(TRACE_ENTRY_COUNT);
66     assert(status == FWK_E_PARAM);
67     status = FWK_TRACE_START(TRACE_ENTRY_COUNT + 1);
68     assert(status == FWK_E_PARAM);
69     status = FWK_TRACE_START(-1);
70     assert(status == FWK_E_PARAM);
71 }
72 
test_fwk_trace_start_twice(void)73 static void test_fwk_trace_start_twice(void)
74 {
75     int status = FWK_TRACE_START(0);
76     int status2 = FWK_TRACE_START(0);
77     assert(status == FWK_SUCCESS);
78     assert(status2 == FWK_E_STATE);
79 }
80 
test_fwk_trace_start_no_driver(void)81 static void test_fwk_trace_start_no_driver(void)
82 {
83     driver.get_trace_count = NULL;
84     fwk_trace_init();
85     int status = FWK_TRACE_START(0);
86     assert(status == FWK_E_DEVICE);
87 }
88 
test_fwk_trace_finish_invalid_id(void)89 static void test_fwk_trace_finish_invalid_id(void)
90 {
91     int status = FWK_TRACE_FINISH(TRACE_ENTRY_COUNT, "");
92     assert(status == FWK_E_PARAM);
93     status = FWK_TRACE_FINISH(TRACE_ENTRY_COUNT + 1, "");
94     assert(status == FWK_E_PARAM);
95     status = FWK_TRACE_FINISH(-1, "");
96     assert(status == FWK_E_PARAM);
97 }
98 
test_fwk_trace_finish_with_no_start(void)99 static void test_fwk_trace_finish_with_no_start(void)
100 {
101     int status = FWK_TRACE_FINISH(0, "");
102     assert(status == FWK_E_STATE);
103 }
104 
test_fwk_trace_normal_usage(void)105 static void test_fwk_trace_normal_usage(void)
106 {
107     current_trace_count = 1000;
108     int status = FWK_TRACE_START(0);
109     assert(status == FWK_SUCCESS);
110     current_trace_count = 3000;
111     expected_id = 0;
112     expected_trace_entry_count = 2000;
113     status = FWK_TRACE_FINISH(0, "");
114     assert(status == FWK_SUCCESS);
115 }
116 
test_fwk_trace_full_nesting(void)117 static void test_fwk_trace_full_nesting(void)
118 {
119     /*
120      *  ----(1000)------(2000)----(3000)-----(4000)---------->
121      *  ----[s:0]-------[s:1]-----[f:1]------[f:0]----------->
122      */
123     fwk_trace_count_t trace_counts[] = { 1000, 2000, 3000, 4000 };
124     current_trace_count = trace_counts[0];
125     int status = FWK_TRACE_START(0);
126     assert(status == FWK_SUCCESS);
127 
128     current_trace_count = trace_counts[1];
129     status = FWK_TRACE_START(1);
130     assert(status == FWK_SUCCESS);
131     current_trace_count = trace_counts[2];
132     expected_id = 1;
133     expected_trace_entry_count = trace_counts[2] - trace_counts[1];
134     status = FWK_TRACE_FINISH(1, "");
135     assert(status == FWK_SUCCESS);
136 
137     current_trace_count = trace_counts[3];
138     expected_id = 0;
139     expected_trace_entry_count = trace_counts[3] - trace_counts[0];
140     status = FWK_TRACE_FINISH(0, "");
141     assert(status == FWK_SUCCESS);
142 }
143 
test_fwk_trace_partial_nesting(void)144 static void test_fwk_trace_partial_nesting(void)
145 {
146     /*
147      *  ----(1000)------(2000)----(3000)-----(4000)---------->
148      *  ----[s:0]-------[s:1]-----[f:0]------[f:1]----------->
149      */
150     fwk_trace_count_t trace_counts[] = { 1000, 2000, 3000, 4000 };
151     current_trace_count = trace_counts[0];
152     int status = FWK_TRACE_START(0);
153     assert(status == FWK_SUCCESS);
154 
155     current_trace_count = trace_counts[1];
156     status = FWK_TRACE_START(1);
157     assert(status == FWK_SUCCESS);
158 
159     current_trace_count = trace_counts[2];
160     expected_id = 0;
161     expected_trace_entry_count = trace_counts[2] - trace_counts[0];
162     status = FWK_TRACE_FINISH(0, "");
163     assert(status == FWK_SUCCESS);
164 
165     current_trace_count = trace_counts[3];
166     expected_id = 1;
167     expected_trace_entry_count = trace_counts[3] - trace_counts[1];
168     status = FWK_TRACE_FINISH(1, "");
169     assert(status == FWK_SUCCESS);
170 }
171 
172 static const struct fwk_test_case_desc test_case_table[] = {
173     FWK_TEST_CASE(test_fwk_trace_start_invalid_id),
174     FWK_TEST_CASE(test_fwk_trace_start_twice),
175     FWK_TEST_CASE(test_fwk_trace_start_no_driver),
176     FWK_TEST_CASE(test_fwk_trace_finish_invalid_id),
177     FWK_TEST_CASE(test_fwk_trace_finish_with_no_start),
178     FWK_TEST_CASE(test_fwk_trace_normal_usage),
179     FWK_TEST_CASE(test_fwk_trace_full_nesting),
180     FWK_TEST_CASE(test_fwk_trace_partial_nesting),
181 };
182 
183 struct fwk_test_suite_desc test_suite = {
184     .name = "fwk_test",
185 
186     .test_suite_setup = test_suite_setup,
187     .test_case_setup = test_case_setup,
188 
189     .test_case_count = FWK_ARRAY_SIZE(test_case_table),
190     .test_case_table = test_case_table,
191 };
192