1
2    /*+-----------------------------------------------------------------**
3     **                       OpenScop Library                          **
4     **-----------------------------------------------------------------**
5     **                            test.c                               **
6     **-----------------------------------------------------------------**
7     **                   First version: 01/10/2010                     **
8     **-----------------------------------------------------------------**
9
10
11 *****************************************************************************
12 * OpenScop: Structures and formats for polyhedral tools to talk together    *
13 *****************************************************************************
14 *    ,___,,_,__,,__,,__,,__,,_,__,,_,__,,__,,___,_,__,,_,__,                *
15 *    /   / /  //  //  //  // /   / /  //  //   / /  // /  /|,_,             *
16 *   /   / /  //  //  //  // /   / /  //  //   / /  // /  / / /\             *
17 *  |~~~|~|~~~|~~~|~~~|~~~|~|~~~|~|~~~|~~~|~~~|~|~~~|~|~~~|/_/  \            *
18 *  | G |C| P | = | L | P |=| = |C| = | = | = |=| = |=| C |\  \ /\           *
19 *  | R |l| o | = | e | l |=| = |a| = | = | = |=| = |=| L | \# \ /\          *
20 *  | A |a| l | = | t | u |=| = |n| = | = | = |=| = |=| o | |\# \  \         *
21 *  | P |n| l | = | s | t |=| = |d| = | = | = | |   |=| o | | \# \  \        *
22 *  | H | | y |   | e | o | | = |l|   |   | = | |   | | G | |  \  \  \       *
23 *  | I | |   |   | e |   | |   | |   |   |   | |   | |   | |   \  \  \      *
24 *  | T | |   |   |   |   | |   | |   |   |   | |   | |   | |    \  \  \     *
25 *  | E | |   |   |   |   | |   | |   |   |   | |   | |   | |     \  \  \    *
26 *  | * |*| * | * | * | * |*| * |*| * | * | * |*| * |*| * | /      \* \  \   *
27 *  | O |p| e | n | S | c |o| p |-| L | i | b |r| a |r| y |/        \  \ /   *
28 *  '---'-'---'---'---'---'-'---'-'---'---'---'-'---'-'---'          '--'    *
29 *                                                                           *
30 * Copyright (C) 2008 University Paris-Sud 11 and INRIA                      *
31 *                                                                           *
32 * (3-clause BSD license)                                                    *
33 * Redistribution and use in source  and binary forms, with or without       *
34 * modification, are permitted provided that the following conditions        *
35 * are met:                                                                  *
36 *                                                                           *
37 * 1. Redistributions of source code must retain the above copyright notice, *
38 *    this list of conditions and the following disclaimer.                  *
39 * 2. Redistributions in binary form must reproduce the above copyright      *
40 *    notice, this list of conditions and the following disclaimer in the    *
41 *    documentation and/or other materials provided with the distribution.   *
42 * 3. The name of the author may not be used to endorse or promote products  *
43 *    derived from this software without specific prior written permission.  *
44 *                                                                           *
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR      *
46 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *
47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.   *
48 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,          *
49 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT  *
50 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
51 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     *
52 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       *
53 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF  *
54 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.         *
55 *                                                                           *
56 * OpenScop Library, a library to manipulate OpenScop formats and data       *
57 * structures. Written by:                                                   *
58 * Cedric Bastoul     <Cedric.Bastoul@u-psud.fr> and                         *
59 * Louis-Noel Pouchet <Louis-Noel.Pouchet@inria.fr>                          *
60 *                                                                           *
61 *****************************************************************************/
62
63#include <stdlib.h>
64#include <stdio.h>
65#include <dirent.h>
66#include <string.h>
67#include <unistd.h>
68#include <sys/wait.h>
69#include <osl/osl.h>
70
71//#define FORK                 // Comment that if you want only one process
72                             // (best for debugging with valgrind but bad
73                             // for make check since any error will
74                             // stop the job).
75
76#define TEST_DIR    "."      // Directory to scan for OpenScop files
77#define TEST_SUFFIX ".scop"  // Suffix of OpenScop files
78
79
80/**
81 * test_file function
82 * This function tests an onpenscop file. A test has six steps:
83 * 1. read the file to raise the data up to OpenScop data structures,
84 * 2. clone the data structures,
85 * 3. compare the clone and the original one,
86 * 4. dump the data structures to a new OpenScop file,
87 * 5. read the generated file,
88 * 6. compare the data structures.
89 * If everything went well, the data structure of the two scops are the same.
90 * \param input_name The name of the input file.
91 * \param verbose    Verbose option (1 to set, 0 not to set).
92 * \return 1 if the test is successful, 0 otherwise.
93 */
94int test_file(char * input_name, int verbose) {
95  int success = 0;
96  int failure = 0;
97  int cloning = 0;
98  int dumping = 0;
99  int equal   = 0;
100  int output_desc;
101  char output_name[] = "/tmp/osl_test_XXXXXX";
102  FILE * input_file, * output_file;
103  osl_scop_p input_scop;
104  osl_scop_p output_scop;
105  osl_scop_p cloned_scop;
106
107  printf("\nTesting file %s... \n", input_name);
108
109  // PART I. Raise from file.
110  input_file = fopen(input_name, "r");
111  if (input_file == NULL) {
112    fflush(stdout);
113    fprintf(stderr, "\nError: unable to open file %s\n", input_name);
114    exit(2);
115  }
116  input_scop = osl_scop_read(input_file);
117  fclose(input_file);
118
119  // PART II. Clone and test.
120  cloned_scop = osl_scop_clone(input_scop);
121  // Compare the two scops.
122  if (cloning = osl_scop_equal(input_scop, cloned_scop))
123    printf("- cloning succeeded\n");
124  else
125    printf("- cloning failed\n");
126
127  // PART III. Dump to file and test.
128  output_desc = mkstemp(output_name);
129  if ((output_file = fdopen(output_desc, "w")) == NULL)
130    OSL_error("cannot open temporary output file for writing");
131  //osl_scop_dump(stdout, input_scop);
132  //osl_scop_print(stdout, input_scop);
133  osl_scop_print(output_file, input_scop);
134  fclose(output_file);
135
136  // Raise the generated file to data structures.
137  if ((output_file = fopen(output_name, "r")) == NULL)
138    OSL_error("cannot open temporary output file for reading");
139  output_scop = osl_scop_read(output_file);
140  //osl_scop_dump(stdout, output_scop);
141  fclose(output_file);
142  close(output_desc);
143
144  if (verbose) {
145    printf("\n\n*************************************************\n\n");
146    osl_scop_dump(stdout, output_scop);
147    osl_scop_print(stdout, output_scop);
148    printf("\n*************************************************\n\n");
149  }
150
151  // Compare the two scops.
152  if (dumping = osl_scop_equal(input_scop, output_scop))
153    printf("- dumping succeeded\n");
154  else
155    printf("- dumping failed\n");
156
157  // PART IV. Report.
158  if (equal = (cloning + dumping > 0) ? 1 : 0)
159    printf("Success :-)\n");
160  else
161    printf("Failure :-(\n");
162
163  // Save the planet.
164  osl_scop_free(input_scop);
165  osl_scop_free(cloned_scop);
166  osl_scop_free(output_scop);
167  remove(output_name);
168
169  return equal;
170}
171
172
173/**
174 * OpenScop test program.
175 * Usage: osl_test [-v] [osl_file]
176 * This program scans a directory for openscop files and test each of them.
177 * Optionnally the user can provide a file name to check this file only. A
178 * verbose option is also provided to output more information during tests.
179 */
180int main(int argc, char * argv[]) {
181  int total   = 0; // Total number of tests.
182  int success = 0; // Number of successes.
183  int verbose = 0; // 1 if the verbose option is set, 0 otherwise.
184  int dirtest = 1; // 1 if we check a whole directory, 0 for a single file.
185  int fileidx = 0; // Index of the file to check in argv (0 if none).
186  int d_namlen;
187  int suffix_length;
188  DIR * dir;
189  struct dirent * dp;
190
191  // Process the command line information
192  if (((argc > 1) && (!strcmp(argv[1], "-v"))) ||
193      ((argc > 2) && (!strcmp(argv[2], "-v"))))
194    verbose = 1;
195
196  if ((argc > 3) || ((argc == 3) && (!verbose))) {
197    fprintf(stderr, "usage: osl_test [-v] [osl_file]\n");
198    exit(1);
199  }
200
201  if ((argc - verbose) > 1) {
202    dirtest = 0;
203    fileidx = (!strcmp(argv[1], "-v")) ? 2 : 1;
204  }
205
206  // Proceed with the test(s), either directory or single file
207  if (dirtest) {
208    suffix_length = strlen(TEST_SUFFIX);
209
210    // For each file in the directory to check...
211    dir = opendir(TEST_DIR);
212    while ((dp = readdir(dir)) != NULL) {
213      d_namlen = strlen(dp->d_name);
214      // If the file has the convenient suffix...
215      if ((d_namlen > suffix_length) &&
216          (!strcmp(dp->d_name+(d_namlen-suffix_length), TEST_SUFFIX))) {
217        // Test it !
218#ifdef FORK
219        int report;
220        if (!fork())
221          exit(test_file(dp->d_name, verbose) ? 0 : 1);
222        wait(&report);
223        if (!WEXITSTATUS(report))
224          success++;
225#else
226        success += test_file(dp->d_name, verbose);
227#endif
228        total++;
229      }
230    }
231    closedir(dir);
232  }
233  else {
234    success = test_file(argv[fileidx], verbose);
235    total++;
236  }
237
238  printf("\n  +-----------------------+\n");
239  printf("  | OpenScop Test Summary |\n");
240  printf("  |-----------------------|\n");
241  printf("  | total          %4d   |\n", total);
242  printf("  | success(es)    %4d   |\n", success);
243  printf("  | failure(s)     %4d   |\n", total - success);
244  printf("  +-----------------------+\n\n");
245
246  // Return 0 if all tests were successful, 1 otherwise.
247  if (total - success)
248    return 1;
249  else
250    return 0;
251}
252