123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- /* See COPYING.txt for the full license governing this code. */
- /**
- * \file harness_argparser.c
- *
- * Source file for functions to parse arguments to the test harness.
- */
- #include <SDL_test.h>
- #include <stdio.h>
- #include <string.h>
- #include "SDL_visualtest_harness_argparser.h"
- #include "SDL_visualtest_rwhelper.h"
- /** Maximum length of one line in the config file */
- #define MAX_CONFIG_LINE_LEN 400
- /** Default value for the timeout after which the SUT is forcefully killed */
- #define DEFAULT_SUT_TIMEOUT (60 * 1000)
- /* String compare s1 and s2 ignoring leading hyphens */
- static int
- StrCaseCmpIgnoreHyphen(char* s1, char* s2)
- {
- /* treat NULL pointer as empty strings */
- if(!s1)
- s1 = "";
- if(!s2)
- s2 = "";
- while(*s1 == '-')
- s1++;
- while(*s2 == '-')
- s2++;
- return SDL_strcasecmp(s1, s2);
- }
- /* parser an argument, updates the state object and returns the number of
- arguments processed; returns -1 on failure */
- static int
- ParseArg(char** argv, int index, SDLVisualTest_HarnessState* state)
- {
- if(!argv || !argv[index] || !state)
- return 0;
- if(StrCaseCmpIgnoreHyphen("sutapp", argv[index]) == 0)
- {
- index++;
- if(!argv[index])
- {
- SDLTest_LogError("Arguments parsing error: Invalid argument for sutapp.");
- return -1;
- }
- SDL_strlcpy(state->sutapp, argv[index], MAX_PATH_LEN);
- SDLTest_Log("SUT Application: %s", state->sutapp);
- return 2;
- }
- else if(StrCaseCmpIgnoreHyphen("output-dir", argv[index]) == 0)
- {
- index++;
- if(!argv[index])
- {
- SDLTest_LogError("Arguments parsing error: Invalid argument for output-dir.");
- return -1;
- }
- SDL_strlcpy(state->output_dir, argv[index], MAX_PATH_LEN);
- SDLTest_Log("Screenshot Output Directory: %s", state->output_dir);
- return 2;
- }
- else if(StrCaseCmpIgnoreHyphen("verify-dir", argv[index]) == 0)
- {
- index++;
- if(!argv[index])
- {
- SDLTest_LogError("Arguments parsing error: Invalid argument for verify-dir.");
- return -1;
- }
- SDL_strlcpy(state->verify_dir, argv[index], MAX_PATH_LEN);
- SDLTest_Log("Screenshot Verification Directory: %s", state->verify_dir);
- return 2;
- }
- else if(StrCaseCmpIgnoreHyphen("sutargs", argv[index]) == 0)
- {
- index++;
- if(!argv[index])
- {
- SDLTest_LogError("Arguments parsing error: Invalid argument for sutargs.");
- return -1;
- }
- SDL_strlcpy(state->sutargs, argv[index], MAX_SUT_ARGS_LEN);
- SDLTest_Log("SUT Arguments: %s", state->sutargs);
- return 2;
- }
- else if(StrCaseCmpIgnoreHyphen("timeout", argv[index]) == 0)
- {
- int hr, min, sec;
- index++;
- if(!argv[index] || SDL_sscanf(argv[index], "%d:%d:%d", &hr, &min, &sec) != 3)
- {
- SDLTest_LogError("Arguments parsing error: Invalid argument for timeout.");
- return -1;
- }
- state->timeout = (((hr * 60) + min) * 60 + sec) * 1000;
- SDLTest_Log("Maximum Timeout for each SUT run: %d milliseconds",
- state->timeout);
- return 2;
- }
- else if(StrCaseCmpIgnoreHyphen("parameter-config", argv[index]) == 0)
- {
- index++;
- if(!argv[index])
- {
- SDLTest_LogError("Arguments parsing error: Invalid argument for parameter-config.");
- return -1;
- }
- SDLTest_Log("SUT Parameters file: %s", argv[index]);
- SDLVisualTest_FreeSUTConfig(&state->sut_config);
- if(!SDLVisualTest_ParseSUTConfig(argv[index], &state->sut_config))
- {
- SDLTest_LogError("Failed to parse SUT parameters file");
- return -1;
- }
- return 2;
- }
- else if(StrCaseCmpIgnoreHyphen("variator", argv[index]) == 0)
- {
- index++;
- if(!argv[index])
- {
- SDLTest_LogError("Arguments parsing error: Invalid argument for variator.");
- return -1;
- }
- SDLTest_Log("Variator: %s", argv[index]);
- if(SDL_strcasecmp("exhaustive", argv[index]) == 0)
- state->variator_type = SDL_VARIATOR_EXHAUSTIVE;
- else if(SDL_strcasecmp("random", argv[index]) == 0)
- state->variator_type = SDL_VARIATOR_RANDOM;
- else
- {
- SDLTest_LogError("Arguments parsing error: Invalid variator name.");
- return -1;
- }
- return 2;
- }
- else if(StrCaseCmpIgnoreHyphen("num-variations", argv[index]) == 0)
- {
- index++;
- if(!argv[index])
- {
- SDLTest_LogError("Arguments parsing error: Invalid argument for num-variations.");
- return -1;
- }
- state->num_variations = SDL_atoi(argv[index]);
- SDLTest_Log("Number of variations to run: %d", state->num_variations);
- if(state->num_variations <= 0)
- {
- SDLTest_LogError("Arguments parsing error: num-variations must be positive.");
- return -1;
- }
- return 2;
- }
- else if(StrCaseCmpIgnoreHyphen("no-launch", argv[index]) == 0)
- {
- state->no_launch = SDL_TRUE;
- SDLTest_Log("SUT will not be launched.");
- return 1;
- }
- else if(StrCaseCmpIgnoreHyphen("action-config", argv[index]) == 0)
- {
- index++;
- if(!argv[index])
- {
- SDLTest_LogError("Arguments parsing error: invalid argument for action-config");
- return -1;
- }
- SDLTest_Log("Action Config file: %s", argv[index]);
- SDLVisualTest_EmptyActionQueue(&state->action_queue);
- if(!SDLVisualTest_ParseActionConfig(argv[index], &state->action_queue))
- {
- SDLTest_LogError("SDLVisualTest_ParseActionConfig() failed");
- return -1;
- }
- return 2;
- }
- else if(StrCaseCmpIgnoreHyphen("config", argv[index]) == 0)
- {
- index++;
- if(!argv[index])
- {
- SDLTest_LogError("Arguments parsing error: invalid argument for config");
- return -1;
- }
- /* do nothing, this option has already been handled */
- return 2;
- }
- return 0;
- }
- /* TODO: Trailing/leading spaces and spaces between equals sign not supported. */
- static int
- ParseConfig(char* file, SDLVisualTest_HarnessState* state)
- {
- SDL_RWops* rw;
- SDLVisualTest_RWHelperBuffer buffer;
- char line[MAX_CONFIG_LINE_LEN];
- rw = SDL_RWFromFile(file, "r");
- if(!rw)
- {
- SDLTest_LogError("SDL_RWFromFile() failed");
- return 0;
- }
- SDLVisualTest_RWHelperResetBuffer(&buffer);
- while(SDLVisualTest_RWHelperReadLine(rw, line, MAX_CONFIG_LINE_LEN,
- &buffer, '#'))
- {
- char** argv;
- int i, num_params;
- /* count number of parameters and replace the trailing newline with 0 */
- num_params = 1;
- for(i = 0; line[i]; i++)
- {
- if(line[i] == '=')
- {
- num_params = 2;
- break;
- }
- }
- /* populate argv */
- argv = (char**)SDL_malloc((num_params + 1) * sizeof(char*));
- if(!argv)
- {
- SDLTest_LogError("malloc() failed.");
- SDL_RWclose(rw);
- return 0;
- }
- argv[num_params] = NULL;
- for(i = 0; i < num_params; i++)
- {
- argv[i] = strtok(i == 0 ? line : NULL, "=");
- }
- if(ParseArg(argv, 0, state) == -1)
- {
- SDLTest_LogError("ParseArg() failed");
- SDL_free(argv);
- SDL_RWclose(rw);
- return 0;
- }
- SDL_free(argv);
- }
- SDL_RWclose(rw);
- if(!state->sutapp[0])
- return 0;
- return 1;
- }
- int
- SDLVisualTest_ParseHarnessArgs(char** argv, SDLVisualTest_HarnessState* state)
- {
- int i;
- SDLTest_Log("Parsing commandline arguments..");
- if(!argv)
- {
- SDLTest_LogError("argv is NULL");
- return 0;
- }
- if(!state)
- {
- SDLTest_LogError("state is NULL");
- return 0;
- }
- /* initialize the state object */
- state->sutargs[0] = '\0';
- state->sutapp[0] = '\0';
- state->output_dir[0] = '\0';
- state->verify_dir[0] = '\0';
- state->timeout = DEFAULT_SUT_TIMEOUT;
- SDL_memset(&state->sut_config, 0, sizeof(SDLVisualTest_SUTConfig));
- SDL_memset(&state->action_queue, 0, sizeof(SDLVisualTest_ActionQueue));
- state->variator_type = SDL_VARIATOR_RANDOM;
- state->num_variations = -1;
- state->no_launch = SDL_FALSE;
- /* parse config file if passed */
- for(i = 0; argv[i]; i++)
- {
- if(StrCaseCmpIgnoreHyphen("config", argv[i]) == 0)
- {
- if(!argv[i + 1])
- {
- SDLTest_Log("Arguments parsing error: invalid argument for config.");
- return 0;
- }
- if(!ParseConfig(argv[i + 1], state))
- {
- SDLTest_LogError("ParseConfig() failed");
- return 0;
- }
- }
- }
- /* parse the arguments */
- for(i = 0; argv[i];)
- {
- int consumed = ParseArg(argv, i, state);
- if(consumed == -1 || consumed == 0)
- {
- SDLTest_LogError("ParseArg() failed");
- return 0;
- }
- i += consumed;
- }
- if(state->variator_type == SDL_VARIATOR_RANDOM && state->num_variations == -1)
- state->num_variations = 1;
- /* check to see if required options have been passed */
- if(!state->sutapp[0])
- {
- SDLTest_LogError("sutapp must be passed.");
- return 0;
- }
- if(!state->sutargs[0] && !state->sut_config.options)
- {
- SDLTest_LogError("Either sutargs or parameter-config must be passed.");
- return 0;
- }
- if(!state->output_dir[0])
- {
- SDL_strlcpy(state->output_dir, "./output", MAX_PATH_LEN);
- }
- if(!state->verify_dir[0])
- {
- SDL_strlcpy(state->verify_dir, "./verify", MAX_PATH_LEN);
- }
- return 1;
- }
- void
- SDLVisualTest_FreeHarnessState(SDLVisualTest_HarnessState* state)
- {
- if(state)
- {
- SDLVisualTest_EmptyActionQueue(&state->action_queue);
- SDLVisualTest_FreeSUTConfig(&state->sut_config);
- }
- }
|