GCC Code Coverage Report


Directory: src/gate/
File: src/gate/system/tests/gateservice_test/gateservice_test.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 0 96 0.0%
Functions: 0 11 0.0%
Branches: 0 30 0.0%

Line Branch Exec Source
1 #include "gate/gatemain.h"
2 #include "gate/console.h"
3 #include "gate/results.h"
4 #include "gate/applications.h"
5 #include "gate/strings.h"
6 #include "gate/processes.h"
7 #include "gate/files.h"
8 #include "gate/environments.h"
9 #include "gate/system/services.h"
10 #include "gate/io/logging.h"
11 #include "gate/debugging.h"
12
13 #if defined(GATE_COMPILER_MSVC) && defined(GATE_LEAK_DETECTION) && defined(GATE_SYS_WIN) && !defined(GATE_SYS_WINCE) && (GATE_ARCH != GATE_ARCH_ARM32) && (GATE_ARCH != GATE_ARCH_ARM64)
14 # include <vld.h>
15 #endif
16
17 static gate_string_t const test_service_name = GATE_STRING_INIT_STATIC("gate_test_service");
18 static gate_string_t const test_service_descr = GATE_STRING_INIT_STATIC("GATE Test Service");
19
20
21 typedef struct service_args_class
22 {
23 gate_bool_t register_svc;
24 gate_bool_t unregister_svc;
25 gate_bool_t start;
26 gate_bool_t stop;
27 gate_bool_t help;
28 } service_args_t;
29
30 static service_args_t service_args;
31
32 static gate_app_option_t service_options[] =
33 {
34 GATE_APP_OPTION_INIT_STATIC("register", GATE_APP_OPTION_TYPE_SWITCH, &service_args.register_svc, "R", "service", "Registers the service process"),
35 GATE_APP_OPTION_INIT_STATIC("unregister", GATE_APP_OPTION_TYPE_SWITCH, &service_args.unregister_svc, "U", "service", "Unregisters the service process"),
36 GATE_APP_OPTION_INIT_STATIC("start", GATE_APP_OPTION_TYPE_SWITCH, &service_args.start, "S", "service", "Starts the service"),
37 GATE_APP_OPTION_INIT_STATIC("stop", GATE_APP_OPTION_TYPE_SWITCH, &service_args.stop, "P", "service", "Stops the service"),
38
39 GATE_APP_OPTION_INIT_STATIC("help", GATE_APP_OPTION_TYPE_SWITCH, &service_args.help, "?", "show_help", "Shows help")
40 };
41
42 static gate_result_t svc_init(gate_appservice_t* service, char const* program, char const* const* arguments, gate_size_t argcount, gate_uintptr_t apphandle)
43 {
44 gate_logger_t const* logger = gate_logger_get();
45 gate_strbuilder_t msg_builder;
46 gate_size_t ndx;
47
48 GATE_UNUSED_ARG(service);
49 GATE_UNUSED_ARG(apphandle);
50
51 gate_strbuilder_create(&msg_builder, 256);
52 gate_strbuilder_append(&msg_builder,
53 GATE_PRINT_CSTR, "INIT: ",
54 GATE_PRINT_CSTR, program,
55 GATE_PRINT_END);
56 for (ndx = 0; ndx != argcount; ++ndx)
57 {
58 gate_strbuilder_append_cstr(&msg_builder, " ");
59 gate_strbuilder_append_cstr(&msg_builder, arguments[ndx]);
60 }
61
62 GATE_LOG_INFO(logger, "svc_init", gate_strbuilder_ptr(&msg_builder, 0));
63
64 gate_strbuilder_release(&msg_builder);
65 return GATE_RESULT_OK;
66 }
67
68 static gate_result_t svc_run(gate_appservice_t* service)
69 {
70 gate_logger_t const* logger = gate_logger_get();
71
72 GATE_UNUSED_ARG(service);
73 GATE_LOG_INFO(logger, "svc_run", "RUN");
74 return GATE_RESULT_OK;
75 }
76
77 static gate_result_t svc_on_signal(gate_appservice_t* service, int appsignal)
78 {
79 gate_logger_t const* logger = gate_logger_get();
80
81 GATE_UNUSED_ARG(service);
82 GATE_LOG_FAIL_INFO(logger, appsignal, 0, "svc_on_signal", "SIGNAL");
83 return GATE_RESULT_OK;
84 }
85
86 static gate_size_t svc_get_servicename(gate_appservice_t* service, char* buffer, gate_size_t bufferlength)
87 {
88 GATE_UNUSED_ARG(service);
89 return gate_str_print_text(buffer, bufferlength, test_service_name.str, test_service_name.length);
90 }
91
92 static gate_result_t svc_on_start(gate_appservice_t* service)
93 {
94 gate_logger_t const* logger = gate_logger_get();
95
96 GATE_UNUSED_ARG(service);
97 GATE_LOG_STATUS(logger, "svc_on_start", "START");
98 return GATE_RESULT_OK;
99 }
100 static gate_result_t svc_on_stop(gate_appservice_t* service)
101 {
102 gate_logger_t const* logger = gate_logger_get();
103
104 GATE_UNUSED_ARG(service);
105 GATE_LOG_STATUS(logger, "svc_on_stop", "STOP");
106 return GATE_RESULT_OK;
107 }
108 static gate_result_t svc_on_pause(gate_appservice_t* service)
109 {
110 gate_logger_t const* logger = gate_logger_get();
111
112 GATE_UNUSED_ARG(service);
113 GATE_LOG_STATUS(logger, "svc_on_pause", "PAUSE");
114 return GATE_RESULT_OK;
115 }
116 static gate_result_t svc_on_continue(gate_appservice_t* service)
117 {
118 gate_logger_t const* logger = gate_logger_get();
119
120 GATE_UNUSED_ARG(service);
121 GATE_LOG_STATUS(logger, "svc_on_continue", "CONTINUE");
122 return GATE_RESULT_OK;
123 }
124 static gate_result_t svc_on_error(gate_appservice_t* service, gate_result_t resultcode, gate_int32_t nativecode, char const* message)
125 {
126 gate_logger_t const* logger = gate_logger_get();
127
128 GATE_UNUSED_ARG(service);
129 GATE_LOG_FAIL_ERROR(logger, resultcode, nativecode, "svc_on_error", message);
130 return GATE_RESULT_OK;
131 }
132
133 static void start_logging(char const* program)
134 {
135 gate_strbuilder_t builder;
136 char file_buffer[GATE_MAX_FILEPATH_LENGTH];
137 gate_string_t file_path = GATE_STRING_INIT_EMPTY;
138 gate_process_id_t pid = 0;
139
140 gate_process_get_id(&pid);
141 gate_strbuilder_create_static(&builder, file_buffer, sizeof(file_buffer), 0);
142 gate_strbuilder_append_cstr(&builder, program);
143 gate_strbuilder_append_cstr(&builder, "_");
144 gate_strbuilder_append_int64(&builder, pid);
145 gate_strbuilder_append_cstr(&builder, ".log");
146 gate_strbuilder_to_string(&builder, &file_path);
147
148 gate_logger_start(&file_path, GATE_LOG_TYPE_DEBUG);
149
150 gate_string_release(&file_path);
151 }
152
153 int gate_main(char const* program, char const* const* arguments, gate_size_t argcount, gate_uintptr_t apphandle)
154 {
155 int ret;
156 gate_appservice_t svc;
157 gate_result_t result = GATE_RESULT_OK;
158 gate_console_t* console = gate_console();
159 gate_stream_t* con = (gate_stream_t*)console;
160 gate_logger_t const* logger = NULL;
161 gate_string_t service_exe = GATE_STRING_INIT_EMPTY;
162 char exebuffer[GATE_MAX_FILEPATH_LENGTH];
163 gate_size_t exebufferlen = sizeof(exebuffer) - 1;
164
165 gate_env_app_executable_str(exebuffer, &exebufferlen);
166 exebuffer[exebufferlen] = 0;
167 GATE_DEBUG_TRACE(exebuffer);
168
169 gate_string_create_static_len(&service_exe, exebuffer, exebufferlen);
170
171 start_logging(exebufferlen ? &exebuffer[0] : program);
172 logger = gate_logger_get();
173
174 gate_app_options_parse_strs(arguments, argcount, service_options, sizeof(service_options) / sizeof(service_options[0]));
175
176 if (service_args.register_svc)
177 {
178 result = gate_service_register(&test_service_name, &service_exe, &test_service_descr, 0, NULL, NULL, NULL);
179 if (GATE_FAILED(result))
180 {
181 return GATE_RESULT_TO_EXITCODE(result);
182 }
183 else
184 {
185 return 0;
186 }
187 }
188 else if (service_args.unregister_svc)
189 {
190 result = gate_service_unregister(&test_service_name, NULL, NULL);
191 if (GATE_FAILED(result))
192 {
193 return GATE_RESULT_TO_EXITCODE(result);
194 }
195 else
196 {
197 return 0;
198 }
199 }
200 else if (service_args.start)
201 {
202 result = gate_service_start(&test_service_name, NULL, NULL);
203 if (GATE_FAILED(result))
204 {
205 return GATE_RESULT_TO_EXITCODE(result);
206 }
207 else
208 {
209 return 0;
210 }
211 }
212 else if (service_args.stop)
213 {
214 result = gate_service_stop(&test_service_name, 0, false, NULL, NULL);
215 if (GATE_FAILED(result))
216 {
217 return GATE_RESULT_TO_EXITCODE(result);
218 }
219 else
220 {
221 return 0;
222 }
223 }
224 else if (service_args.help)
225 {
226 gate_app_options_print(service_options, sizeof(service_options) / sizeof(service_options[0]), con);
227 return 0;
228 }
229
230 GATE_LOG_DEBUG(logger, "main", "service_init()");
231
232 gate_appservice_init(&svc, &svc_init, &svc_run, &svc_on_signal, &svc_get_servicename,
233 &svc_on_start, &svc_on_stop, &svc_on_pause, &svc_on_continue, &svc_on_error);
234
235 GATE_LOG_DEBUG(logger, "main", "service_run");
236 ret = gate_appservice_run(&svc, program, arguments, argcount, apphandle);
237 GATE_LOG_DEBUG(logger, "main", "service_run exit");
238 return ret;
239 }
240