root/opal/mca/pmix/pmix4x/pmix/test/test_common.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   1 /*
   2  * Copyright (c) 2013-2019 Intel, Inc.  All rights reserved.
   3  * Copyright (c) 2015      Artem Y. Polyakov <artpol84@gmail.com>.
   4  *                         All rights reserved.
   5  * Copyright (c) 2015      Research Organization for Information Science
   6  *                         and Technology (RIST). All rights reserved.
   7  * Copyright (c) 2015-2018 Mellanox Technologies, Inc.
   8  *                         All rights reserved.
   9  * $COPYRIGHT$
  10  *
  11  * Additional copyrights may follow
  12  *
  13  * $HEADER$
  14  *
  15  */
  16 
  17 #ifndef TEST_COMMON_H
  18 #define TEST_COMMON_H
  19 
  20 #include <src/include/pmix_config.h>
  21 #include <pmix_common.h>
  22 
  23 #include <stdio.h>
  24 #include <string.h>
  25 #include <stdlib.h>
  26 #include <unistd.h>
  27 #include <stdint.h>
  28 
  29 #include "src/include/pmix_globals.h"
  30 #include "src/class/pmix_list.h"
  31 #include "src/util/argv.h"
  32 
  33 #define TEST_NAMESPACE "smoky_nspace"
  34 #define TEST_CREDENTIAL "dummy"
  35 
  36 #define PMIX_WAIT_FOR_COMPLETION(m) \
  37     do {                            \
  38         while ((m)) {               \
  39             usleep(10);             \
  40         }                           \
  41     } while(0)
  42 
  43 
  44 /* WARNING: pmix_test_output_prepare is currently not threadsafe!
  45  * fix it once needed!
  46  */
  47 char *pmix_test_output_prepare(const char *fmt,... );
  48 extern int pmix_test_verbose;
  49 extern FILE *file;
  50 
  51 #define STRIPPED_FILE_NAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
  52 
  53 #define TEST_OUTPUT(x) { \
  54     fprintf(file,"==%d== %s:%s: %s\n", getpid(), STRIPPED_FILE_NAME, __func__, \
  55             pmix_test_output_prepare x ); \
  56     fflush(file); \
  57 }
  58 
  59 // Write output without adding anything to it.
  60 // Need for automate tests to receive "OK" string
  61 #define TEST_OUTPUT_CLEAR(x) { \
  62     fprintf(file, "==%d== %s", getpid(), pmix_test_output_prepare x ); \
  63     fflush(file); \
  64 }
  65 
  66 // Always write errors to the stderr
  67 #define TEST_ERROR(x) { \
  68     fprintf(stderr,"==%d== ERROR [%s:%d:%s]: %s\n", getpid(), STRIPPED_FILE_NAME, __LINE__, __func__, \
  69             pmix_test_output_prepare x ); \
  70     fflush(stderr); \
  71 }
  72 
  73 #define TEST_VERBOSE_ON() (pmix_test_verbose = 1)
  74 #define TEST_VERBOSE_GET() (pmix_test_verbose)
  75 
  76 #define TEST_VERBOSE(x) { \
  77     if( pmix_test_verbose ){ \
  78         TEST_OUTPUT(x); \
  79     } \
  80 }
  81 
  82 #define TEST_DEFAULT_TIMEOUT 10
  83 #define MAX_DIGIT_LEN 10
  84 #define TEST_REPLACE_DEFAULT "3:1"
  85 
  86 #define TEST_SET_FILE(prefix, ns_id, rank) { \
  87     char *fname = malloc( strlen(prefix) + MAX_DIGIT_LEN + 2 ); \
  88     sprintf(fname, "%s.%d.%d", prefix, ns_id, rank); \
  89     file = fopen(fname, "w"); \
  90     free(fname); \
  91     if( NULL == file ){ \
  92         fprintf(stderr, "Cannot open file %s for writing!", fname); \
  93         exit(1); \
  94     } \
  95 }
  96 
  97 #define TEST_CLOSE_FILE() { \
  98     if ( stderr != file ) { \
  99         fclose(file); \
 100     } \
 101 }
 102 
 103 typedef struct {
 104     char *binary;
 105     char *np;
 106     char *prefix;
 107     char *nspace;
 108     uint32_t nprocs;
 109     int timeout;
 110     int verbose;
 111     pmix_rank_t rank;
 112     int early_fail;
 113     int test_job_fence;
 114     int collect_bad;
 115     int use_same_keys;
 116     int collect;
 117     int nonblocking;
 118     char *fences;
 119     char *noise;
 120     char *ns_dist;
 121     int ns_size;
 122     int ns_id;
 123     pmix_rank_t base_rank;
 124     int test_publish;
 125     int test_spawn;
 126     int test_connect;
 127     int test_resolve_peers;
 128     int test_error;
 129     char *key_replace;
 130     int test_internal;
 131     char *gds_mode;
 132     int nservers;
 133     uint32_t lsize;
 134 } test_params;
 135 
 136 #define INIT_TEST_PARAMS(params) do { \
 137     params.nprocs = 1;                \
 138     params.verbose = 0;               \
 139     params.rank = PMIX_RANK_UNDEF;    \
 140     params.base_rank = 0;             \
 141     params.early_fail = 0;            \
 142     params.ns_size = -1;              \
 143     params.ns_id = -1;                \
 144     params.timeout = TEST_DEFAULT_TIMEOUT; \
 145     params.test_job_fence = 0;        \
 146     params.use_same_keys = 0;         \
 147     params.collect = 0;               \
 148     params.collect_bad = 0;           \
 149     params.nonblocking = 0;           \
 150     params.test_publish = 0;          \
 151     params.test_spawn = 0;            \
 152     params.test_connect = 0;          \
 153     params.test_resolve_peers = 0;    \
 154     params.binary = NULL;             \
 155     params.np = NULL;                 \
 156     params.prefix = NULL;             \
 157     params.nspace = NULL;             \
 158     params.fences = NULL;             \
 159     params.noise = NULL;              \
 160     params.ns_dist = NULL;            \
 161     params.test_error = 0;            \
 162     params.key_replace = NULL;        \
 163     params.test_internal = 0;         \
 164     params.gds_mode = NULL;           \
 165     params.nservers = 1;              \
 166     params.lsize = 0;                 \
 167 } while (0)
 168 
 169 #define FREE_TEST_PARAMS(params) do { \
 170     if (NULL != params.binary) {      \
 171         free(params.binary);          \
 172     }                                 \
 173     if (NULL != params.np) {          \
 174         free(params.np);              \
 175     }                                 \
 176     if (NULL != params.prefix) {      \
 177         free(params.prefix);          \
 178     }                                 \
 179     if (NULL != params.nspace) {      \
 180         free(params.nspace);          \
 181     }                                 \
 182     if (NULL != params.fences) {      \
 183         free(params.fences);          \
 184     }                                 \
 185     if (NULL != params.noise) {       \
 186         free(params.noise);           \
 187     }                                 \
 188     if (NULL != params.ns_dist) {     \
 189         free(params.ns_dist);         \
 190     }                                 \
 191 } while (0)
 192 
 193 void parse_cmd(int argc, char **argv, test_params *params);
 194 int parse_fence(char *fence_param, int store);
 195 int parse_noise(char *noise_param, int store);
 196 int parse_replace(char *replace_param, int store, int *key_num);
 197 
 198 typedef struct {
 199     pmix_list_item_t super;
 200     int blocking;
 201     int data_exchange;
 202     pmix_list_t *participants;  // list of participants
 203 } fence_desc_t;
 204 PMIX_CLASS_DECLARATION(fence_desc_t);
 205 
 206 typedef struct {
 207     pmix_list_item_t super;
 208     pmix_proc_t proc;
 209 } participant_t;
 210 PMIX_CLASS_DECLARATION(participant_t);
 211 
 212 typedef struct {
 213     pmix_list_item_t super;
 214     int key_idx;
 215 } key_replace_t;
 216 PMIX_CLASS_DECLARATION(key_replace_t);
 217 
 218 extern pmix_list_t test_fences;
 219 extern pmix_list_t *noise_range;
 220 extern pmix_list_t key_replace;
 221 
 222 #define NODE_NAME "node1"
 223 int get_total_ns_number(test_params params);
 224 int get_all_ranks_from_namespace(test_params params, char *nspace, pmix_proc_t **ranks, size_t *nranks);
 225 
 226 typedef struct {
 227     int in_progress;
 228     pmix_value_t *kv;
 229     int status;
 230 } get_cbdata;
 231 
 232 #define SET_KEY(key, fence_num, ind, use_same_keys) do {                                                            \
 233     if (use_same_keys) {                                                                                            \
 234         (void)snprintf(key, sizeof(key)-1, "key-%d", ind);                                                            \
 235     } else {                                                                                                        \
 236         (void)snprintf(key, sizeof(key)-1, "key-f%d:%d", fence_num, ind);                                             \
 237     }                                                                                                               \
 238 } while (0)
 239 
 240 #define PUT(dtype, data, flag, fence_num, ind, use_same_keys) do {                                                  \
 241     char key[50];                                                                                                   \
 242     pmix_value_t value;                                                                                             \
 243     SET_KEY(key, fence_num, ind, use_same_keys);                                                                    \
 244     PMIX_VAL_SET(&value, dtype, data);                                                                              \
 245     TEST_VERBOSE(("%s:%d put key %s", my_nspace, my_rank, key));                                                  \
 246     if (PMIX_SUCCESS != (rc = PMIx_Put(flag, key, &value))) {                                                       \
 247         TEST_ERROR(("%s:%d: PMIx_Put key %s failed: %d", my_nspace, my_rank, key, rc));                             \
 248         rc = PMIX_ERROR;                                                                                            \
 249     }                                                                                                               \
 250     PMIX_VALUE_DESTRUCT(&value);                                                                                    \
 251 } while (0)
 252 
 253 #define GET(dtype, data, ns, r, fence_num, ind, use_same_keys, blocking, ok_notfnd) do {                        \
 254     char key[50];                                                                                                   \
 255     pmix_value_t *val;                                                                                              \
 256     get_cbdata cbdata;                                                                                              \
 257     cbdata.status = PMIX_SUCCESS;                                                                                   \
 258     pmix_proc_t foobar; \
 259     SET_KEY(key, fence_num, ind, use_same_keys);                                                                    \
 260     (void)strncpy(foobar.nspace, ns, PMIX_MAX_NSLEN); \
 261     foobar.rank = r; \
 262     TEST_VERBOSE(("%s:%d want to get from %s:%d key %s", my_nspace, my_rank, ns, r, key));                          \
 263     if (blocking) {                                                                                                 \
 264         if (PMIX_SUCCESS != (rc = PMIx_Get(&foobar, key, NULL, 0, &val))) {                                         \
 265             if( !( (rc == PMIX_ERR_NOT_FOUND || rc == PMIX_ERR_PROC_ENTRY_NOT_FOUND) && ok_notfnd ) ){                                                       \
 266                 TEST_ERROR(("%s:%d: PMIx_Get failed: %d from %s:%d, key %s", my_nspace, my_rank, rc, ns, r, key));  \
 267             }                                                                                                       \
 268             rc = PMIX_ERROR;                                                                                        \
 269         }                                                                                                           \
 270     } else {                                                                                                        \
 271         int count;                                                                                                  \
 272         cbdata.in_progress = 1;                                                                                     \
 273         PMIX_VALUE_CREATE(val, 1);                                                                                  \
 274         cbdata.kv = val;                                                                                            \
 275         if (PMIX_SUCCESS != (rc = PMIx_Get_nb(&foobar, key, NULL, 0, get_cb, (void*)&cbdata))) {                    \
 276             TEST_VERBOSE(("%s:%d: PMIx_Get_nb failed: %d from %s:%d, key=%s", my_nspace, my_rank, rc, ns, r, key)); \
 277             rc = PMIX_ERROR;                                                                                        \
 278         } else {                                                                                                    \
 279             count = 0;                                                                                              \
 280             while(cbdata.in_progress){                                                                              \
 281                 struct timespec ts;                                                                                 \
 282                 ts.tv_sec = 0;                                                                                      \
 283                 ts.tv_nsec = 100;                                                                                   \
 284                 nanosleep(&ts,NULL);                                                                                \
 285                 count++;                                                                                            \
 286             }                                                                                                       \
 287             PMIX_ACQUIRE_OBJECT(&cbdata);                                                                            \
 288         }                                                                                                           \
 289     }                                                                                                               \
 290     if (PMIX_SUCCESS == rc) {                                                                                       \
 291         if( PMIX_SUCCESS != cbdata.status ){                                                                        \
 292             if( !( (cbdata.status == PMIX_ERR_NOT_FOUND || cbdata.status == PMIX_ERR_PROC_ENTRY_NOT_FOUND) && ok_notfnd ) ){                                                       \
 293                 TEST_ERROR(("%s:%d: PMIx_Get_nb failed: %d from %s:%d, key=%s",                                   \
 294                             my_nspace, my_rank, rc, my_nspace, r));                                                 \
 295             }                                                                                                       \
 296             rc = PMIX_ERROR;                                                                                        \
 297         } else if (NULL == val) {                                                                                   \
 298             TEST_VERBOSE(("%s:%d: PMIx_Get returned NULL value", my_nspace, my_rank));                              \
 299             rc = PMIX_ERROR;                                                                                        \
 300         }                                                                                                           \
 301         else if (val->type != PMIX_VAL_TYPE_ ## dtype || PMIX_VAL_CMP(dtype, PMIX_VAL_FIELD_ ## dtype((val)), data)) {  \
 302             TEST_ERROR(("%s:%u: from %s:%d Key %s value or type mismatch,"                                        \
 303                         " want type %d get type %d",                                                                \
 304                         my_nspace, my_rank, ns, r, key, PMIX_VAL_TYPE_ ## dtype, val->type));                    \
 305             rc = PMIX_ERROR;                                                                                        \
 306         }                                                                                                           \
 307     }                                                                                                               \
 308     if (PMIX_SUCCESS == rc) {                                                                                       \
 309         TEST_VERBOSE(("%s:%d: GET OF %s from %s:%d SUCCEEDED", my_nspace, my_rank, key, ns, r));                 \
 310         PMIX_VALUE_RELEASE(val);                                                                                    \
 311     }                                                                                                               \
 312 } while (0)
 313 
 314 #define FENCE(blocking, data_ex, pcs, nprocs) do {                              \
 315     if( blocking ){                                                             \
 316         pmix_info_t *info = NULL;                                               \
 317         size_t ninfo = 0;                                                       \
 318         if (data_ex) {                                                          \
 319             bool value = 1;                                            \
 320             PMIX_INFO_CREATE(info, 1);                                          \
 321             (void)strncpy(info->key, PMIX_COLLECT_DATA, PMIX_MAX_KEYLEN);       \
 322             pmix_value_load(&info->value, &value, PMIX_BOOL);                   \
 323             ninfo = 1;                                                          \
 324         }                                                                       \
 325         rc = PMIx_Fence(pcs, nprocs, info, ninfo);                              \
 326         PMIX_INFO_FREE(info, ninfo);                                            \
 327     } else {                                                                    \
 328         int in_progress = 1, count;                                             \
 329         rc = PMIx_Fence_nb(pcs, nprocs, NULL, 0, release_cb, &in_progress);     \
 330         if ( PMIX_SUCCESS == rc ) {                                             \
 331             count = 0;                                                          \
 332             while( in_progress ){                                               \
 333                 struct timespec ts;                                             \
 334                 ts.tv_sec = 0;                                                  \
 335                 ts.tv_nsec = 100;                                               \
 336                 nanosleep(&ts,NULL);                                            \
 337                 count++;                                                        \
 338             }                                                                   \
 339             TEST_VERBOSE(("PMIx_Fence_nb(barrier,collect): free time: %lfs",    \
 340                             count*100*1E-9));                                   \
 341         }                                                                       \
 342     }                                                                           \
 343     if (PMIX_SUCCESS == rc) {                                                   \
 344         TEST_VERBOSE(("%s:%d: Fence successfully completed",                    \
 345                         my_nspace, my_rank));                                   \
 346     }                                                                           \
 347 } while (0)
 348 
 349 /* Key-Value pair management macros */
 350 // TODO: add all possible types/fields here.
 351 
 352 #define PMIX_VAL_FIELD_int(x)       ((x)->data.integer)
 353 #define PMIX_VAL_FIELD_uint32_t(x)  ((x)->data.uint32)
 354 #define PMIX_VAL_FIELD_uint16_t(x)  ((x)->data.uint16)
 355 #define PMIX_VAL_FIELD_string(x)    ((x)->data.string)
 356 #define PMIX_VAL_FIELD_float(x)     ((x)->data.fval)
 357 #define PMIX_VAL_FIELD_byte(x)      ((x)->data.byte)
 358 #define PMIX_VAL_FIELD_flag(x)      ((x)->data.flag)
 359 
 360 #define PMIX_VAL_TYPE_int      PMIX_INT
 361 #define PMIX_VAL_TYPE_uint32_t PMIX_UINT32
 362 #define PMIX_VAL_TYPE_uint16_t PMIX_UINT16
 363 #define PMIX_VAL_TYPE_string   PMIX_STRING
 364 #define PMIX_VAL_TYPE_float    PMIX_FLOAT
 365 #define PMIX_VAL_TYPE_byte     PMIX_BYTE
 366 #define PMIX_VAL_TYPE_flag     PMIX_BOOL
 367 
 368 #define PMIX_VAL_set_assign(_v, _field, _val )   \
 369     do {                                                            \
 370         (_v)->type = PMIX_VAL_TYPE_ ## _field;                      \
 371         PMIX_VAL_FIELD_ ## _field((_v)) = _val;                     \
 372     } while (0)
 373 
 374 #define PMIX_VAL_set_strdup(_v, _field, _val )       \
 375     do {                                                                \
 376         (_v)->type = PMIX_VAL_TYPE_ ## _field;                          \
 377         PMIX_VAL_FIELD_ ## _field((_v)) = strdup(_val);                 \
 378     } while (0)
 379 
 380 #define PMIX_VAL_SET_int        PMIX_VAL_set_assign
 381 #define PMIX_VAL_SET_uint32_t   PMIX_VAL_set_assign
 382 #define PMIX_VAL_SET_uint16_t   PMIX_VAL_set_assign
 383 #define PMIX_VAL_SET_string     PMIX_VAL_set_strdup
 384 #define PMIX_VAL_SET_float      PMIX_VAL_set_assign
 385 #define PMIX_VAL_SET_byte       PMIX_VAL_set_assign
 386 #define PMIX_VAL_SET_flag       PMIX_VAL_set_assign
 387 
 388 #define PMIX_VAL_SET(_v, _field, _val )   \
 389     PMIX_VAL_SET_ ## _field(_v, _field, _val)
 390 
 391 #define PMIX_VAL_cmp_val(_val1, _val2)      ((_val1) != (_val2))
 392 #define PMIX_VAL_cmp_float(_val1, _val2)    (((_val1)>(_val2))?(((_val1)-(_val2))>0.000001):(((_val2)-(_val1))>0.000001))
 393 #define PMIX_VAL_cmp_ptr(_val1, _val2)      strncmp(_val1, _val2, strlen(_val1)+1)
 394 
 395 #define PMIX_VAL_CMP_int        PMIX_VAL_cmp_val
 396 #define PMIX_VAL_CMP_uint32_t   PMIX_VAL_cmp_val
 397 #define PMIX_VAL_CMP_uint16_t   PMIX_VAL_cmp_val
 398 #define PMIX_VAL_CMP_float      PMIX_VAL_cmp_float
 399 #define PMIX_VAL_CMP_string     PMIX_VAL_cmp_ptr
 400 #define PMIX_VAL_CMP_byte       PMIX_VAL_cmp_val
 401 #define PMIX_VAL_CMP_flag       PMIX_VAL_cmp_val
 402 
 403 #define PMIX_VAL_ASSIGN(_v, _field, _val) \
 404     PMIX_VAL_set_assign(_v, _field, _val)
 405 
 406 #define PMIX_VAL_CMP(_field, _val1, _val2) \
 407     PMIX_VAL_CMP_ ## _field(_val1, _val2)
 408 
 409 #define PMIX_VAL_FREE(_v) \
 410      PMIx_free_value_data(_v)
 411 
 412 #endif // TEST_COMMON_H

/* [<][>][^][v][top][bottom][index][help] */