Changed include paths to be explicitly specified in the #include directive.
[pspp-builds.git] / src / language / tests / casefile-test.c
1 /* PSPP - computes sample statistics.
2    Copyright (C) 2004 Free Software Foundation, Inc.
3    Written by Ben Pfaff <blp@gnu.org>.
4
5    This program is free software; you can redistribute it and/or
6    modify it under the terms of the GNU General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18    02110-1301, USA. */
19
20 #include <config.h>
21 #include <data/casefile.h>
22 #include <data/case.h>
23
24 #include <gsl/gsl_rng.h>
25 #include <stdarg.h>
26 #include <language/command.h>
27 #include <language/lexer/lexer.h>
28
29 static void test_casefile (int pattern, size_t value_cnt, size_t case_cnt);
30 static void get_random_case (struct ccase *, size_t value_cnt,
31                              size_t case_idx);
32 static void write_random_case (struct casefile *cf, size_t case_idx);
33 static void read_and_verify_random_case (struct casefile *cf,
34                                          struct casereader *reader,
35                                          size_t case_idx);
36 static void fail_test (const char *message, ...);
37
38 int
39 cmd_debug_casefile (void) 
40 {
41   static const size_t sizes[] =
42     {
43       1, 2, 3, 4, 5, 6, 7, 14, 15, 16, 17, 31, 55, 73,
44       100, 137, 257, 521, 1031, 2053
45     };
46   int size_max;
47   int case_max;
48   int pattern;
49
50   size_max = sizeof sizes / sizeof *sizes;
51   if (lex_match_id ("SMALL")) 
52     {
53       size_max -= 4;
54       case_max = 511; 
55     }
56   else
57     case_max = 4095;
58   if (token != '.')
59     return lex_end_of_command ();
60     
61   for (pattern = 0; pattern < 6; pattern++) 
62     {
63       const size_t *size;
64
65       for (size = sizes; size < sizes + size_max; size++) 
66         {
67           size_t case_cnt;
68
69           for (case_cnt = 0; case_cnt <= case_max;
70                case_cnt = (case_cnt * 2) + 1)
71             test_casefile (pattern, *size, case_cnt);
72         }
73     }
74   printf ("Casefile tests succeeded.\n");
75   return CMD_SUCCESS;
76 }
77
78 static void
79 test_casefile (int pattern, size_t value_cnt, size_t case_cnt) 
80 {
81   struct casefile *cf;
82   struct casereader *r1, *r2;
83   struct ccase c;
84   gsl_rng *rng;
85   size_t i, j;
86
87   rng = gsl_rng_alloc (gsl_rng_mt19937);
88   cf = casefile_create (value_cnt);
89   if (pattern == 5)
90     casefile_to_disk (cf);
91   for (i = 0; i < case_cnt; i++)
92     write_random_case (cf, i);
93   if (pattern == 5)
94     casefile_sleep (cf);
95   r1 = casefile_get_reader (cf);
96   r2 = casefile_get_reader (cf);
97   switch (pattern) 
98     {
99     case 0:
100     case 5:
101       for (i = 0; i < case_cnt; i++) 
102         {
103           read_and_verify_random_case (cf, r1, i);
104           read_and_verify_random_case (cf, r2, i);
105         } 
106       break;
107     case 1:
108       for (i = 0; i < case_cnt; i++)
109         read_and_verify_random_case (cf, r1, i);
110       for (i = 0; i < case_cnt; i++) 
111         read_and_verify_random_case (cf, r2, i);
112       break;
113     case 2:
114     case 3:
115     case 4:
116       for (i = j = 0; i < case_cnt; i++) 
117         {
118           read_and_verify_random_case (cf, r1, i);
119           if (gsl_rng_get (rng) % pattern == 0) 
120             read_and_verify_random_case (cf, r2, j++); 
121           if (i == case_cnt / 2)
122             casefile_to_disk (cf);
123         }
124       for (; j < case_cnt; j++) 
125         read_and_verify_random_case (cf, r2, j);
126       break;
127     }
128   if (casereader_read (r1, &c))
129     fail_test ("Casereader 1 not at end of file.");
130   if (casereader_read (r2, &c))
131     fail_test ("Casereader 2 not at end of file.");
132   if (pattern != 1)
133     casereader_destroy (r1);
134   if (pattern != 2)
135     casereader_destroy (r2);
136   if (pattern > 2) 
137     {
138       r1 = casefile_get_destructive_reader (cf);
139       for (i = 0; i < case_cnt; i++) 
140         {
141           struct ccase read_case, expected_case;
142           
143           get_random_case (&expected_case, value_cnt, i);
144           if (!casereader_read_xfer (r1, &read_case)) 
145             fail_test ("Premature end of casefile.");
146           for (j = 0; j < value_cnt; j++) 
147             {
148               double a = case_num (&read_case, j);
149               double b = case_num (&expected_case, j);
150               if (a != b)
151                 fail_test ("Case %lu fails comparison.", (unsigned long) i); 
152             }
153           case_destroy (&expected_case);
154           case_destroy (&read_case);
155         }
156       casereader_destroy (r1);
157     }
158   casefile_destroy (cf);
159   gsl_rng_free (rng);
160 }
161
162 static void
163 get_random_case (struct ccase *c, size_t value_cnt, size_t case_idx) 
164 {
165   int i;
166   case_create (c, value_cnt);
167   for (i = 0; i < value_cnt; i++)
168     case_data_rw (c, i)->f = case_idx % 257 + i;
169 }
170
171 static void
172 write_random_case (struct casefile *cf, size_t case_idx) 
173 {
174   struct ccase c;
175   get_random_case (&c, casefile_get_value_cnt (cf), case_idx);
176   casefile_append_xfer (cf, &c);
177 }
178
179 static void
180 read_and_verify_random_case (struct casefile *cf,
181                              struct casereader *reader, size_t case_idx) 
182 {
183   struct ccase read_case, expected_case;
184   size_t value_cnt;
185   size_t i;
186   
187   value_cnt = casefile_get_value_cnt (cf);
188   get_random_case (&expected_case, value_cnt, case_idx);
189   if (!casereader_read (reader, &read_case)) 
190     fail_test ("Premature end of casefile.");
191   for (i = 0; i < value_cnt; i++) 
192     {
193       double a = case_num (&read_case, i);
194       double b = case_num (&expected_case, i);
195       if (a != b)
196         fail_test ("Case %lu fails comparison.", (unsigned long) case_idx); 
197     }
198   case_destroy (&read_case);
199   case_destroy (&expected_case);
200 }
201
202 static void
203 fail_test (const char *message, ...) 
204 {
205   va_list args;
206
207   va_start (args, message);
208   vprintf (message, args);
209   putchar ('\n');
210   va_end (args);
211   
212   exit (1);
213 }