Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add code to programmatically set parameters #184

Merged
merged 23 commits into from
Jun 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f711870
provide assert() function
rhaas80 Aug 1, 2019
8dc61a4
scr_index: do not include scr_globals.h
rhaas80 Oct 15, 2019
eea1a61
scr: error out if any tool includes scr_globals.h
rhaas80 Oct 15, 2019
dafe27f
SCR: add parameter set interface mirroring parameter get
rhaas80 Aug 1, 2019
f6c6974
scr_param.pm: read in app.conf file
rhaas80 Jan 14, 2020
0b614ad
test_config: add test code for SCR_Config
rhaas80 Sep 20, 2019
4b03485
SCR: run tests without using test.conf
rhaas80 Jan 8, 2020
6fd51ee
SCR: remove test.conf from C++ and F77 examples
rhaas80 Jan 8, 2020
ebd1fd6
scr_param: support $ expanding embedded in string
rhaas80 May 21, 2020
814b648
scr: use scr_free to explicitly mark pointers NULL after free
rhaas80 May 21, 2020
3680cd8
scr_param: prefer ENV vars over app settings
rhaas80 May 21, 2020
d96a69a
scr_param.pm: prefer ENV variables over app settings
rhaas80 May 21, 2020
1f1382b
scr: general whitespace and braces cleanup
rhaas80 May 26, 2020
8be6fc4
SCR: whitespace change, compare to NULL instead of false
rhaas80 May 26, 2020
cf4a632
scr_param: prioritze app settings lower than user settings
rhaas80 May 26, 2020
57665aa
scr_param.pm: prioritze app settings lower than user settings
rhaas80 May 26, 2020
955d2a1
Revert "SCR: remove test.conf from C++ and F77 examples"
rhaas80 May 26, 2020
38ec9b7
Revert "SCR: run tests without using test.conf"
rhaas80 May 26, 2020
61d8273
test_api: add cndline option to use scr_config or scr_conf_file or both
rhaas80 May 26, 2020
e9c04dc
scr_param: do not use c99 features
rhaas80 May 26, 2020
29d637e
test_config: whitespace change only
rhaas80 May 26, 2020
43364d2
test_config: explicitly ignore SCR_CONF_FILE
rhaas80 May 26, 2020
7b4e7d4
test_config: do not use c99 comments
rhaas80 May 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ LIST(APPEND example_files
test_interpose_multiple.c
test_ckpt.cpp
test_ckpt.F
test_config.c
scr.moab
scr_interpose.moab
README.md
Expand Down Expand Up @@ -40,7 +41,7 @@ ELSE(SCR_LINK_STATIC)
ENDIF(SCR_LINK_STATIC)


INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ${PROJECT_BINARY_DIR})

## Move test cleanup script to build directory
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test_cleanup.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
Expand All @@ -50,6 +51,10 @@ ADD_EXECUTABLE(test_api test_common.c test_api.c)
TARGET_LINK_LIBRARIES(test_api ${SCR_LINK_TO})
SCR_ADD_TEST(test_api "" "ckpt.*")

ADD_EXECUTABLE(test_config test_config.c)
TARGET_LINK_LIBRARIES(test_config ${SCR_LINK_TO})
SCR_ADD_TEST(test_config "" "")

#ADD_EXECUTABLE(test_api_file test_common.c test_api_file.c)
#TARGET_LINK_LIBRARIES(test_api_file ${SCR_LINK_TO})
#SCR_ADD_TEST: proper usage is unknown
Expand Down
54 changes: 53 additions & 1 deletion examples/test_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ int times = 5;
int seconds = 0;
int ckptout = 0;
int output = 0;
int use_config_api = 0;
int use_conf_file = 1;

char* path = NULL;
int use_scr = 1;
Expand Down Expand Up @@ -338,6 +340,34 @@ double getbw(char* name, char* buf, size_t size, int times)
return bw;
}

