multipath-tools: Introducing multipath C API
[multipath-tools/.git] / libdmmp / test / libdmmp_test.c
1 /*
2  * Copyright (C) 2015-2016 Red Hat, Inc.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  * Author: Gris Ge <fge@redhat.com>
18  */
19
20 #include <stdint.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <inttypes.h>
24 #include <string.h>
25 #include <pthread.h>
26 #include <unistd.h>
27
28 #include <libdmmp/libdmmp.h>
29
30 #define FAIL(rc, out, ...) \
31         do { \
32                 rc = EXIT_FAILURE; \
33                 fprintf(stderr, "FAIL: "__VA_ARGS__ ); \
34                 goto out; \
35         } while(0)
36 #define PASS(...) fprintf(stdout, "PASS: "__VA_ARGS__ );
37 #define FILE_NAME_SIZE 256
38 #define TMO 10000       /* Forcing timeout to 10 seconds */
39
40 int test_paths(struct dmmp_path_group *mp_pg)
41 {
42         struct dmmp_path **mp_ps = NULL;
43         uint32_t mp_p_count = 0;
44         uint32_t i = 0;
45         const char *blk_name = NULL;
46         int rc = EXIT_SUCCESS;
47
48         dmmp_path_array_get(mp_pg, &mp_ps, &mp_p_count);
49         if (mp_p_count == 0)
50                 FAIL(rc, out, "dmmp_path_array_get(): Got no path\n");
51         for (i = 0; i < mp_p_count; ++i) {
52                 blk_name = dmmp_path_blk_name_get(mp_ps[i]);
53                 if (blk_name == NULL)
54                         FAIL(rc, out, "dmmp_path_blk_name_get(): Got NULL\n");
55                 PASS("dmmp_path_blk_name_get(): %s\n", blk_name);
56                 PASS("dmmp_path_status_get(): %" PRIu32 " -- %s\n",
57                      dmmp_path_status_get(mp_ps[i]),
58                      dmmp_path_status_str(dmmp_path_status_get(mp_ps[i])));
59         }
60 out:
61         return rc;
62 }
63
64 int test_path_groups(struct dmmp_mpath *dmmp_mp)
65 {
66         struct dmmp_path_group **dmmp_pgs = NULL;
67         uint32_t dmmp_pg_count = 0;
68         uint32_t i = 0;
69         int rc = EXIT_SUCCESS;
70
71         dmmp_path_group_array_get(dmmp_mp, &dmmp_pgs, &dmmp_pg_count);
72         if ((dmmp_pg_count == 0) && (dmmp_pgs != NULL))
73                 FAIL(rc, out, "dmmp_path_group_array_get(): mp_pgs is not NULL "
74                      "but mp_pg_count is 0\n");
75         if ((dmmp_pg_count != 0) && (dmmp_pgs == NULL))
76                 FAIL(rc, out, "dmmp_path_group_array_get(): mp_pgs is NULL "
77                      "but mp_pg_count is not 0\n");
78         if (dmmp_pg_count == 0)
79                 FAIL(rc, out, "dmmp_path_group_array_get(): "
80                      "Got 0 path group\n");
81
82         PASS("dmmp_path_group_array_get(): Got %" PRIu32 " path groups\n",
83              dmmp_pg_count);
84
85         for (i = 0; i < dmmp_pg_count; ++i) {
86                 PASS("dmmp_path_group_id_get(): %" PRIu32 "\n",
87                      dmmp_path_group_id_get(dmmp_pgs[i]));
88                 PASS("dmmp_path_group_priority_get(): %" PRIu32 "\n",
89                      dmmp_path_group_priority_get(dmmp_pgs[i]));
90                 PASS("dmmp_path_group_status_get(): %" PRIu32 " -- %s\n",
91                      dmmp_path_group_status_get(dmmp_pgs[i]),
92                      dmmp_path_group_status_str
93                         (dmmp_path_group_status_get(dmmp_pgs[i])));
94                 PASS("dmmp_path_group_selector_get(): %s\n",
95                      dmmp_path_group_selector_get(dmmp_pgs[i]));
96                 rc = test_paths(dmmp_pgs[i]);
97                 if (rc != 0)
98                         goto out;
99         }
100 out:
101         return rc;
102 }
103
104 int main(int argc, char *argv[])
105 {
106         struct dmmp_context *ctx = NULL;
107         struct dmmp_mpath **dmmp_mps = NULL;
108         uint32_t dmmp_mp_count = 0;
109         const char *name = NULL;
110         const char *wwid = NULL;
111         const char *kdev = NULL;
112         uint32_t i = 0;
113         int rc = EXIT_SUCCESS;
114
115         ctx = dmmp_context_new();
116         dmmp_context_log_priority_set(ctx, DMMP_LOG_PRIORITY_DEBUG);
117         dmmp_context_userdata_set(ctx, ctx);
118         dmmp_context_userdata_set(ctx, NULL);
119         dmmp_context_timeout_set(ctx, TMO);
120         if (dmmp_context_timeout_get(ctx) != TMO)
121                 FAIL(rc, out, "dmmp_context_timeout_set(): Failed to set "
122                      "timeout to %u", TMO);
123
124         if (dmmp_mpath_array_get(ctx, &dmmp_mps, &dmmp_mp_count) != 0)
125                 FAIL(rc, out, "dmmp_mpath_array_get(): rc != 0\n");
126         if (dmmp_mp_count == 0)
127                 FAIL(rc, out, "dmmp_mpath_array_get(): "
128                      "Got no multipath devices\n");
129         PASS("dmmp_mpath_array_get(): Got %" PRIu32 " mpath\n", dmmp_mp_count);
130         for (i = 0; i < dmmp_mp_count; ++i) {
131                 name = dmmp_mpath_name_get(dmmp_mps[i]);
132                 wwid = dmmp_mpath_wwid_get(dmmp_mps[i]);
133                 kdev = dmmp_mpath_kdev_name_get(dmmp_mps[i]);
134                 if ((name == NULL) ||(wwid == NULL) || (kdev == NULL))
135                         FAIL(rc, out,
136                              "dmmp_mpath_array_get(): Got NULL name or wwid");
137                 PASS("dmmp_mpath_array_get(): Got mpath(%s): %s %s\n",
138                      kdev, name, wwid);
139                 rc = test_path_groups(dmmp_mps[i]);
140                 if (rc != 0)
141                         goto out;
142         }
143         dmmp_mpath_array_free(dmmp_mps, dmmp_mp_count);
144 out:
145         dmmp_context_free(ctx);
146         exit(rc);
147 }