1 /*
2 * Copyright (c) 2004-2010 The Trustees of Indiana University and Indiana
3 * University Research and Technology
4 * Corporation. All rights reserved.
5 * Copyright (c) 2004-2011 The University of Tennessee and The University
6 * of Tennessee Research Foundation. All rights
7 * reserved.
8 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9 * University of Stuttgart. All rights reserved.
10 * Copyright (c) 2004-2005 The Regents of the University of California.
11 * All rights reserved.
12 * Copyright (c) 2006-2013 Los Alamos National Security, LLC.
13 * All rights reserved.
14 * Copyright (c) 2009-2012 Cisco Systems, Inc. All rights reserved.
15 * Copyright (c) 2011 Oak Ridge National Labs. All rights reserved.
16 * Copyright (c) 2013-2019 Intel, Inc. All rights reserved.
17 * Copyright (c) 2015 Research Organization for Information Science
18 * and Technology (RIST). All rights reserved.
19 * Copyright (c) 2015 Mellanox Technologies, Inc.
20 * All rights reserved.
21 * $COPYRIGHT$
22 *
23 * Additional copyrights may follow
24 *
25 * $HEADER$
26 *
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32
33 #include "src/util/pmix_environ.h"
34 #include "src/util/output.h"
35
36 #include "server_callbacks.h"
37 #include "utils.h"
38 #include "src/include/pmix_globals.h"
39
40 bool spawn_wait = false;
41
main(int argc,char ** argv)42 int main(int argc, char **argv)
43 {
44 char **client_env=NULL;
45 char **client_argv=NULL;
46 int rc;
47 struct stat stat_buf;
48 struct timeval tv;
49 double test_start;
50 test_params params;
51 INIT_TEST_PARAMS(params);
52 int test_fail = 0;
53 char *tmp;
54 int ns_nprocs;
55
56 gettimeofday(&tv, NULL);
57 test_start = tv.tv_sec + 1E-6*tv.tv_usec;
58
59 /* smoke test */
60 if (PMIX_SUCCESS != 0) {
61 TEST_ERROR(("ERROR IN COMPUTING CONSTANTS: PMIX_SUCCESS = %d", PMIX_SUCCESS));
62 exit(1);
63 }
64
65 TEST_VERBOSE(("Testing version %s", PMIx_Get_version()));
66
67 parse_cmd(argc, argv, ¶ms);
68 TEST_VERBOSE(("Start PMIx_lite smoke test (timeout is %d)", params.timeout));
69
70 /* verify executable */
71 if( 0 > ( rc = stat(params.binary, &stat_buf) ) ){
72 TEST_ERROR(("Cannot stat() executable \"%s\": %d: %s", params.binary, errno, strerror(errno)));
73 FREE_TEST_PARAMS(params);
74 return 0;
75 } else if( !S_ISREG(stat_buf.st_mode) ){
76 TEST_ERROR(("Client executable \"%s\": is not a regular file", params.binary));
77 FREE_TEST_PARAMS(params);
78 return 0;
79 }else if( !(stat_buf.st_mode & S_IXUSR) ){
80 TEST_ERROR(("Client executable \"%s\": has no executable flag", params.binary));
81 FREE_TEST_PARAMS(params);
82 return 0;
83 }
84
85 /* setup the server library */
86 pmix_info_t info[1];
87 (void)strncpy(info[0].key, PMIX_SOCKET_MODE, PMIX_MAX_KEYLEN);
88 info[0].value.type = PMIX_UINT32;
89 info[0].value.data.uint32 = 0666;
90
91 if (PMIX_SUCCESS != (rc = PMIx_server_init(&mymodule, info, 1))) {
92 TEST_ERROR(("Init failed with error %d", rc));
93 FREE_TEST_PARAMS(params);
94 return rc;
95 }
96 /* register the errhandler */
97 PMIx_Register_event_handler(NULL, 0, NULL, 0,
98 errhandler, errhandler_reg_callbk, NULL);
99
100 cli_init(params.nprocs);
101
102 /* set common argv and env */
103 client_env = pmix_argv_copy(environ);
104 set_client_argv(¶ms, &client_argv);
105
106 tmp = pmix_argv_join(client_argv, ' ');
107 TEST_VERBOSE(("Executing test: %s", tmp));
108 free(tmp);
109
110 int launched = 0;
111 /* set namespaces and fork clients */
112 if (NULL == params.ns_dist) {
113 /* we have a single namespace for all clients */
114 ns_nprocs = params.nprocs;
115 rc = launch_clients(ns_nprocs, params.binary, &client_env, &client_argv);
116 if (PMIX_SUCCESS != rc) {
117 FREE_TEST_PARAMS(params);
118 return rc;
119 }
120 launched += ns_nprocs;
121 } else {
122 char *pch;
123 pch = strtok(params.ns_dist, ":");
124 while (NULL != pch) {
125 ns_nprocs = (int)strtol(pch, NULL, 10);
126 if (params.nprocs < (uint32_t)(launched+ns_nprocs)) {
127 TEST_ERROR(("Total number of processes doesn't correspond number specified by ns_dist parameter."));
128 FREE_TEST_PARAMS(params);
129 return PMIX_ERROR;
130 }
131 if (0 < ns_nprocs) {
132 rc = launch_clients(ns_nprocs, params.binary, &client_env, &client_argv);
133 if (PMIX_SUCCESS != rc) {
134 FREE_TEST_PARAMS(params);
135 return rc;
136 }
137 }
138 pch = strtok (NULL, ":");
139 launched += ns_nprocs;
140 }
141 }
142 if (params.nprocs != (uint32_t)launched) {
143 TEST_ERROR(("Total number of processes doesn't correspond number specified by ns_dist parameter."));
144 cli_kill_all();
145 test_fail = 1;
146 }
147
148 /* hang around until the client(s) finalize */
149 while (!test_terminated()) {
150 // To avoid test hang we want to interrupt the loop each 0.1s
151 double test_current;
152
153 // check if we exceed the max time
154 gettimeofday(&tv, NULL);
155 test_current = tv.tv_sec + 1E-6*tv.tv_usec;
156 if( (test_current - test_start) > params.timeout ){
157 break;
158 }
159 cli_wait_all(0);
160 }
161
162 if( !test_terminated() ){
163 TEST_ERROR(("Test exited by a timeout!"));
164 cli_kill_all();
165 test_fail = 1;
166 }
167
168 if( test_abort ){
169 TEST_ERROR(("Test was aborted!"));
170 /* do not simply kill the clients as that generates
171 * event notifications which these tests then print
172 * out, flooding the log */
173 // cli_kill_all();
174 test_fail = 1;
175 }
176
177 if (0 != params.test_spawn) {
178 PMIX_WAIT_FOR_COMPLETION(spawn_wait);
179 }
180
181 pmix_argv_free(client_argv);
182 pmix_argv_free(client_env);
183
184 /* deregister the errhandler */
185 PMIx_Deregister_event_handler(0, op_callbk, NULL);
186
187 cli_wait_all(1.0);
188
189 /* finalize the server library */
190 if (PMIX_SUCCESS != (rc = PMIx_server_finalize())) {
191 TEST_ERROR(("Finalize failed with error %d", rc));
192 }
193
194 FREE_TEST_PARAMS(params);
195
196 if (0 == test_fail) {
197 TEST_OUTPUT(("Test finished OK!"));
198 }
199
200 return test_fail;
201 }
202