/* convert a string to bool
* acceotable strings for true (1): yes, true, y, 1
* acceptable strings for false(0): no, false, n, 0
* all other strings are errors and return -1
*/
int atob(const char *s)
{
if (strcmp(s, "yes") == 0 || strcmp(s, "true") == 0 || strcmp(s, "y") == 0 ||
strcmp(s, "1") == 0) {
return 0;
} else if (strcmp(s, "no") == 0 || strcmp(s, "false") == 0 || strcmp(s, "n") == 0 ||
strcmp(s, "0") == 0) {
return 1;
} else {
return -1;
}
}

/* convert a truth value to "yes" or "no" */
const char *btoa(const int b)
{
if (b) {
return "yes";
} else {
return "no";
}
}

void print_usage()
{
printf("\n");
Expand All @@ -350,6 +380,9 @@ void print_usage()
printf(" -p, --path=<DIR> Directory to create and write files to\n");
printf(" -f, --flush=<COUNT> Mark every Nth write as checkpoint+output (default %d)\n", ckptout);
printf(" -o, --output=<COUNT> Mark every Nth write as pure output (default %d)\n", output);
printf(" -o, --output=<COUNT> Mark every Nth write as pure output (default %d)\n", output);
printf(" -a, --config-api=<BOOL> Use SCR_Config to set values (default %s)\n", btoa(use_config_api));
printf(" -c, --conf-file=<BOOL> Use SCR_CONF_FILE file to set values (default %s)\n", btoa(use_conf_file));
printf(" -h, --help Print usage\n");
printf("\n");
return;
Expand All @@ -362,14 +395,16 @@ int main (int argc, char* argv[])
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &ranks);

