app: add new tests on eal flags
[dpdk.git] / app / test / test_eal_flags.c
1 /*-
2  *   BSD LICENSE
3  * 
4  *   Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  * 
7  *   Redistribution and use in source and binary forms, with or without 
8  *   modification, are permitted provided that the following conditions 
9  *   are met:
10  * 
11  *     * Redistributions of source code must retain the above copyright 
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright 
14  *       notice, this list of conditions and the following disclaimer in 
15  *       the documentation and/or other materials provided with the 
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its 
18  *       contributors may be used to endorse or promote products derived 
19  *       from this software without specific prior written permission.
20  * 
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  * 
33  */
34 #include <stdio.h>
35
36 #include <cmdline_parse.h>
37
38 #include "test.h"
39
40 #ifndef RTE_EXEC_ENV_BAREMETAL
41 #include <string.h>
42 #include <stdarg.h>
43 #include <libgen.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <errno.h>
47 #include <unistd.h>
48 #include <dirent.h>
49 #include <sys/wait.h>
50 #include <sys/file.h>
51
52 #include <rte_debug.h>
53 #include <rte_string_fns.h>
54
55 #include "process.h"
56
57 #define mp_flag "--proc-type=secondary"
58 #define no_hpet "--no-hpet"
59 #define no_huge "--no-huge"
60 #define no_shconf "--no-shconf"
61 #define memtest "memtest"
62 #define memtest1 "memtest1"
63 #define memtest2 "memtest2"
64 #define SOCKET_MEM_STRLEN (RTE_MAX_NUMA_NODES * 10)
65 #define launch_proc(ARGV) process_dup(ARGV, \
66                 sizeof(ARGV)/(sizeof(ARGV[0])), __func__)
67
68 enum hugepage_action {
69         HUGEPAGE_CHECK_EXISTS = 0,
70         HUGEPAGE_CHECK_LOCKED,
71         HUGEPAGE_DELETE,
72         HUGEPAGE_INVALID
73 };
74
75 /* if string contains a hugepage path */
76 static int
77 get_hugepage_path(char * src, int src_len, char * dst, int dst_len)
78 {
79 #define NUM_TOKENS 4
80         char *tokens[NUM_TOKENS];
81
82         /* if we couldn't properly split the string */
83         if (rte_strsplit(src, src_len, tokens, NUM_TOKENS, ' ') < NUM_TOKENS)
84                 return 0;
85
86         if (strncmp(tokens[2], "hugetlbfs", sizeof("hugetlbfs")) == 0) {
87                 rte_snprintf(dst, dst_len, "%s", tokens[1]);
88                 return 1;
89         }
90         return 0;
91 }
92
93 /*
94  * Cycles through hugepage directories and looks for hugepage
95  * files associated with a given prefix. Depending on value of
96  * action, the hugepages are checked if they exist, checked if
97  * they can be locked, or are simply deleted.
98  *
99  * Returns 1 if it finds at least one hugepage matching the action
100  * Returns 0 if no matching hugepages were found
101  * Returns -1 if it encounters an error
102  */
103 static int
104 process_hugefiles(const char * prefix, enum hugepage_action action)
105 {
106         FILE * hugedir_handle = NULL;
107         DIR * hugepage_dir = NULL;
108         struct dirent *dirent = NULL;
109
110         char hugefile_prefix[PATH_MAX] = {0};
111         char hugedir[PATH_MAX] = {0};
112         char line[PATH_MAX] = {0};
113
114         int fd, lck_result, result = 0;
115
116         const int prefix_len = rte_snprintf(hugefile_prefix,
117                         sizeof(hugefile_prefix), "%smap_", prefix);
118         if (prefix_len <= 0 || prefix_len >= (int)sizeof(hugefile_prefix)) {
119                 printf("Error creating hugefile filename prefix\n");
120                 return -1;
121         }
122
123         /* get hugetlbfs mountpoints from /proc/mounts */
124         hugedir_handle = fopen("/proc/mounts", "r");
125
126         if (hugedir_handle == NULL) {
127                 printf("Error parsing /proc/mounts!\n");
128                 return -1;
129         }
130
131         /* read and parse script output */
132         while (fgets(line, sizeof(line), hugedir_handle) != NULL) {
133
134                 /* check if we have a hugepage filesystem path */
135                 if (!get_hugepage_path(line, sizeof(line), hugedir, sizeof(hugedir)))
136                         continue;
137
138                 /* check if directory exists */
139                 if ((hugepage_dir = opendir(hugedir)) == NULL) {
140                         fclose(hugedir_handle);
141                         printf("Error reading %s: %s\n", hugedir, strerror(errno));
142                         return -1;
143                 }
144
145                 while ((dirent = readdir(hugepage_dir)) != NULL) {
146                         if (memcmp(dirent->d_name, hugefile_prefix, prefix_len) != 0)
147                                 continue;
148
149                         switch (action) {
150                         case HUGEPAGE_CHECK_EXISTS:
151                                 {
152                                         /* file exists, return */
153                                         result = 1;
154                                         goto end;
155                                 }
156                                 break;
157                         case HUGEPAGE_DELETE:
158                                 {
159                                         char file_path[PATH_MAX] = {0};
160
161                                         rte_snprintf(file_path, sizeof(file_path),
162                                                 "%s/%s", hugedir, dirent->d_name);
163                                         
164                                         /* remove file */
165                                         if (remove(file_path) < 0) {
166                                                 printf("Error deleting %s - %s!\n",
167                                                                 dirent->d_name, strerror(errno));
168                                                 closedir(hugepage_dir);
169                                                 result = -1;
170                                                 goto end;
171                                         }
172                                         result = 1;
173                                 }
174                                 break;
175                         case HUGEPAGE_CHECK_LOCKED:
176                                 {
177                                         /* try and lock the file */
178                                         fd = openat(dirfd(hugepage_dir), dirent->d_name, O_RDONLY);
179
180                                         /* this shouldn't happen */
181                                         if (fd == -1) {
182                                                 printf("Error opening %s - %s!\n",
183                                                                 dirent->d_name, strerror(errno));
184                                                 closedir(hugepage_dir);
185                                                 result = -1;
186                                                 goto end;
187                                         }
188
189                                         /* non-blocking lock */
190                                         lck_result = flock(fd, LOCK_EX | LOCK_NB);
191
192                                         /* if lock succeeds, there's something wrong */
193                                         if (lck_result != -1) {
194                                                 result = 0;
195
196                                                 /* unlock the resulting lock */
197                                                 flock(fd, LOCK_UN);
198                                                 close(fd);
199                                                 closedir(hugepage_dir);
200                                                 goto end;
201                                         }
202                                         result = 1;
203                                         close(fd);
204                                 }
205                                 break;
206                                 /* shouldn't happen */
207                         default:
208                                 goto end;
209                         } /* switch */
210
211                 } /* read hugepage directory */
212                 closedir(hugepage_dir);
213         } /* read /proc/mounts */
214 end:
215         fclose(hugedir_handle);
216         return result;
217 }
218
219 /*
220  * count the number of "node*" files in /sys/devices/system/node/
221  */
222 static int
223 get_number_of_sockets(void)
224 {
225         struct dirent *dirent = NULL;
226         const char * nodedir = "/sys/devices/system/node/";
227         DIR * dir = NULL;
228         int result = 0;
229
230         /* check if directory exists */
231         if ((dir = opendir(nodedir)) == NULL) {
232                 printf("Error opening %s: %s\n", nodedir, strerror(errno));
233                 return -1;
234         }
235
236         while ((dirent = readdir(dir)) != NULL)
237                 if (strncmp(dirent->d_name, "node", sizeof("node") - 1) == 0)
238                         result++;
239
240         closedir(dir);
241         return result;
242 }
243
244 static char*
245 get_current_prefix(char * prefix, int size)
246 {
247         char path[PATH_MAX] = {0};
248         char buf[PATH_MAX] = {0};
249
250         /* get file for config (fd is always 3) */
251         rte_snprintf(path, sizeof(path), "/proc/self/fd/%d", 3);
252
253         /* return NULL on error */
254         if (readlink(path, buf, sizeof(buf)) == -1)
255                 return NULL;
256
257         /* get the basename */
258         rte_snprintf(buf, sizeof(buf), "%s", basename(buf));
259
260         /* copy string all the way from second char up to start of _config */
261         rte_snprintf(prefix, size, "%.*s",
262                         strnlen(buf, sizeof(buf)) - sizeof("_config"), &buf[1]);
263
264         return prefix;
265 }
266
267 /*
268  * Test that the app doesn't run without invalid blacklist option.
269  * Final test ensures it does run with valid options as sanity check
270  */
271 static int
272 test_invalid_b_flag(void)
273 {
274         char prefix[PATH_MAX], tmp[PATH_MAX];
275         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
276                 printf("Error - unable to get current prefix!\n");
277                 return -1;
278         }
279         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
280
281         const char *blinval[][9] = {
282                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "error"},
283                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0"},
284                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:error:0.1"},
285                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1error"},
286                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "error0:0:0.1"},
287                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1.2"},
288         };
289         /* Test with valid blacklist option */
290         const char *blval[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "FF:09:0B.3"};
291
292         int i;
293
294         for (i = 0; i != sizeof (blinval) / sizeof (blinval[0]); i++) {
295                 if (launch_proc(blinval[i]) == 0) {
296                         printf("Error - process did run ok with invalid "
297                             "blacklist parameter\n");
298                         return -1;
299                 }
300         }
301         if (launch_proc(blval) != 0) {
302                 printf("Error - process did not run ok with valid blacklist value\n");
303                 return -1;
304         }
305         return 0;
306 }
307
308
309 /*
310  * Test that the app doesn't run with invalid -r option.
311  */
312 static int
313 test_invalid_r_flag(void)
314 {
315         char prefix[PATH_MAX], tmp[PATH_MAX];
316         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
317                 printf("Error - unable to get current prefix!\n");
318                 return -1;
319         }
320         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
321
322         const char *rinval[][9] = {
323                         {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "error"},
324                         {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "0"},
325                         {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "-1"},
326                         {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "17"},
327         };
328         /* Test with valid blacklist option */
329         const char *rval[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "16"};
330
331         int i;
332
333         for (i = 0; i != sizeof (rinval) / sizeof (rinval[0]); i++) {
334                 if (launch_proc(rinval[i]) == 0) {
335                         printf("Error - process did run ok with invalid "
336                             "-r (rank) parameter\n");
337                         return -1;
338                 }
339         }
340         if (launch_proc(rval) != 0) {
341                 printf("Error - process did not run ok with valid -r (rank) value\n");
342                 return -1;
343         }
344         return 0;
345 }
346
347 /*
348  * Test that the app doesn't run without the coremask flag. In all cases
349  * should give an error and fail to run
350  */
351 static int
352 test_missing_c_flag(void)
353 {
354         char prefix[PATH_MAX], tmp[PATH_MAX];
355         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
356                 printf("Error - unable to get current prefix!\n");
357                 return -1;
358         }
359         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
360
361         /* -c flag but no coremask value */
362         const char *argv1[] = { prgname, prefix, mp_flag, "-n", "3", "-c"};
363         /* No -c flag at all */
364         const char *argv2[] = { prgname, prefix, mp_flag, "-n", "3"};
365         /* bad coremask value */
366         const char *argv3[] = { prgname, prefix, mp_flag, "-n", "3", "-c", "error" };
367         /* sanity check of tests - valid coremask value */
368         const char *argv4[] = { prgname, prefix, mp_flag, "-n", "3", "-c", "1" };
369
370         if (launch_proc(argv1) == 0
371                         || launch_proc(argv2) == 0
372                         || launch_proc(argv3) == 0) {
373                 printf("Error - process ran without error when missing -c flag\n");
374                 return -1;
375         }
376         if (launch_proc(argv4) != 0) {
377                 printf("Error - process did not run ok with valid coremask value\n");
378                 return -1;
379         }
380         return 0;
381 }
382
383 /*
384  * Test that the app doesn't run without the -n flag. In all cases
385  * should give an error and fail to run.
386  * Since -n is not compulsory for MP, we instead use --no-huge and --no-shconf
387  * flags.
388  */
389 static int
390 test_missing_n_flag(void)
391 {
392         char prefix[PATH_MAX], tmp[PATH_MAX];
393         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
394                 printf("Error - unable to get current prefix!\n");
395                 return -1;
396         }
397         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
398
399         /* -n flag but no value */
400         const char *argv1[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n"};
401         /* No -n flag at all */
402         const char *argv2[] = { prgname, prefix, no_huge, no_shconf, "-c", "1"};
403         /* bad numeric value */
404         const char *argv3[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "e" };
405         /* out-of-range value */
406         const char *argv4[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "9" };
407         /* sanity test - check with good value */
408         const char *argv5[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "2" };
409
410         if (launch_proc(argv1) == 0
411                         || launch_proc(argv2) == 0
412                         || launch_proc(argv3) == 0
413                         || launch_proc(argv4) == 0) {
414                 printf("Error - process ran without error when missing -n flag\n");
415                 return -1;
416         }
417         if (launch_proc(argv5) != 0) {
418                 printf("Error - process did not run ok with valid num-channel value\n");
419                 return -1;
420         }
421         return 0;
422 }
423
424 /*
425  * Test that the app runs with HPET, and without HPET
426  */
427 static int
428 test_no_hpet_flag(void)
429 {
430         char prefix[PATH_MAX], tmp[PATH_MAX];
431         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
432                 printf("Error - unable to get current prefix!\n");
433                 return -1;
434         }
435         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
436
437         /* With --no-hpet */
438         const char *argv1[] = {prgname, prefix, mp_flag, no_hpet, "-c", "1", "-n", "2"};
439         /* Without --no-hpet */
440         const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-n", "2"};
441
442         if (launch_proc(argv1) != 0) {
443                 printf("Error - process did not run ok with --no-hpet flag\n");
444                 return -1;
445         }
446         if (launch_proc(argv2) != 0) {
447                 printf("Error - process did not run ok without --no-hpet flag\n");
448                 return -1;
449         }
450         return 0;
451 }
452
453 /*
454  * Test that the app runs with --no-huge and doesn't run when either
455  * -m or --socket-mem are specified with --no-huge.
456  */
457 static int
458 test_no_huge_flag(void)
459 {
460         char prefix[PATH_MAX], tmp[PATH_MAX];
461         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
462                 printf("Error - unable to get current prefix!\n");
463                 return -1;
464         }
465         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
466
467         /* With --no-huge */
468         const char *argv1[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
469                         "--file-prefix=nohuge"};
470         /* With --no-huge and -m */
471         const char *argv2[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2", "-m", "2",
472                         "--file-prefix=nohuge"};
473         /* With --no-huge and --socket-mem */
474         const char *argv3[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
475                         "--socket-mem=2", "--file-prefix=nohuge"};
476         /* With --no-huge, -m and --socket-mem */
477         const char *argv4[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
478                         "-m", "2", "--socket-mem=2", "--file-prefix=nohuge"};
479
480         if (launch_proc(argv1) != 0) {
481                 printf("Error - process did not run ok with --no-huge flag\n");
482                 return -1;
483         }
484         if (launch_proc(argv2) == 0) {
485                 printf("Error - process run ok with --no-huge and -m flags\n");
486                 return -1;
487         }
488         if (launch_proc(argv3) == 0) {
489                 printf("Error - process run ok with --no-huge and --socket-mem "
490                                 "flags\n");
491                 return -1;
492         }
493         if (launch_proc(argv4) == 0) {
494                 printf("Error - process run ok with --no-huge, -m and "
495                                 "--socket-mem flags\n");
496                 return -1;
497         }
498         return 0;
499 }
500
501 static int
502 test_misc_flags(void)
503 {
504         char prefix[PATH_MAX], tmp[PATH_MAX];
505         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
506                 printf("Error - unable to get current prefix!\n");
507                 return -1;
508         }
509         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
510
511         /* check that some general flags don't prevent things from working.
512          * All cases, apart from the first, app should run.
513          * No futher testing of output done.
514          */
515         /* sanity check - failure with invalid option */
516         const char *argv0[] = {prgname, prefix, mp_flag, "-c", "1", "--invalid-opt"};
517
518         /* With --no-pci */
519         const char *argv1[] = {prgname, prefix, mp_flag, "-c", "1", "--no-pci"};
520         /* With -v */
521         const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-v"};
522
523         if (launch_proc(argv0) == 0) {
524                 printf("Error - process ran ok with invalid flag\n");
525                 return -1;
526         }
527         if (launch_proc(argv1) != 0) {
528                 printf("Error - process did not run ok with --no-pci flag\n");
529                 return -1;
530         }
531         if (launch_proc(argv2) != 0) {
532                 printf("Error - process did not run ok with -v flag\n");
533                 return -1;
534         }
535         return 0;
536 }
537
538 static int
539 test_file_prefix(void)
540 {
541         /*
542          * 1. check if current process hugefiles are locked
543          * 2. try to run secondary process without a corresponding primary process
544          * (while failing to run, it will also remove any unused hugepage files)
545          * 3. check if current process hugefiles are still in place and are locked
546          * 4. run a primary process with memtest1 prefix
547          * 5. check if memtest1 hugefiles are created
548          * 6. run a primary process with memtest2 prefix
549          * 7. check that only memtest2 hugefiles are present in the hugedir
550          */
551
552         /* this should fail unless the test itself is run with "memtest" prefix */
553         const char *argv0[] = {prgname, mp_flag, "-c", "1", "-n", "2", "-m", "2",
554                         "--file-prefix=" memtest };
555
556         /* primary process with memtest1 */
557         const char *argv1[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
558                                 "--file-prefix=" memtest1 };
559
560         /* primary process with memtest2 */
561         const char *argv2[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
562                                 "--file-prefix=" memtest2 };
563
564         char prefix[32];
565         if (get_current_prefix(prefix, sizeof(prefix)) == NULL) {
566                 printf("Error - unable to get current prefix!\n");
567                 return -1;
568         }
569
570         /* check if files for current prefix are present */
571         if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
572                 printf("Error - hugepage files for %s were not created!\n", prefix);
573                 return -1;
574         }
575
576         /* checks if files for current prefix are locked */
577         if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) {
578                 printf("Error - hugepages for current process aren't locked!\n");
579                 return -1;
580         }
581
582         /* check if files for secondary process are present */
583         if (process_hugefiles(memtest, HUGEPAGE_CHECK_EXISTS) == 1) {
584                 /* check if they are not locked */
585                 if (process_hugefiles(memtest, HUGEPAGE_CHECK_LOCKED) == 1) {
586                         printf("Error - hugepages for current process are locked!\n");
587                         return -1;
588                 }
589                 /* they aren't locked, delete them */
590                 else {
591                         if (process_hugefiles(memtest, HUGEPAGE_DELETE) != 1) {
592                                 printf("Error - deleting hugepages failed!\n");
593                                 return -1;
594                         }
595                 }
596         }
597
598         if (launch_proc(argv0) == 0) {
599                 printf("Error - secondary process ran ok without primary process\n");
600                 return -1;
601         }
602
603         /* check if files for current prefix are present */
604         if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
605                 printf("Error - hugepage files for %s were not created!\n", prefix);
606                 return -1;
607         }
608
609         /* checks if files for current prefix are locked */
610         if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) {
611                 printf("Error - hugepages for current process aren't locked!\n");
612                 return -1;
613         }
614
615         if (launch_proc(argv1) != 0) {
616                 printf("Error - failed to run with --file-prefix=%s\n", memtest);
617                 return -1;
618         }
619
620         /* check if memtest1_map0 is present */
621         if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 1) {
622                 printf("Error - hugepage files for %s were not created!\n", memtest1);
623                 return -1;
624         }
625
626         if (launch_proc(argv2) != 0) {
627                 printf("Error - failed to run with --file-prefix=%s\n", memtest2);
628                 return -1;
629         }
630
631         /* check if hugefiles for memtest2 are present */
632         if (process_hugefiles(memtest2, HUGEPAGE_CHECK_EXISTS) != 1) {
633                 printf("Error - hugepage files for %s were not created!\n", memtest2);
634                 return -1;
635         }
636
637         /* check if hugefiles for memtest1 are present */
638         if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
639                 printf("Error - hugepage files for %s were not deleted!\n", memtest1);
640                 return -1;
641         }
642
643         return 0;
644 }
645
646 /*
647  * Tests for correct handling of -m and --socket-mem flags
648  */
649 static int
650 test_memory_flags(void)
651 {
652         char prefix[PATH_MAX], tmp[PATH_MAX];
653         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
654                 printf("Error - unable to get current prefix!\n");
655                 return -1;
656         }
657         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
658
659         /* valid -m flag */
660         const char *argv0[] = {prgname, "-c", "10", "-n", "2",
661                         "--file-prefix=" memtest, "-m", "2"};
662
663         /* valid -m flag and mp flag */
664         const char *argv1[] = {prgname, prefix, mp_flag, "-c", "10",
665                         "-n", "2", "-m", "2"};
666
667         /* invalid (zero) --socket-mem flag */
668         const char *argv2[] = {prgname, "-c", "10", "-n", "2",
669                         "--file-prefix=" memtest, "--socket-mem=0,0,0,0"};
670
671         /* invalid (incomplete) --socket-mem flag */
672         const char *argv3[] = {prgname, "-c", "10", "-n", "2",
673                         "--file-prefix=" memtest, "--socket-mem=2,2,"};
674
675         /* invalid (mixed with invalid data) --socket-mem flag */
676         const char *argv4[] = {prgname, "-c", "10", "-n", "2",
677                         "--file-prefix=" memtest, "--socket-mem=2,2,Fred"};
678
679         /* invalid (with numeric value as last character) --socket-mem flag */
680         const char *argv5[] = {prgname, "-c", "10", "-n", "2",
681                         "--file-prefix=" memtest, "--socket-mem=2,2,Fred0"};
682
683         /* invalid (with empty socket) --socket-mem flag */
684         const char *argv6[] = {prgname, "-c", "10", "-n", "2",
685                         "--file-prefix=" memtest, "--socket-mem=2,,2"};
686
687         /* invalid (null) --socket-mem flag */
688         const char *argv7[] = {prgname, "-c", "10", "-n", "2",
689                         "--file-prefix=" memtest, "--socket-mem="};
690
691         /* valid --socket-mem specified together with -m flag */
692         const char *argv8[] = {prgname, "-c", "10", "-n", "2",
693                         "--file-prefix=" memtest, "-m", "2", "--socket-mem=2,2"};
694
695         /* construct an invalid socket mask with 2 megs on each socket plus
696          * extra 2 megs on socket that doesn't exist on current system */
697         char invalid_socket_mem[SOCKET_MEM_STRLEN];
698         char buf[SOCKET_MEM_STRLEN];    /* to avoid copying string onto itself */
699         int i, num_sockets = get_number_of_sockets();
700
701         if (num_sockets <= 0 || num_sockets > RTE_MAX_NUMA_NODES) {
702                 printf("Error - cannot get number of sockets!\n");
703                 return -1;
704         }
705
706         rte_snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "--socket-mem=");
707
708         /* add one extra socket */
709         for (i = 0; i < num_sockets + 1; i++) {
710                 rte_snprintf(buf, sizeof(buf), "%s2", invalid_socket_mem);
711                 rte_snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "%s", buf);
712
713                 if (num_sockets + 1 - i > 1) {
714                         rte_snprintf(buf, sizeof(buf), "%s,", invalid_socket_mem);
715                         rte_snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "%s", buf);
716                 }
717         }
718
719         /* construct a valid socket mask with 2 megs on each existing socket */
720         char valid_socket_mem[SOCKET_MEM_STRLEN];
721
722         rte_snprintf(valid_socket_mem, sizeof(valid_socket_mem), "--socket-mem=");
723
724         /* add one extra socket */
725         for (i = 0; i < num_sockets; i++) {
726                 rte_snprintf(buf, sizeof(buf), "%s2", valid_socket_mem);
727                 rte_snprintf(valid_socket_mem, sizeof(valid_socket_mem), "%s", buf);
728
729                 if (num_sockets - i > 1) {
730                         rte_snprintf(buf, sizeof(buf), "%s,", valid_socket_mem);
731                         rte_snprintf(valid_socket_mem, sizeof(valid_socket_mem), "%s", buf);
732                 }
733         }
734
735         /* invalid --socket-mem flag (with extra socket) */
736         const char *argv9[] = {prgname, "-c", "10", "-n", "2",
737                         "--file-prefix=" memtest, invalid_socket_mem};
738
739         /* valid --socket-mem flag */
740         const char *argv10[] = {prgname, "-c", "10", "-n", "2",
741                         "--file-prefix=" memtest, valid_socket_mem};
742
743         if (launch_proc(argv0) != 0) {
744                 printf("Error - process failed with valid -m flag!\n");
745                 return -1;
746         }
747
748         if (launch_proc(argv1) != 0) {
749                 printf("Error - secondary process failed with valid -m flag !\n");
750                 return -1;
751         }
752
753         if (launch_proc(argv2) == 0) {
754                 printf("Error - process run ok with invalid (zero) --socket-mem!\n");
755                 return -1;
756         }
757
758         if (launch_proc(argv3) == 0) {
759                 printf("Error - process run ok with invalid "
760                                 "(incomplete) --socket-mem!\n");
761                 return -1;
762         }
763
764         if (launch_proc(argv4) == 0) {
765                 printf("Error - process run ok with invalid "
766                                 "(mixed with invalid input) --socket-mem!\n");
767                 return -1;
768         }
769
770         if (launch_proc(argv5) == 0) {
771                 printf("Error - process run ok with invalid "
772                                 "(mixed with invalid input with a numeric value as "
773                                 "last character) --socket-mem!\n");
774                 return -1;
775         }
776
777         if (launch_proc(argv6) == 0) {
778                 printf("Error - process run ok with invalid "
779                                 "(with empty socket) --socket-mem!\n");
780                 return -1;
781         }
782
783         if (launch_proc(argv7) == 0) {
784                 printf("Error - process run ok with invalid (null) --socket-mem!\n");
785                 return -1;
786         }
787
788         if (launch_proc(argv8) == 0) {
789                 printf("Error - process run ok with --socket-mem and -m specified!\n");
790                 return -1;
791         }
792
793         if (launch_proc(argv9) == 0) {
794                 printf("Error - process run ok with extra socket in --socket-mem!\n");
795                 return -1;
796         }
797
798         if (launch_proc(argv10) != 0) {
799                 printf("Error - process failed with valid --socket-mem!\n");
800                 return -1;
801         }
802
803         return 0;
804 }
805
806 int
807 test_eal_flags(void)
808 {
809         int ret = 0;
810
811         ret = test_missing_c_flag();
812         if (ret < 0) {
813                 printf("Error in test_missing_c_flag()\n");
814                 return ret;
815         }
816
817         ret = test_missing_n_flag();
818         if (ret < 0) {
819                 printf("Error in test_missing_n_flag()\n");
820                 return ret;
821         }
822
823         ret = test_no_hpet_flag();
824         if (ret < 0) {
825                 printf("Error in test_no_hpet_flag()\n");
826                 return ret;
827         }
828
829         ret = test_no_huge_flag();
830         if (ret < 0) {
831                 printf("Error in test_no_huge_flag()\n");
832                 return ret;
833         }
834
835         ret = test_invalid_b_flag();
836         if (ret < 0) {
837                 printf("Error in test_invalid_b_flag()\n");
838                 return ret;
839         }
840
841         ret = test_invalid_r_flag();
842         if (ret < 0) {
843                 printf("Error in test_invalid_r_flag()\n");
844                 return ret;
845         }
846
847         ret = test_memory_flags();
848         if (ret < 0) {
849                 printf("Error in test_memory_flags()\n");
850                 return ret;
851         }
852
853         ret = test_file_prefix();
854         if (ret < 0) {
855                 printf("Error in test_file_prefix()\n");
856                 return ret;
857         }
858
859         ret = test_misc_flags();
860         if (ret < 0) {
861                 printf("Error in test_misc_flags()");
862                 return ret;
863         }
864
865         return ret;
866 }
867
868 #else
869 /* Baremetal version
870  * Multiprocess not applicable, so just return 0 always
871  */
872 int
873 test_eal_flags(void)
874 {
875         printf("Multi-process not possible for baremetal, cannot test EAL flags\n");
876         return 0;
877 }
878
879 #endif