Line data Source code
1 : //------------------------------------------------------------------------------
2 : // LAGraph/src/test/test_CheckGraph.c: test LAGraph_CheckGraph
3 : //------------------------------------------------------------------------------
4 :
5 : // LAGraph, (c) 2019-2022 by The LAGraph Contributors, All Rights Reserved.
6 : // SPDX-License-Identifier: BSD-2-Clause
7 : //
8 : // For additional details (including references to third party source code and
9 : // other files) see the LICENSE file or contact permission@sei.cmu.edu. See
10 : // Contributors.txt for a full list of contributors. Created, in part, with
11 : // funding and support from the U.S. Government (see Acknowledgments.txt file).
12 : // DM22-0790
13 :
14 : // Contributed by Timothy A. Davis, Texas A&M University
15 :
16 : //------------------------------------------------------------------------------
17 :
18 : #include "LAGraph_test.h"
19 :
20 : //------------------------------------------------------------------------------
21 : // global variables
22 : //------------------------------------------------------------------------------
23 :
24 : LAGraph_Graph G = NULL ;
25 : char msg [LAGRAPH_MSG_LEN] ;
26 : GrB_Matrix A = NULL, B_bool = NULL, B_int32 = NULL ;
27 : GrB_Vector d_int64 = NULL, d_bool = NULL ;
28 : #define LEN 512
29 : char filename [LEN+1] ;
30 :
31 : //------------------------------------------------------------------------------
32 : // setup: start a test
33 : //------------------------------------------------------------------------------
34 :
35 2 : void setup (void)
36 : {
37 2 : OK (LAGraph_Init (msg)) ;
38 2 : }
39 :
40 : //------------------------------------------------------------------------------
41 : // teardown: finalize a test
42 : //------------------------------------------------------------------------------
43 :
44 2 : void teardown (void)
45 : {
46 2 : OK (LAGraph_Finalize (msg)) ;
47 2 : }
48 :
49 : //------------------------------------------------------------------------------
50 : // test_CheckGraph: test LAGraph_CheckGraph
51 : //------------------------------------------------------------------------------
52 :
53 : typedef struct
54 : {
55 : LAGraph_Kind kind ;
56 : const char *name ;
57 : }
58 : matrix_info ;
59 :
60 : const matrix_info files [ ] =
61 : {
62 : LAGraph_ADJACENCY_DIRECTED, "cover.mtx",
63 : LAGraph_ADJACENCY_DIRECTED, "ldbc-directed-example.mtx",
64 : LAGraph_ADJACENCY_UNDIRECTED, "ldbc-undirected-example.mtx",
65 : LAGRAPH_UNKNOWN, ""
66 : } ;
67 :
68 1 : void test_CheckGraph (void)
69 : {
70 1 : setup ( ) ;
71 :
72 1 : for (int k = 0 ; ; k++)
73 3 : {
74 :
75 : // load the adjacency matrix as A
76 4 : const char *aname = files [k].name ;
77 4 : LAGraph_Kind kind = files [k].kind ;
78 4 : if (strlen (aname) == 0) break;
79 3 : TEST_CASE (aname) ;
80 3 : snprintf (filename, LEN, LG_DATA_DIR "%s", aname) ;
81 3 : FILE *f = fopen (filename, "r") ;
82 3 : TEST_CHECK (f != NULL) ;
83 3 : OK (LAGraph_MMRead (&A, f, msg)) ;
84 3 : OK (fclose (f)) ;
85 3 : TEST_MSG ("Loading of adjacency matrix failed") ;
86 :
87 : // create the graph
88 3 : OK (LAGraph_New (&G, &A, kind, msg)) ;
89 3 : TEST_CHECK (A == NULL) ; // A has been moved into G->A
90 :
91 : // check the graph
92 3 : OK (LAGraph_CheckGraph (G, msg)) ;
93 3 : TEST_CHECK (G->kind == kind) ;
94 3 : if (kind == LAGraph_ADJACENCY_DIRECTED)
95 : {
96 2 : TEST_CHECK (G->is_symmetric_structure == LAGRAPH_UNKNOWN) ;
97 : }
98 : else
99 : {
100 1 : TEST_CHECK (G->is_symmetric_structure == LAGraph_TRUE) ;
101 : }
102 :
103 : // create its cached properties
104 3 : int ok_result = (kind == LAGraph_ADJACENCY_UNDIRECTED) ?
105 3 : LAGRAPH_CACHE_NOT_NEEDED : GrB_SUCCESS ;
106 3 : int result = LAGraph_Cached_AT (G, msg) ;
107 3 : OK (LAGraph_CheckGraph (G, msg)) ;
108 3 : TEST_CHECK (result == ok_result) ;
109 :
110 3 : OK (LAGraph_Cached_OutDegree (G, msg)) ;
111 3 : OK (LAGraph_CheckGraph (G, msg)) ;
112 :
113 3 : result = LAGraph_Cached_InDegree (G, msg) ;
114 3 : TEST_CHECK (result == ok_result) ;
115 3 : OK (LAGraph_CheckGraph (G, msg)) ;
116 :
117 : // free the graph
118 3 : OK (LAGraph_Delete (&G, msg)) ;
119 3 : TEST_CHECK (G == NULL) ;
120 :
121 : }
122 :
123 1 : teardown ( ) ;
124 1 : }
125 :
126 : //------------------------------------------------------------------------------
127 : // test_CheckGraph_failures: test error handling of LAGraph_CheckGraph
128 : //------------------------------------------------------------------------------
129 :
130 1 : void test_CheckGraph_failures (void)
131 : {
132 1 : setup ( ) ;
133 :
134 1 : printf ("\nTesting LAGraph_CheckGraph error handling:\n") ;
135 :
136 : // construct an invalid graph with a rectangular adjacency matrix
137 1 : TEST_CASE ("lp_afiro") ;
138 1 : FILE *f = fopen (LG_DATA_DIR "lp_afiro.mtx", "r") ;
139 1 : TEST_CHECK (f != NULL) ;
140 1 : OK (LAGraph_MMRead (&A, f, msg)) ;
141 1 : OK (fclose (f)) ;
142 1 : TEST_MSG ("Loading of lp_afiro.mtx failed") ;
143 :
144 : // create an invalid graph
145 1 : OK (LAGraph_New (&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)) ;
146 1 : TEST_CHECK (A == NULL) ; // A has been moved into G->A
147 :
148 : // adjacency matrix invalid
149 1 : TEST_CHECK (LAGraph_CheckGraph (G, msg) == LAGRAPH_INVALID_GRAPH) ;
150 1 : printf ("msg: %s\n", msg) ;
151 :
152 : // free the graph
153 1 : OK (LAGraph_Delete (&G, msg)) ;
154 1 : TEST_CHECK (G == NULL) ;
155 :
156 : // load a valid adjacency matrix
157 1 : TEST_CASE ("cover") ;
158 1 : f = fopen (LG_DATA_DIR "cover.mtx", "r") ;
159 1 : TEST_CHECK (f != NULL) ;
160 1 : OK (LAGraph_MMRead (&A, f, msg)) ;
161 1 : OK (fclose (f)) ;
162 1 : TEST_MSG ("Loading of cover.mtx failed") ;
163 :
164 : // create an valid graph
165 1 : OK (LAGraph_New (&G, &A, LAGraph_ADJACENCY_DIRECTED, msg)) ;
166 1 : TEST_CHECK (A == NULL) ; // A has been moved into G->A
167 1 : OK (LAGraph_CheckGraph (G, msg)) ;
168 :
169 1 : OK (GrB_Vector_new (&d_bool, GrB_BOOL, 7)) ;
170 1 : OK (GrB_Vector_new (&d_int64, GrB_INT64, 1000)) ;
171 1 : OK (GrB_Matrix_new (&B_bool, GrB_INT64, 7, 7)) ;
172 1 : OK (GrB_Matrix_new (&B_int32, GrB_INT32, 3, 4)) ;
173 :
174 : // G->AT has the right type, but wrong size
175 1 : G->AT = B_int32 ;
176 1 : TEST_CHECK (LAGraph_CheckGraph (G, msg) == LAGRAPH_INVALID_GRAPH) ;
177 1 : printf ("msg: %s\n", msg) ;
178 :
179 : // G->AT has the right size, but wrong type
180 1 : G->AT = B_bool ;
181 1 : TEST_CHECK (LAGraph_CheckGraph (G, msg) == LAGRAPH_INVALID_GRAPH) ;
182 1 : printf ("msg: %s\n", msg) ;
183 :
184 : #if LAGRAPH_SUITESPARSE
185 : // G->AT must be by-row
186 1 : OK (GxB_set (G->AT, GxB_FORMAT, GxB_BY_COL)) ;
187 1 : TEST_CHECK (LAGraph_CheckGraph (G, msg) == LAGRAPH_INVALID_GRAPH) ;
188 1 : printf ("msg: %s\n", msg) ;
189 : #endif
190 :
191 1 : G->AT = NULL ;
192 :
193 : // G->out_degree has the right type, but wrong size
194 1 : G->out_degree = d_int64 ;
195 1 : TEST_CHECK (LAGraph_CheckGraph (G, msg) == LAGRAPH_INVALID_GRAPH) ;
196 1 : printf ("msg: %s\n", msg) ;
197 :
198 : // G->out_degree has the right size, but wrong type
199 1 : G->out_degree = d_bool ;
200 1 : TEST_CHECK (LAGraph_CheckGraph (G, msg) == LAGRAPH_INVALID_GRAPH) ;
201 1 : printf ("msg: %s\n", msg) ;
202 :
203 1 : G->out_degree = NULL ;
204 :
205 : // G->in_degree has the right type, but wrong size
206 1 : G->in_degree = d_int64 ;
207 1 : TEST_CHECK (LAGraph_CheckGraph (G, msg) == LAGRAPH_INVALID_GRAPH) ;
208 1 : printf ("msg: %s\n", msg) ;
209 :
210 : // G->in_degree has the right size, but wrong type
211 1 : G->in_degree = d_bool ;
212 1 : TEST_CHECK (LAGraph_CheckGraph (G, msg) == LAGRAPH_INVALID_GRAPH) ;
213 1 : printf ("msg: %s\n", msg) ;
214 :
215 1 : G->in_degree = NULL ;
216 :
217 : #if LAGRAPH_SUITESPARSE
218 : // G->A must be by-row
219 1 : OK (GxB_set (G->A, GxB_FORMAT, GxB_BY_COL)) ;
220 1 : TEST_CHECK (LAGraph_CheckGraph (G, msg) == LAGRAPH_INVALID_GRAPH) ;
221 1 : printf ("msg: %s\n", msg) ;
222 : #endif
223 :
224 1 : GrB_free (&d_bool) ;
225 1 : GrB_free (&d_int64) ;
226 1 : GrB_free (&B_bool) ;
227 1 : GrB_free (&B_int32) ;
228 :
229 : // mangle G->kind
230 1 : G->kind = LAGRAPH_UNKNOWN ;
231 1 : TEST_CHECK (LAGraph_CheckGraph (G, msg) == LAGRAPH_INVALID_GRAPH) ;
232 1 : printf ("msg: %s\n", msg) ;
233 1 : G->kind = LAGraph_ADJACENCY_DIRECTED ;
234 :
235 : // free the adjacency matrix
236 1 : GrB_free (&(G->A)) ;
237 1 : TEST_CHECK (G->A == NULL) ;
238 :
239 1 : int result = LAGraph_CheckGraph (G, msg) ;
240 1 : printf ("result : %d msg: %s\n", result, msg) ;
241 1 : TEST_CHECK (result == LAGRAPH_INVALID_GRAPH) ;
242 :
243 : // free the graph
244 1 : OK (LAGraph_Delete (&G, msg)) ;
245 1 : TEST_CHECK (G == NULL) ;
246 :
247 1 : TEST_CHECK (LAGraph_CheckGraph (NULL, msg) == GrB_NULL_POINTER) ;
248 1 : printf ("msg: %s\n", msg) ;
249 :
250 1 : teardown ( ) ;
251 1 : }
252 :
253 : //------------------------------------------------------------------------------
254 : // test_CheckGraph_brutal:
255 : //------------------------------------------------------------------------------
256 :
257 : #if LAGRAPH_SUITESPARSE
258 1 : void test_CheckGraph_brutal (void)
259 : {
260 1 : OK (LG_brutal_setup (msg)) ;
261 :
262 : // load a valid adjacency matrix
263 1 : TEST_CASE ("karate") ;
264 1 : FILE *f = fopen (LG_DATA_DIR "karate.mtx", "r") ;
265 1 : TEST_CHECK (f != NULL) ;
266 1 : OK (LAGraph_MMRead (&A, f, msg)) ;
267 1 : OK (fclose (f)) ;
268 1 : TEST_MSG ("Loading of karate.mtx failed") ;
269 1 : printf ("\n") ;
270 :
271 : // create an valid graph
272 1 : OK (LAGraph_New (&G, &A, LAGraph_ADJACENCY_UNDIRECTED, msg)) ;
273 1 : TEST_CHECK (A == NULL) ; // A has been moved into G->A
274 1 : LG_BRUTAL_BURBLE (LAGraph_CheckGraph (G, msg)) ;
275 :
276 : // create its cached properties
277 1 : LG_BRUTAL_BURBLE (LAGraph_Cached_AT (G, msg)) ;
278 1 : LG_BRUTAL_BURBLE (LAGraph_CheckGraph (G, msg)) ;
279 7 : LG_BRUTAL_BURBLE (LAGraph_Cached_OutDegree (G, msg)) ;
280 1 : LG_BRUTAL_BURBLE (LAGraph_CheckGraph (G, msg)) ;
281 1 : LG_BRUTAL_BURBLE (LAGraph_Cached_InDegree (G, msg)) ;
282 1 : LG_BRUTAL_BURBLE (LAGraph_CheckGraph (G, msg)) ;
283 1 : LG_BRUTAL_BURBLE (LAGraph_Delete (&G, msg)) ;
284 :
285 1 : OK (LG_brutal_teardown (msg)) ;
286 1 : }
287 : #endif
288 :
289 : //-----------------------------------------------------------------------------
290 : // TEST_LIST: the list of tasks for this entire test
291 : //-----------------------------------------------------------------------------
292 :
293 : TEST_LIST =
294 : {
295 : { "CheckGraph", test_CheckGraph },
296 : { "CheckGraph_failures", test_CheckGraph_failures },
297 : #if LAGRAPH_SUITESPARSE
298 : { "CheckGraph_brutal", test_CheckGraph_brutal },
299 : #endif
300 : { NULL, NULL }
301 : } ;
|