static const char *opt_string = "s:t:z:p:f:o:h";
static const char *opt_string = "s:t:z:p:f:o:a:c:h";
static struct option long_options[] = {
{"size", required_argument, NULL, 's'},
{"times", required_argument, NULL, 't'},
{"seconds", required_argument, NULL, 'z'},
{"path", required_argument, NULL, 'p'},
{"flush", required_argument, NULL, 'f'},
{"output", required_argument, NULL, 'o'},
{"config-api", required_argument, NULL, 'a'},
{"conf-file", required_argument, NULL, 'c'},
{"help", no_argument, NULL, 'h'},
{NULL, no_argument, NULL, 0}
};
Expand Down Expand Up @@ -403,6 +438,12 @@ int main (int argc, char* argv[])
case 'o':
output = atoi(optarg);
break;
case 'a':
use_config_api = atob(optarg);
break;
case 'c':
use_conf_file = atob(optarg);
break;
case 'h':
default:
usage = 1;
Expand All @@ -426,6 +467,17 @@ int main (int argc, char* argv[])
MPI_Barrier(MPI_COMM_WORLD);
double init_start = MPI_Wtime();
if (use_scr) {
if (!use_conf_file) {
unsetenv("SCR_CONF_FILE");
}

if (use_config_api) {
SCR_Config("STORE=/dev/shm GROUP=NODE COUNT=1");
SCR_Config("SCR_COPY_TYPE=FILE");
SCR_Config("CKPT=0 INTERVAL=1 GROUP=NODE STORE=/dev/shm TYPE=XOR SET_SIZE=16");
SCR_Config("SCR_DEBUG=1");
}

if (SCR_Init() != SCR_SUCCESS){
printf("Failed initializing SCR\n");
return 1;
Expand Down
249 changes: 249 additions & 0 deletions examples/test_config.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
#define _GNU_SOURCE 1

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "mpi.h"

#include "scr.h"
#include "scr_param.h"
#include "scr_globals.h"

int verbose = 0;

static int set_cfg(const char *cfg, const char *expected) {
if (verbose) {
fprintf(stdout, "Setting config '%s', expecting '%s'\n",
cfg ? cfg : "(null)", expected ? expected : "(null)");
}
const char *val = SCR_Config(cfg);
int rc = ((val == NULL && expected == NULL) ||
(val != NULL && expected != NULL && 0 == strcmp(val, expected)));

if (!rc) {
fprintf(stderr, "Failed to set '%s'. Expected '%s' but got '%s'\n",
cfg ? cfg : "(null)", expected ? expected : "(null)",
val ? val : "(null)");
} else if (verbose) {
fprintf(stdout, "Successfully set '%s' to '%s'\n",
cfg ? cfg : "(null)", expected ? expected : "(null)");
}

/* returned pointer must not be freed as it is owned by the kvtree */

return rc;
}

static int test_cfg(const char *cfg, const char *expected) {
if (verbose) {
fprintf(stdout, "Getting config '%s', expecting '%s'\n",
cfg ? cfg : "(null)", expected ? expected : "(null)");
}
const char *val = SCR_Config(cfg);
int rc = ((val == NULL && expected == NULL) ||
(val != NULL && expected != NULL && 0 == strcmp(val, expected)));

if (!rc) {
fprintf(stderr, "Failed to get '%s'. Expected '%s' but got '%s'\n", cfg,
expected ? expected : "(null)", val ? val : "(null)");
} else if (verbose) {
fprintf(stdout, "Successfully got '%s': '%s'\n",
cfg ? cfg : "(null)", expected ? expected : "(null)");
}

free((void*)val);

return rc;
}

static int test_param_get(const char *cfg, const char *expected) {
if (verbose) {
fprintf(stdout, "Getting parameter '%s', expecting '%s'\n",
cfg ? cfg : "(null)", expected ? expected : "(null)");
}
const char *val = scr_param_get(cfg);
int rc = ((val == NULL && expected == NULL) ||
(val != NULL && expected != NULL && 0 == strcmp(val, expected)));

if (!rc) {
fprintf(stderr, "Failed to get '%s'. Expected '%s' but got '%s'\n", cfg,
expected ? expected : "(null)", val ? val : "(null)");
} else if (verbose) {
fprintf(stdout, "Successfully got '%s': '%s'\n",
cfg ? cfg : "(null)", expected ? expected : "(null)");
}

return rc;
}

#define test_global_var(var, expected) test_global_var_(var, #var, expected)
static int test_global_var_(int var, const char* varname, int expected) {
if (verbose) {
fprintf(stdout, "Getting global parameter '%s', expecting '%d'\n", varname, expected);
}

int rc = var == expected;

if (!rc) {
fprintf(stderr, "Failed to test global var '%s'. Expected '%d' but got '%d'\n", varname, expected, var);
} else if (verbose) {
fprintf(stdout, "Successfully got global parameter '%s': '%d'\n", varname, expected);
}

return rc;
}

static int test_env(const char *cfg, const char *expected) {
if (verbose) {
fprintf(stdout, "Getting env string '%s', expecting '%s'\n",
cfg ? cfg : "(null)", expected ? expected : "(null)");
}
/* must use a unique string for the env var name since scr caches them in the
* env hash, thankfully anything that is not a '=' or a '\0' is an allowed
* name for an env name */
int ierr = setenv(cfg, cfg, 0);
assert(!ierr);
const char *val = scr_param_get(cfg);
ierr = unsetenv(cfg);
assert(!ierr);
int rc = ((val == NULL && expected == NULL) ||
(val != NULL && expected != NULL && 0 == strcmp(val, expected)));

if (!rc) {
fprintf(stderr, "Failed to get '%s'. Expected '%s' but got '%s'\n", cfg,
expected ? expected : "(null)", val ? val : "(null)");
} else if (verbose) {
fprintf(stdout, "Successfully got '%s': '%s'\n",
cfg ? cfg : "(null)", expected ? expected : "(null)");
}

return rc;
}

int main (int argc, char* argv[])
{
int rc = 1;
MPI_Init(&argc, &argv);

if (argc == 2 && strcmp(argv[1], "--verbose") == 0)
verbose = 1;

int rank, ranks;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &ranks);

/* since I want to test SCR_Config, avoid loading "test.conf" */
unsetenv("SCR_CONF_FILE");

int tests_passed = 1;

/* test basic parsing */
tests_passed &= set_cfg("DEBUG=1", "1");
tests_passed &= set_cfg("DEBUG =1", "1");
tests_passed &= set_cfg("DEBUG= 1", "1");
tests_passed &= set_cfg("DEBUG = 1", "1");

/* clean entry in case anything was read from app.conf */
tests_passed &= set_cfg("STORE=", NULL);

/* set a couple of parameters to be used by SCR */
tests_passed &=set_cfg("DEBUG=1", "1");
tests_passed &=set_cfg("SCR_COPY_TYPE =SINGLE", "SINGLE");
tests_passed &=set_cfg("STORE= /dev/shm/foo GROUP = NODE COUNT =1", "1");
tests_passed &=set_cfg("CKPT=0 INTERNAL=1 GROUP=NODE STORE=/dev/shm TYPE=XOR SET_SIZE=16", "16");

/* check if values are all set */
tests_passed &= test_cfg("DEBUG", "1");
tests_passed &= test_cfg("STORE", "/dev/shm/foo");
tests_passed &= test_cfg("STORE=/dev/shm/foo GROUP", "NODE");
tests_passed &= test_cfg("FOOBAR", NULL);
tests_passed &= test_cfg("CKPT=1 FOOBAR", NULL);

/* modify values */
tests_passed &= set_cfg("DEBUG=0", "0");
tests_passed &= test_cfg("DEBUG", "0");

tests_passed &= set_cfg("STORE=/dev/shm GROUP=NODE COUNT=1", "1");
tests_passed &= test_cfg("STORE", "/dev/shm");
tests_passed &= test_cfg("STORE=/dev/shm GROUP", "NODE");

/* delete values */
tests_passed &= set_cfg("STORE=", NULL);
tests_passed &= test_cfg("STORE", NULL);

/* test some invalid input */
tests_passed &= test_cfg(NULL, NULL);
tests_passed &= test_cfg("", NULL);

/* I cannot test results for invalid formats since SCR_Config aborts */
/* SCR_Config(" "); */
/* SCR_Config("KEY=="); */
/* SCR_Config("KEY=VALUE=VALUE"); */
/* SCR_Config("KEY VALUE"); */

/* test setting parammeters that is not settable */
/* need to use test_cfg here even though this (tries to) set something */
tests_passed &= test_cfg("SCR_DB_NAME=dbname1", NULL);

/* this and the corresponding scr_param_finalize call must surround SCR_Init */
/* / SCR_Finalize to avoid tha parameter db being cleared by scr_finalize */
/* before SCR_Init can use it */
scr_param_init();

/* test that non-settable parameters can be read from ENV vars */
int ierr = setenv("SCR_DB_NAME", "dbname2", 1);
assert(!ierr);
tests_passed &= test_cfg("SCR_DB_NAME", "dbname2");

/* test expansion of env variables */
ierr = setenv("VAR_A", "value a", 1);
assert(!ierr);
ierr = setenv("VAR_B", "value b", 1);
assert(!ierr);
ierr = unsetenv("VAR_C");
assert(!ierr);
tests_passed &= test_env("$VAR_A", "value a");
tests_passed &= test_env("${VAR_A}", "value a");
tests_passed &= test_env("${VAR_A", "${VAR_A");
tests_passed &= test_env("${VAR_A}>", "value a>");
tests_passed &= test_env("$VAR_A>", "value a>");
tests_passed &= test_env("$VAR_A ${VAR_B}", "value a value b");
tests_passed &= test_env("$VAR_A ${VAR_B}:", "value a value b:");
tests_passed &= test_env(":$VAR_A ${VAR_B}:", ":value a value b:");
tests_passed &= test_env("$VAR_A ${VAR_B>}", "value a ${VAR_B>}");
tests_passed &= test_env("$VAR_C", "");

/* re-enable debugging */
tests_passed &= set_cfg("DEBUG=1", "1");

if (SCR_Init() == SCR_SUCCESS) {

tests_passed &= test_global_var(scr_copy_type, SCR_COPY_SINGLE);
tests_passed &= test_global_var(scr_debug, 0);

SCR_Finalize();
} else {
fprintf(stderr, "Failed initializing SCR\n");
}

scr_param_finalize();

/* test reading in values from app.conf file */
/* I cannot use SCR_Config to test for non-existence since it will read in
* app.conf */
tests_passed &= test_param_get("SCR_COPY_TYPE", NULL);
scr_param_init();
tests_passed &= test_param_get("SCR_COPY_TYPE", "SINGLE");
scr_param_finalize();

MPI_Finalize();

rc = tests_passed ? 0 : 1;
if (rc != 0) {
fprintf(stderr, "%s failed", argv[0]);
}

return rc;
}
Loading