Comment typo.
[ardour2.git] / tools / sanity_check / main.cpp
blobc1886b295f73048921fe50e8c345d3699d32cb61
1 /*
2 *
3 * program: sanityCheck
4 * file: main.c
5 * author: Todd Naugle
6 * date: 11/17/2010
7 *
8 * Desc: Command line version of the sanity check functions found in jack
9 */
11 #include <algorithm>
12 #include <stdio.h>
13 #include <string>
14 #include <vector>
16 #include "systemtest.h"
19 using namespace std;
21 typedef int (*testfuncPtr) ();
22 typedef int (*testfuncOpPtr) (string);
24 typedef struct
26 string switchText; // ie -option
27 string swOptionText; // option arguments for just this swtich.
28 string descriptionText; // Help Text on what this does
29 string failureText; // What to say when this test fails
30 bool hasOption; // Set true if this switch has option paramters
31 testfuncPtr functionPtr; // Function to call
32 testfuncOpPtr opFunctionPtr; // Function with option string to call
33 string optionArg; // Storage used to hold any options passed in by the user
34 } testRecord;
36 static vector<testRecord> gTestSet;
38 static vector<string> gValidSwitchList;
39 static vector<string> gSwitchDescriptionList;
41 static vector<string> gSwitchesReceived;
43 int
44 ExecuteAll()
46 bool OK = true;
48 OK &= system_user_can_rtprio();
50 if (system_has_frequencyscaling()) {
51 OK &= !system_uses_frequencyscaling();
54 OK &= !(system_memlock_amount() == 0);
56 return OK;
59 int
60 HasGroup(string name)
62 return system_has_group(name.c_str());
65 int
66 IsMemberOfGroup(string name)
68 return system_user_in_group(name.c_str());
71 int
72 CheckFreqScaling()
74 bool OK = true;
76 if (system_has_frequencyscaling()) {
77 OK &= !system_uses_frequencyscaling();
80 return OK;
83 int
84 CheckMemoryLocking()
86 return !(system_memlock_amount() == 0);
89 int
90 PrintUsage()
92 printf("\n");
93 printf(" sanityCheck - A program to verify proper system settings for use with audio applications (Ardour/Jack/Mixbus).\n");
94 printf("\n");
95 printf(" Usage: sanityCheck [OPTIONS]\n");
96 printf("\n");
97 printf(" Options are as follows:\n");
98 printf("\n");
99 printf("\n");
101 vector<testRecord>::iterator itr;
103 for (itr = gTestSet.begin(); itr != gTestSet.end(); ++itr) {
104 printf("%20s %s :\t%s\n", (*itr).switchText.c_str(), (*itr).swOptionText.c_str(), (*itr).descriptionText.c_str());
107 printf("\n");
109 return true;
112 void
113 DefineSwitches()
115 testRecord rec;
117 // Global switches
118 rec.switchText = "-a";
119 rec.swOptionText = "";
120 rec.descriptionText = "Checks for a working RT system. Same as -rt -freqscaling -memlock";
121 rec.failureText = "";
122 rec.hasOption = false;
123 rec.functionPtr = &ExecuteAll;
124 rec.optionArg = "";
125 gTestSet.push_back(rec);
127 rec.switchText = "-h";
128 rec.swOptionText = "";
129 rec.descriptionText = "Print usage";
130 rec.failureText = "";
131 rec.hasOption = false;
132 rec.functionPtr = &PrintUsage;
133 rec.optionArg = "";
134 gTestSet.push_back(rec);
136 // Switches for various tests that can be performed.
137 rec.switchText = "-rt";
138 rec.swOptionText = "";
139 rec.descriptionText = "Verfiy that the user can run tasks with realtime priority";
140 rec.failureText = "";
141 rec.hasOption = false;
142 rec.functionPtr = &system_user_can_rtprio;
143 rec.optionArg = "";
144 gTestSet.push_back(rec);
146 rec.switchText = "-hasrtlimits";
147 rec.swOptionText = "";
148 rec.descriptionText = "Verfiy the system has a limits.conf and the audio group can use realtime";
149 rec.failureText = "";
150 rec.hasOption = false;
151 rec.functionPtr = &system_has_rtprio_limits_conf;
152 rec.optionArg = "";
153 gTestSet.push_back(rec);
155 rec.switchText = "-hasgroup";
156 rec.swOptionText = "<groupname>";
157 rec.descriptionText = "Verfiy that the system has a group named <groupname>";
158 rec.failureText = "";
159 rec.hasOption = true;
160 rec.opFunctionPtr = &HasGroup;
161 rec.optionArg = "";
162 gTestSet.push_back(rec);
164 rec.switchText = "-hasaudiogroup";
165 rec.swOptionText = "";
166 rec.descriptionText = "Verfiy that the system has an audio group (audio or jackuser) defined";
167 rec.failureText = "";
168 rec.hasOption = false;
169 rec.functionPtr = &system_has_audiogroup;
170 rec.optionArg = "";
171 gTestSet.push_back(rec);
173 rec.switchText = "-memberofgroup";
174 rec.swOptionText = "<groupname>";
175 rec.descriptionText = "Verfiy that the user is a member of the group named <groupname>";
176 rec.failureText = "";
177 rec.hasOption = true;
178 rec.opFunctionPtr = &IsMemberOfGroup;
179 rec.optionArg = "";
180 gTestSet.push_back(rec);
182 rec.switchText = "-memberaudiogroup";
183 rec.swOptionText = "";
184 rec.descriptionText = "Verfiy that the user is a member of the audio group (audio or jackuser)";
185 rec.failureText = "";
186 rec.hasOption = false;
187 rec.functionPtr = &system_user_in_audiogroup;
188 rec.optionArg = "";
189 gTestSet.push_back(rec);
191 rec.switchText = "-freqscaling";
192 rec.swOptionText = "";
193 rec.descriptionText = "Check to see if frequency scaling is being used by the CPU";
194 rec.failureText = "";
195 rec.hasOption = false;
196 rec.functionPtr = &CheckFreqScaling;
197 rec.optionArg = "";
198 gTestSet.push_back(rec);
200 rec.switchText = "-memlock";
201 rec.swOptionText = "";
202 rec.descriptionText = "Check to see if the user is able to lock memory";
203 rec.failureText = "";
204 rec.hasOption = false;
205 rec.functionPtr = &CheckMemoryLocking;
206 rec.optionArg = "";
207 gTestSet.push_back(rec);
211 bool
212 ParseSwitches(
213 int argc,
214 char **argv)
216 string tmp;
217 vector<testRecord>::iterator itr;
218 bool OK = true;
219 int i;
221 if (argc == 1) {
222 gSwitchesReceived.push_back("-a");
224 else {
225 for (i = 1; i < argc && OK == true; i++) {
226 tmp = argv[i];
228 for (itr = gTestSet.begin(); itr != gTestSet.end(); ++itr) {
229 if (tmp == (*itr).switchText) {
230 if ((*itr).hasOption == true) {
231 if (++i < argc) {
232 string op = argv[i];
233 if (op[0] == '-') {
234 // reqiured option for this switch is missing
235 --i;
236 OK = false;
237 break;
239 (*itr).optionArg = op;
240 break;
242 else {
243 // reqiured option for this switch is missing
244 --i;
245 OK = false;
246 break;
249 break;
253 if (OK && itr != gTestSet.end()) {
254 // Known option switch found
255 gSwitchesReceived.push_back(tmp);
257 else {
258 // Unknown option
259 OK = false;
264 if (OK) {
265 // All switches are at least valid, now check to make sure they are all valid to
266 // be used together.
268 if (gSwitchesReceived.size() > 1) {
269 // make sure help is not mixed with other options
270 vector<string>::iterator swItr;
271 tmp = "-h";
273 swItr = find(gSwitchesReceived.begin(), gSwitchesReceived.end(), tmp);
275 if (swItr != gSwitchesReceived.end()) {
276 gSwitchesReceived.clear();
277 gSwitchesReceived.push_back("-h");
280 // make sure -a is only used by itself
281 tmp = "-a";
282 swItr = find(gSwitchesReceived.begin(), gSwitchesReceived.end(), tmp);
284 if (swItr != gSwitchesReceived.end()) {
285 gSwitchesReceived.clear();
286 gSwitchesReceived.push_back("-a");
290 return true;
292 else {
293 fprintf(stderr, "\n");
294 fprintf(stderr, "ERROR - Invalid Option: %s\n", (const char *) argv[--i]);
295 fprintf(stderr, "Check syntax\n");
296 PrintUsage();
297 return false;
301 bool
302 Execute()
304 bool OK = true;
305 vector<string>::iterator itr;
306 vector<testRecord>::iterator testItr;
308 for (itr = gSwitchesReceived.begin(); itr != gSwitchesReceived.end(); ++itr) {
309 for (testItr = gTestSet.begin(); testItr != gTestSet.end(); ++testItr) {
310 if ((*itr) == (*testItr).switchText) {
311 break;
315 bool result;
316 if ((*testItr).hasOption) {
317 result = ((*testItr).opFunctionPtr((*testItr).optionArg) != 0);
319 else {
320 result = ((*testItr).functionPtr() != 0);
323 if (result == 0) {
324 // Check for a Failure message and print it if found.
325 if (!(*testItr).failureText.empty()) {
326 printf("\n%s\n", (*testItr).failureText.c_str());
330 OK &= result;
333 return OK;
337 main(
338 int argc,
339 char **argv)
341 int status = 0;
343 DefineSwitches();
345 if (ParseSwitches(argc, argv)) {
346 if (Execute() == false) {
347 printf("\nSanity Check Failed!\n\n");
348 status = -1;
350 else {
351 printf("\nSanity Check OK!\n\n");
354 else {
355 status = -1;
358 return status;