1 // Copyright (C) 2005 Derek Scherger <derek@echologic.com>
2 //
3 // This program is made available under the GNU GPL version 2.0 or
4 // greater. See the accompanying file COPYING for details.
5 //
6 // This program is distributed WITHOUT ANY WARRANTY; without even the
7 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE.
9 
10 #include "../../../src/base.hh"
11 #include "../unit_tests.hh"
12 #include "../../../src/restrictions.hh"
13 #include "../../../src/constants.hh"
14 #include "../../../src/file_io.hh"
15 #include "../../../src/roster.hh"
16 
17 using std::string;
18 using std::vector;
19 
20 // f's and g's are files
21 // x's and y's are directories
22 // and this is rather painful
23 
24 #define fp_root file_path_internal("")
25 #define fp_f file_path_internal("f")
26 #define fp_g file_path_internal("g")
27 
28 #define fp_x file_path_internal("x")
29 #define fp_xf file_path_internal("x/f")
30 #define fp_xg file_path_internal("x/g")
31 #define fp_xx file_path_internal("x/x")
32 #define fp_xxf file_path_internal("x/x/f")
33 #define fp_xxg file_path_internal("x/x/g")
34 #define fp_xy file_path_internal("x/y")
35 #define fp_xyf file_path_internal("x/y/f")
36 #define fp_xyg file_path_internal("x/y/g")
37 
38 #define fp_y file_path_internal("y")
39 #define fp_yf file_path_internal("y/f")
40 #define fp_yg file_path_internal("y/g")
41 #define fp_yx file_path_internal("y/x")
42 #define fp_yxf file_path_internal("y/x/f")
43 #define fp_yxg file_path_internal("y/x/g")
44 #define fp_yy file_path_internal("y/y")
45 #define fp_yyf file_path_internal("y/y/f")
46 #define fp_yyg file_path_internal("y/y/g")
47 
48 namespace
49 {
50   node_id nid_root;
51   node_id nid_f;
52   node_id nid_g;
53 
54   node_id nid_x;
55   node_id nid_xf;
56   node_id nid_xg;
57   node_id nid_xx;
58   node_id nid_xxf;
59   node_id nid_xxg;
60   node_id nid_xy;
61   node_id nid_xyf;
62   node_id nid_xyg;
63 
64   node_id nid_y;
65   node_id nid_yf;
66   node_id nid_yg;
67   node_id nid_yx;
68   node_id nid_yxf;
69   node_id nid_yxg;
70   node_id nid_yy;
71   node_id nid_yyf;
72   node_id nid_yyg;
73 
74   file_id fid_f  (string(constants::idlen_bytes, '\x11'), origin::internal);
75   file_id fid_g  (string(constants::idlen_bytes, '\x22'), origin::internal);
76 
77   file_id fid_xf (string(constants::idlen_bytes, '\x33'), origin::internal);
78   file_id fid_xg (string(constants::idlen_bytes, '\x44'), origin::internal);
79   file_id fid_xxf(string(constants::idlen_bytes, '\x55'), origin::internal);
80   file_id fid_xxg(string(constants::idlen_bytes, '\x66'), origin::internal);
81   file_id fid_xyf(string(constants::idlen_bytes, '\x77'), origin::internal);
82   file_id fid_xyg(string(constants::idlen_bytes, '\x88'), origin::internal);
83 
84   file_id fid_yf (string(constants::idlen_bytes, '\x99'), origin::internal);
85   file_id fid_yg (string(constants::idlen_bytes, '\xaa'), origin::internal);
86   file_id fid_yxf(string(constants::idlen_bytes, '\xbb'), origin::internal);
87   file_id fid_yxg(string(constants::idlen_bytes, '\xcc'), origin::internal);
88   file_id fid_yyf(string(constants::idlen_bytes, '\xdd'), origin::internal);
89   file_id fid_yyg(string(constants::idlen_bytes, '\xee'), origin::internal);
90 }
91 
setup(roster_t & roster)92 static void setup(roster_t & roster)
93 {
94   temp_node_id_source nis;
95 
96   // these directories must exist for the path_restrictions to be valid.
97   mkdir_p(file_path_internal("x/x"));
98   mkdir_p(file_path_internal("x/y"));
99   mkdir_p(file_path_internal("y/x"));
100   mkdir_p(file_path_internal("y/y"));
101 
102   nid_root = roster.create_dir_node(nis);
103   nid_f    = roster.create_file_node(fid_f, nis);
104   nid_g    = roster.create_file_node(fid_g, nis);
105 
106   nid_x   = roster.create_dir_node(nis);
107   nid_xf  = roster.create_file_node(fid_xf, nis);
108   nid_xg  = roster.create_file_node(fid_xg, nis);
109   nid_xx  = roster.create_dir_node(nis);
110   nid_xxf = roster.create_file_node(fid_xxf, nis);
111   nid_xxg = roster.create_file_node(fid_xxg, nis);
112   nid_xy  = roster.create_dir_node(nis);
113   nid_xyf = roster.create_file_node(fid_xxf, nis);
114   nid_xyg = roster.create_file_node(fid_xxg, nis);
115 
116   nid_y   = roster.create_dir_node(nis);
117   nid_yf  = roster.create_file_node(fid_yf, nis);
118   nid_yg  = roster.create_file_node(fid_yg, nis);
119   nid_yx  = roster.create_dir_node(nis);
120   nid_yxf = roster.create_file_node(fid_yxf, nis);
121   nid_yxg = roster.create_file_node(fid_yxg, nis);
122   nid_yy  = roster.create_dir_node(nis);
123   nid_yyf = roster.create_file_node(fid_yxf, nis);
124   nid_yyg = roster.create_file_node(fid_yxg, nis);
125 
126   roster.attach_node(nid_root, fp_root);
127   roster.attach_node(nid_f, fp_f);
128   roster.attach_node(nid_g, fp_g);
129 
130   roster.attach_node(nid_x,   fp_x);
131   roster.attach_node(nid_xf,  fp_xf);
132   roster.attach_node(nid_xg,  fp_xg);
133   roster.attach_node(nid_xx,  fp_xx);
134   roster.attach_node(nid_xxf, fp_xxf);
135   roster.attach_node(nid_xxg, fp_xxg);
136   roster.attach_node(nid_xy,  fp_xy);
137   roster.attach_node(nid_xyf, fp_xyf);
138   roster.attach_node(nid_xyg, fp_xyg);
139 
140   roster.attach_node(nid_y,   fp_y);
141   roster.attach_node(nid_yf,  fp_yf);
142   roster.attach_node(nid_yg,  fp_yg);
143   roster.attach_node(nid_yx,  fp_yx);
144   roster.attach_node(nid_yxf, fp_yxf);
145   roster.attach_node(nid_yxg, fp_yxg);
146   roster.attach_node(nid_yy,  fp_yy);
147   roster.attach_node(nid_yyf, fp_yyf);
148   roster.attach_node(nid_yyg, fp_yyg);
149 
150 }
151 
UNIT_TEST(empty_restriction)152 UNIT_TEST(empty_restriction)
153 {
154   roster_t roster;
155   setup(roster);
156 
157   // check restricted nodes
158 
159   node_restriction nmask;
160 
161   UNIT_TEST_CHECK(nmask.empty());
162 
163   UNIT_TEST_CHECK(nmask.includes(roster, nid_root));
164   UNIT_TEST_CHECK(nmask.includes(roster, nid_f));
165   UNIT_TEST_CHECK(nmask.includes(roster, nid_g));
166 
167   UNIT_TEST_CHECK(nmask.includes(roster, nid_x));
168   UNIT_TEST_CHECK(nmask.includes(roster, nid_xf));
169   UNIT_TEST_CHECK(nmask.includes(roster, nid_xg));
170   UNIT_TEST_CHECK(nmask.includes(roster, nid_xx));
171   UNIT_TEST_CHECK(nmask.includes(roster, nid_xxf));
172   UNIT_TEST_CHECK(nmask.includes(roster, nid_xxg));
173   UNIT_TEST_CHECK(nmask.includes(roster, nid_xy));
174   UNIT_TEST_CHECK(nmask.includes(roster, nid_xyf));
175   UNIT_TEST_CHECK(nmask.includes(roster, nid_xyg));
176 
177   UNIT_TEST_CHECK(nmask.includes(roster, nid_y));
178   UNIT_TEST_CHECK(nmask.includes(roster, nid_yf));
179   UNIT_TEST_CHECK(nmask.includes(roster, nid_yg));
180   UNIT_TEST_CHECK(nmask.includes(roster, nid_yx));
181   UNIT_TEST_CHECK(nmask.includes(roster, nid_yxf));
182   UNIT_TEST_CHECK(nmask.includes(roster, nid_yxg));
183   UNIT_TEST_CHECK(nmask.includes(roster, nid_yy));
184   UNIT_TEST_CHECK(nmask.includes(roster, nid_yyf));
185   UNIT_TEST_CHECK(nmask.includes(roster, nid_yyg));
186 
187   // check restricted paths
188 
189   path_restriction pmask;
190 
191   UNIT_TEST_CHECK(pmask.empty());
192 
193   UNIT_TEST_CHECK(pmask.includes(fp_root));
194   UNIT_TEST_CHECK(pmask.includes(fp_f));
195   UNIT_TEST_CHECK(pmask.includes(fp_g));
196 
197   UNIT_TEST_CHECK(pmask.includes(fp_x));
198   UNIT_TEST_CHECK(pmask.includes(fp_xf));
199   UNIT_TEST_CHECK(pmask.includes(fp_xg));
200   UNIT_TEST_CHECK(pmask.includes(fp_xx));
201   UNIT_TEST_CHECK(pmask.includes(fp_xxf));
202   UNIT_TEST_CHECK(pmask.includes(fp_xxg));
203   UNIT_TEST_CHECK(pmask.includes(fp_xy));
204   UNIT_TEST_CHECK(pmask.includes(fp_xyf));
205   UNIT_TEST_CHECK(pmask.includes(fp_xyg));
206 
207   UNIT_TEST_CHECK(pmask.includes(fp_y));
208   UNIT_TEST_CHECK(pmask.includes(fp_yf));
209   UNIT_TEST_CHECK(pmask.includes(fp_yg));
210   UNIT_TEST_CHECK(pmask.includes(fp_yx));
211   UNIT_TEST_CHECK(pmask.includes(fp_yxf));
212   UNIT_TEST_CHECK(pmask.includes(fp_yxg));
213   UNIT_TEST_CHECK(pmask.includes(fp_yy));
214   UNIT_TEST_CHECK(pmask.includes(fp_yyf));
215   UNIT_TEST_CHECK(pmask.includes(fp_yyg));
216 }
217 
UNIT_TEST(simple_include)218 UNIT_TEST(simple_include)
219 {
220   roster_t roster;
221   setup(roster);
222 
223   vector<file_path> includes, excludes;
224   includes.push_back(file_path_internal("x/x"));
225   includes.push_back(file_path_internal("y/y"));
226 
227   // check restricted nodes
228 
229   node_restriction nmask(includes, excludes, -1, roster);
230 
231   UNIT_TEST_CHECK(!nmask.empty());
232 
233   // the root is included implicitly as the parent of x/x and y/y
234   UNIT_TEST_CHECK( nmask.includes(roster, nid_root));
235   UNIT_TEST_CHECK(!nmask.includes(roster, nid_f));
236   UNIT_TEST_CHECK(!nmask.includes(roster, nid_g));
237 
238   // x is included implicitly as the parent of x/x
239   UNIT_TEST_CHECK( nmask.includes(roster, nid_x));
240   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xf));
241   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xg));
242   UNIT_TEST_CHECK( nmask.includes(roster, nid_xx));
243   UNIT_TEST_CHECK( nmask.includes(roster, nid_xxf));
244   UNIT_TEST_CHECK( nmask.includes(roster, nid_xxg));
245   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xy));
246   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xyf));
247   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xyg));
248 
249   // y is included implicitly as the parent of y/y
250   UNIT_TEST_CHECK( nmask.includes(roster, nid_y));
251   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yf));
252   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yg));
253   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yx));
254   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yxf));
255   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yxg));
256   UNIT_TEST_CHECK( nmask.includes(roster, nid_yy));
257   UNIT_TEST_CHECK( nmask.includes(roster, nid_yyf));
258   UNIT_TEST_CHECK( nmask.includes(roster, nid_yyg));
259 
260   // check restricted paths
261 
262   path_restriction pmask(includes, excludes, -1);
263 
264   UNIT_TEST_CHECK(!pmask.empty());
265 
266   // the root is included implicitly as the parent of x/x and y/y
267   UNIT_TEST_CHECK( pmask.includes(fp_root));
268   UNIT_TEST_CHECK(!pmask.includes(fp_f));
269   UNIT_TEST_CHECK(!pmask.includes(fp_g));
270 
271   // x is included implicitly as the parent of x/x
272   UNIT_TEST_CHECK( pmask.includes(fp_x));
273   UNIT_TEST_CHECK(!pmask.includes(fp_xf));
274   UNIT_TEST_CHECK(!pmask.includes(fp_xg));
275   UNIT_TEST_CHECK( pmask.includes(fp_xx));
276   UNIT_TEST_CHECK( pmask.includes(fp_xxf));
277   UNIT_TEST_CHECK( pmask.includes(fp_xxg));
278   UNIT_TEST_CHECK(!pmask.includes(fp_xy));
279   UNIT_TEST_CHECK(!pmask.includes(fp_xyf));
280   UNIT_TEST_CHECK(!pmask.includes(fp_xyg));
281 
282   // y is included implicitly as the parent of y/y
283   UNIT_TEST_CHECK( pmask.includes(fp_y));
284   UNIT_TEST_CHECK(!pmask.includes(fp_yf));
285   UNIT_TEST_CHECK(!pmask.includes(fp_yg));
286   UNIT_TEST_CHECK(!pmask.includes(fp_yx));
287   UNIT_TEST_CHECK(!pmask.includes(fp_yxf));
288   UNIT_TEST_CHECK(!pmask.includes(fp_yxg));
289   UNIT_TEST_CHECK( pmask.includes(fp_yy));
290   UNIT_TEST_CHECK( pmask.includes(fp_yyf));
291   UNIT_TEST_CHECK( pmask.includes(fp_yyg));
292 }
293 
UNIT_TEST(simple_exclude)294 UNIT_TEST(simple_exclude)
295 {
296   roster_t roster;
297   setup(roster);
298 
299   vector<file_path> includes, excludes;
300   excludes.push_back(file_path_internal("x/x"));
301   excludes.push_back(file_path_internal("y/y"));
302 
303   // check restricted nodes
304 
305   node_restriction nmask(includes, excludes, -1, roster);
306 
307   UNIT_TEST_CHECK(!nmask.empty());
308 
309   UNIT_TEST_CHECK( nmask.includes(roster, nid_root));
310   UNIT_TEST_CHECK( nmask.includes(roster, nid_f));
311   UNIT_TEST_CHECK( nmask.includes(roster, nid_g));
312 
313   UNIT_TEST_CHECK( nmask.includes(roster, nid_x));
314   UNIT_TEST_CHECK( nmask.includes(roster, nid_xf));
315   UNIT_TEST_CHECK( nmask.includes(roster, nid_xg));
316   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xx));
317   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xxf));
318   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xxg));
319   UNIT_TEST_CHECK( nmask.includes(roster, nid_xy));
320   UNIT_TEST_CHECK( nmask.includes(roster, nid_xyf));
321   UNIT_TEST_CHECK( nmask.includes(roster, nid_xyg));
322 
323   UNIT_TEST_CHECK( nmask.includes(roster, nid_y));
324   UNIT_TEST_CHECK( nmask.includes(roster, nid_yf));
325   UNIT_TEST_CHECK( nmask.includes(roster, nid_yg));
326   UNIT_TEST_CHECK( nmask.includes(roster, nid_yx));
327   UNIT_TEST_CHECK( nmask.includes(roster, nid_yxf));
328   UNIT_TEST_CHECK( nmask.includes(roster, nid_yxg));
329   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yy));
330   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yyf));
331   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yyg));
332 
333   // check restricted paths
334 
335   path_restriction pmask(includes, excludes, -1);
336 
337   UNIT_TEST_CHECK(!pmask.empty());
338 
339   UNIT_TEST_CHECK( pmask.includes(fp_root));
340   UNIT_TEST_CHECK( pmask.includes(fp_f));
341   UNIT_TEST_CHECK( pmask.includes(fp_g));
342 
343   UNIT_TEST_CHECK( pmask.includes(fp_x));
344   UNIT_TEST_CHECK( pmask.includes(fp_xf));
345   UNIT_TEST_CHECK( pmask.includes(fp_xg));
346   UNIT_TEST_CHECK(!pmask.includes(fp_xx));
347   UNIT_TEST_CHECK(!pmask.includes(fp_xxf));
348   UNIT_TEST_CHECK(!pmask.includes(fp_xxg));
349   UNIT_TEST_CHECK( pmask.includes(fp_xy));
350   UNIT_TEST_CHECK( pmask.includes(fp_xyf));
351   UNIT_TEST_CHECK( pmask.includes(fp_xyg));
352 
353   UNIT_TEST_CHECK( pmask.includes(fp_y));
354   UNIT_TEST_CHECK( pmask.includes(fp_yf));
355   UNIT_TEST_CHECK( pmask.includes(fp_yg));
356   UNIT_TEST_CHECK( pmask.includes(fp_yx));
357   UNIT_TEST_CHECK( pmask.includes(fp_yxf));
358   UNIT_TEST_CHECK( pmask.includes(fp_yxg));
359   UNIT_TEST_CHECK(!pmask.includes(fp_yy));
360   UNIT_TEST_CHECK(!pmask.includes(fp_yyf));
361   UNIT_TEST_CHECK(!pmask.includes(fp_yyg));
362 }
363 
UNIT_TEST(include_exclude)364 UNIT_TEST(include_exclude)
365 {
366   roster_t roster;
367   setup(roster);
368 
369   vector<file_path> includes, excludes;
370   includes.push_back(file_path_internal("x"));
371   includes.push_back(file_path_internal("y"));
372   excludes.push_back(file_path_internal("x/x"));
373   excludes.push_back(file_path_internal("y/y"));
374 
375   // check restricted nodes
376 
377   node_restriction nmask(includes, excludes, -1, roster);
378 
379   UNIT_TEST_CHECK(!nmask.empty());
380 
381   // the root is included implicitly as the parent of x and y
382   UNIT_TEST_CHECK( nmask.includes(roster, nid_root));
383   UNIT_TEST_CHECK(!nmask.includes(roster, nid_f));
384   UNIT_TEST_CHECK(!nmask.includes(roster, nid_g));
385 
386   UNIT_TEST_CHECK( nmask.includes(roster, nid_x));
387   UNIT_TEST_CHECK( nmask.includes(roster, nid_xf));
388   UNIT_TEST_CHECK( nmask.includes(roster, nid_xg));
389   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xx));
390   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xxf));
391   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xxg));
392   UNIT_TEST_CHECK( nmask.includes(roster, nid_xy));
393   UNIT_TEST_CHECK( nmask.includes(roster, nid_xyf));
394   UNIT_TEST_CHECK( nmask.includes(roster, nid_xyg));
395 
396   UNIT_TEST_CHECK( nmask.includes(roster, nid_y));
397   UNIT_TEST_CHECK( nmask.includes(roster, nid_yf));
398   UNIT_TEST_CHECK( nmask.includes(roster, nid_yg));
399   UNIT_TEST_CHECK( nmask.includes(roster, nid_yx));
400   UNIT_TEST_CHECK( nmask.includes(roster, nid_yxf));
401   UNIT_TEST_CHECK( nmask.includes(roster, nid_yxg));
402   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yy));
403   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yyf));
404   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yyg));
405 
406   // check restricted paths
407 
408   path_restriction pmask(includes, excludes, -1);
409 
410   UNIT_TEST_CHECK(!pmask.empty());
411 
412   // the root is included implicitly as the parent of x and y
413   UNIT_TEST_CHECK( pmask.includes(fp_root));
414   UNIT_TEST_CHECK(!pmask.includes(fp_f));
415   UNIT_TEST_CHECK(!pmask.includes(fp_g));
416 
417   UNIT_TEST_CHECK( pmask.includes(fp_x));
418   UNIT_TEST_CHECK( pmask.includes(fp_xf));
419   UNIT_TEST_CHECK( pmask.includes(fp_xg));
420   UNIT_TEST_CHECK(!pmask.includes(fp_xx));
421   UNIT_TEST_CHECK(!pmask.includes(fp_xxf));
422   UNIT_TEST_CHECK(!pmask.includes(fp_xxg));
423   UNIT_TEST_CHECK( pmask.includes(fp_xy));
424   UNIT_TEST_CHECK( pmask.includes(fp_xyf));
425   UNIT_TEST_CHECK( pmask.includes(fp_xyg));
426 
427   UNIT_TEST_CHECK( pmask.includes(fp_y));
428   UNIT_TEST_CHECK( pmask.includes(fp_yf));
429   UNIT_TEST_CHECK( pmask.includes(fp_yg));
430   UNIT_TEST_CHECK( pmask.includes(fp_yx));
431   UNIT_TEST_CHECK( pmask.includes(fp_yxf));
432   UNIT_TEST_CHECK( pmask.includes(fp_yxg));
433   UNIT_TEST_CHECK(!pmask.includes(fp_yy));
434   UNIT_TEST_CHECK(!pmask.includes(fp_yyf));
435   UNIT_TEST_CHECK(!pmask.includes(fp_yyg));
436 }
437 
UNIT_TEST(exclude_include)438 UNIT_TEST(exclude_include)
439 {
440   roster_t roster;
441   setup(roster);
442 
443   vector<file_path> includes, excludes;
444   // note that excludes higher up the tree than the top
445   // include are rather pointless -- nothing above the
446   // top include is included anyway
447   excludes.push_back(file_path_internal("x"));
448   excludes.push_back(file_path_internal("y"));
449   includes.push_back(file_path_internal("x/x"));
450   includes.push_back(file_path_internal("y/y"));
451 
452   // check restricted nodes
453 
454   node_restriction nmask(includes, excludes, -1, roster);
455 
456   UNIT_TEST_CHECK(!nmask.empty());
457 
458   // the root is included implicitly as the parent of x/x and y/y
459   UNIT_TEST_CHECK( nmask.includes(roster, nid_root));
460   UNIT_TEST_CHECK(!nmask.includes(roster, nid_f));
461   UNIT_TEST_CHECK(!nmask.includes(roster, nid_g));
462 
463   // x is included implicitly as the parent of x/x
464   // even though x is also explcitly excluded
465   // the implicit include applies only to x but not
466   // its children
467   UNIT_TEST_CHECK( nmask.includes(roster, nid_x));
468   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xf));
469   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xg));
470   UNIT_TEST_CHECK( nmask.includes(roster, nid_xx));
471   UNIT_TEST_CHECK( nmask.includes(roster, nid_xxf));
472   UNIT_TEST_CHECK( nmask.includes(roster, nid_xxg));
473   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xy));
474   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xyf));
475   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xyg));
476 
477   // y is included implicitly as the parent of y/y
478   // even though y is also explcitly excluded
479   // the implicit include applies only to y but not
480   // its children
481   UNIT_TEST_CHECK( nmask.includes(roster, nid_y));
482   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yf));
483   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yg));
484   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yx));
485   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yxf));
486   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yxg));
487   UNIT_TEST_CHECK( nmask.includes(roster, nid_yy));
488   UNIT_TEST_CHECK( nmask.includes(roster, nid_yyf));
489   UNIT_TEST_CHECK( nmask.includes(roster, nid_yyg));
490 
491   // check restricted paths
492 
493   path_restriction pmask(includes, excludes, -1);
494 
495   UNIT_TEST_CHECK(!pmask.empty());
496 
497   // the root is included implicitly as the parent of x/x and y/y
498   UNIT_TEST_CHECK( pmask.includes(fp_root));
499   UNIT_TEST_CHECK(!pmask.includes(fp_f));
500   UNIT_TEST_CHECK(!pmask.includes(fp_g));
501 
502   // x is included implicitly as the parent of x/x
503   // even though x is also explcitly excluded
504   // the implicit include applies only to x but not
505   // its children
506   UNIT_TEST_CHECK( pmask.includes(fp_x));
507   UNIT_TEST_CHECK(!pmask.includes(fp_xf));
508   UNIT_TEST_CHECK(!pmask.includes(fp_xg));
509   UNIT_TEST_CHECK( pmask.includes(fp_xx));
510   UNIT_TEST_CHECK( pmask.includes(fp_xxf));
511   UNIT_TEST_CHECK( pmask.includes(fp_xxg));
512   UNIT_TEST_CHECK(!pmask.includes(fp_xy));
513   UNIT_TEST_CHECK(!pmask.includes(fp_xyf));
514   UNIT_TEST_CHECK(!pmask.includes(fp_xyg));
515 
516   // y is included implicitly as the parent of y/y
517   // even though y is also explcitly excluded
518   // the implicit include applies only to y but not
519   // its children
520   UNIT_TEST_CHECK( pmask.includes(fp_y));
521   UNIT_TEST_CHECK(!pmask.includes(fp_yf));
522   UNIT_TEST_CHECK(!pmask.includes(fp_yg));
523   UNIT_TEST_CHECK(!pmask.includes(fp_yx));
524   UNIT_TEST_CHECK(!pmask.includes(fp_yxf));
525   UNIT_TEST_CHECK(!pmask.includes(fp_yxg));
526   UNIT_TEST_CHECK( pmask.includes(fp_yy));
527   UNIT_TEST_CHECK( pmask.includes(fp_yyf));
528   UNIT_TEST_CHECK( pmask.includes(fp_yyg));
529 }
530 
UNIT_TEST(invalid_roster_paths)531 UNIT_TEST(invalid_roster_paths)
532 {
533   roster_t roster;
534   setup(roster);
535 
536   vector<file_path> includes, excludes;
537   includes.push_back(file_path_internal("foo"));
538   excludes.push_back(file_path_internal("bar"));
539 
540   UNIT_TEST_CHECK_THROW(node_restriction(includes, excludes, -1, roster),
541                         recoverable_failure);
542 }
543 
UNIT_TEST(invalid_workspace_paths)544 UNIT_TEST(invalid_workspace_paths)
545 {
546   roster_t roster;
547   setup(roster);
548 
549   vector<file_path> includes, excludes;
550   includes.push_back(file_path_internal("foo"));
551   excludes.push_back(file_path_internal("bar"));
552 
553   UNIT_TEST_CHECK_THROW(path_restriction(includes, excludes, -1),
554                         recoverable_failure);
555 }
556 
UNIT_TEST(ignored_invalid_workspace_paths)557 UNIT_TEST(ignored_invalid_workspace_paths)
558 {
559   roster_t roster;
560   setup(roster);
561 
562   vector<file_path> includes, excludes;
563   includes.push_back(file_path_internal("foo"));
564   excludes.push_back(file_path_internal("bar"));
565 
566   path_restriction pmask(includes, excludes, -1,
567                          path_restriction::skip_check);
568 
569   UNIT_TEST_CHECK( pmask.includes(file_path_internal("foo")));
570   UNIT_TEST_CHECK(!pmask.includes(file_path_internal("bar")));
571 }
572 
UNIT_TEST(include_depth_0)573 UNIT_TEST(include_depth_0)
574 {
575   roster_t roster;
576   setup(roster);
577 
578   vector<file_path> includes, excludes;
579   includes.push_back(file_path_internal("x"));
580   includes.push_back(file_path_internal("y"));
581 
582   long depth = 0;
583 
584   // check restricted nodes
585 
586   node_restriction nmask(includes, excludes, depth, roster);
587 
588   UNIT_TEST_CHECK(!nmask.empty());
589 
590   // root is included implicitly as the parent of x and y
591   UNIT_TEST_CHECK( nmask.includes(roster, nid_root));
592   UNIT_TEST_CHECK(!nmask.includes(roster, nid_f));
593   UNIT_TEST_CHECK(!nmask.includes(roster, nid_g));
594 
595   UNIT_TEST_CHECK( nmask.includes(roster, nid_x));
596   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xf));
597   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xg));
598   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xx));
599   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xxf));
600   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xxg));
601   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xy));
602   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xyf));
603   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xyg));
604 
605   UNIT_TEST_CHECK( nmask.includes(roster, nid_y));
606   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yf));
607   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yg));
608   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yx));
609   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yxf));
610   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yxg));
611   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yy));
612   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yyf));
613   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yyg));
614 
615   // check restricted paths
616 
617   path_restriction pmask(includes, excludes, depth);
618 
619   UNIT_TEST_CHECK(!pmask.empty());
620 
621   // root is included implicitly as the parent of x and y
622   UNIT_TEST_CHECK( pmask.includes(fp_root));
623   UNIT_TEST_CHECK(!pmask.includes(fp_f));
624   UNIT_TEST_CHECK(!pmask.includes(fp_g));
625 
626   UNIT_TEST_CHECK( pmask.includes(fp_x));
627   UNIT_TEST_CHECK(!pmask.includes(fp_xf));
628   UNIT_TEST_CHECK(!pmask.includes(fp_xg));
629   UNIT_TEST_CHECK(!pmask.includes(fp_xx));
630   UNIT_TEST_CHECK(!pmask.includes(fp_xxf));
631   UNIT_TEST_CHECK(!pmask.includes(fp_xxg));
632   UNIT_TEST_CHECK(!pmask.includes(fp_xy));
633   UNIT_TEST_CHECK(!pmask.includes(fp_xyf));
634   UNIT_TEST_CHECK(!pmask.includes(fp_xyg));
635 
636   UNIT_TEST_CHECK( pmask.includes(fp_y));
637   UNIT_TEST_CHECK(!pmask.includes(fp_yf));
638   UNIT_TEST_CHECK(!pmask.includes(fp_yg));
639   UNIT_TEST_CHECK(!pmask.includes(fp_yx));
640   UNIT_TEST_CHECK(!pmask.includes(fp_yxf));
641   UNIT_TEST_CHECK(!pmask.includes(fp_yxg));
642   UNIT_TEST_CHECK(!pmask.includes(fp_yy));
643   UNIT_TEST_CHECK(!pmask.includes(fp_yyf));
644   UNIT_TEST_CHECK(!pmask.includes(fp_yyg));
645 }
646 
UNIT_TEST(include_depth_1)647 UNIT_TEST(include_depth_1)
648 {
649   roster_t roster;
650   setup(roster);
651 
652   vector<file_path> includes, excludes;
653   includes.push_back(file_path_internal("x"));
654   includes.push_back(file_path_internal("y"));
655 
656   long depth = 1;
657 
658   // check restricted nodes
659 
660   node_restriction nmask(includes, excludes, depth, roster);
661 
662   UNIT_TEST_CHECK(!nmask.empty());
663 
664   // root is included implicitly as the parent of x and y
665   UNIT_TEST_CHECK( nmask.includes(roster, nid_root));
666   UNIT_TEST_CHECK(!nmask.includes(roster, nid_f));
667   UNIT_TEST_CHECK(!nmask.includes(roster, nid_g));
668 
669   UNIT_TEST_CHECK( nmask.includes(roster, nid_x));
670   UNIT_TEST_CHECK( nmask.includes(roster, nid_xf));
671   UNIT_TEST_CHECK( nmask.includes(roster, nid_xg));
672   UNIT_TEST_CHECK( nmask.includes(roster, nid_xx));
673   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xxf));
674   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xxg));
675   UNIT_TEST_CHECK( nmask.includes(roster, nid_xy));
676   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xyf));
677   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xyg));
678 
679   UNIT_TEST_CHECK( nmask.includes(roster, nid_y));
680   UNIT_TEST_CHECK( nmask.includes(roster, nid_yf));
681   UNIT_TEST_CHECK( nmask.includes(roster, nid_yg));
682   UNIT_TEST_CHECK( nmask.includes(roster, nid_yx));
683   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yxf));
684   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yxg));
685   UNIT_TEST_CHECK( nmask.includes(roster, nid_yy));
686   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yyf));
687   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yyg));
688 
689   // check restricted paths
690 
691   path_restriction pmask(includes, excludes, depth);
692 
693   UNIT_TEST_CHECK(!pmask.empty());
694 
695   // root is included implicitly as the parent of x and y
696   UNIT_TEST_CHECK( pmask.includes(fp_root));
697   UNIT_TEST_CHECK(!pmask.includes(fp_f));
698   UNIT_TEST_CHECK(!pmask.includes(fp_g));
699 
700   UNIT_TEST_CHECK( pmask.includes(fp_x));
701   UNIT_TEST_CHECK( pmask.includes(fp_xf));
702   UNIT_TEST_CHECK( pmask.includes(fp_xg));
703   UNIT_TEST_CHECK( pmask.includes(fp_xx));
704   UNIT_TEST_CHECK(!pmask.includes(fp_xxf));
705   UNIT_TEST_CHECK(!pmask.includes(fp_xxg));
706   UNIT_TEST_CHECK( pmask.includes(fp_xy));
707   UNIT_TEST_CHECK(!pmask.includes(fp_xyf));
708   UNIT_TEST_CHECK(!pmask.includes(fp_xyg));
709 
710   UNIT_TEST_CHECK( pmask.includes(fp_y));
711   UNIT_TEST_CHECK( pmask.includes(fp_yf));
712   UNIT_TEST_CHECK( pmask.includes(fp_yg));
713   UNIT_TEST_CHECK( pmask.includes(fp_yx));
714   UNIT_TEST_CHECK(!pmask.includes(fp_yxf));
715   UNIT_TEST_CHECK(!pmask.includes(fp_yxg));
716   UNIT_TEST_CHECK( pmask.includes(fp_yy));
717   UNIT_TEST_CHECK(!pmask.includes(fp_yyf));
718   UNIT_TEST_CHECK(!pmask.includes(fp_yyg));
719 }
720 
UNIT_TEST(include_depth_1_empty_restriction)721 UNIT_TEST(include_depth_1_empty_restriction)
722 {
723   roster_t roster;
724   setup(roster);
725 
726   vector<file_path> includes, excludes;
727 
728   long depth = 1;
729 
730   // check restricted nodes
731 
732   node_restriction nmask(includes, excludes, depth, roster);
733 
734   UNIT_TEST_CHECK( nmask.empty());
735 
736   UNIT_TEST_CHECK( nmask.includes(roster, nid_root));
737   UNIT_TEST_CHECK( nmask.includes(roster, nid_f));
738   UNIT_TEST_CHECK( nmask.includes(roster, nid_g));
739 
740   UNIT_TEST_CHECK( nmask.includes(roster, nid_x));
741   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xf));
742   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xg));
743   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xx));
744   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xxf));
745   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xxg));
746   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xy));
747   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xyf));
748   UNIT_TEST_CHECK(!nmask.includes(roster, nid_xyg));
749 
750   UNIT_TEST_CHECK( nmask.includes(roster, nid_y));
751   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yf));
752   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yg));
753   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yx));
754   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yxf));
755   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yxg));
756   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yy));
757   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yyf));
758   UNIT_TEST_CHECK(!nmask.includes(roster, nid_yyg));
759 
760   // check restricted paths
761 
762   path_restriction pmask(includes, excludes, depth);
763 
764   UNIT_TEST_CHECK( pmask.empty());
765 
766   UNIT_TEST_CHECK( pmask.includes(fp_root));
767   UNIT_TEST_CHECK( pmask.includes(fp_f));
768   UNIT_TEST_CHECK( pmask.includes(fp_g));
769 
770   UNIT_TEST_CHECK( pmask.includes(fp_x));
771   UNIT_TEST_CHECK(!pmask.includes(fp_xf));
772   UNIT_TEST_CHECK(!pmask.includes(fp_xg));
773   UNIT_TEST_CHECK(!pmask.includes(fp_xx));
774   UNIT_TEST_CHECK(!pmask.includes(fp_xxf));
775   UNIT_TEST_CHECK(!pmask.includes(fp_xxg));
776   UNIT_TEST_CHECK(!pmask.includes(fp_xy));
777   UNIT_TEST_CHECK(!pmask.includes(fp_xyf));
778   UNIT_TEST_CHECK(!pmask.includes(fp_xyg));
779 
780   UNIT_TEST_CHECK( pmask.includes(fp_y));
781   UNIT_TEST_CHECK(!pmask.includes(fp_yf));
782   UNIT_TEST_CHECK(!pmask.includes(fp_yg));
783   UNIT_TEST_CHECK(!pmask.includes(fp_yx));
784   UNIT_TEST_CHECK(!pmask.includes(fp_yxf));
785   UNIT_TEST_CHECK(!pmask.includes(fp_yxg));
786   UNIT_TEST_CHECK(!pmask.includes(fp_yy));
787   UNIT_TEST_CHECK(!pmask.includes(fp_yyf));
788   UNIT_TEST_CHECK(!pmask.includes(fp_yyg));
789 }
790 
UNIT_TEST(include_depth_2)791 UNIT_TEST(include_depth_2)
792 {
793   roster_t roster;
794   setup(roster);
795 
796   vector<file_path> includes, excludes;
797   includes.push_back(file_path_internal("x"));
798   includes.push_back(file_path_internal("y"));
799 
800   long depth = 2;
801 
802   // check restricted nodes
803 
804   node_restriction nmask(includes, excludes, depth, roster);
805 
806   UNIT_TEST_CHECK(!nmask.empty());
807 
808   // root is included implicitly as the parent of x and y
809   UNIT_TEST_CHECK( nmask.includes(roster, nid_root));
810   UNIT_TEST_CHECK(!nmask.includes(roster, nid_f));
811   UNIT_TEST_CHECK(!nmask.includes(roster, nid_g));
812 
813   UNIT_TEST_CHECK( nmask.includes(roster, nid_x));
814   UNIT_TEST_CHECK( nmask.includes(roster, nid_xf));
815   UNIT_TEST_CHECK( nmask.includes(roster, nid_xg));
816   UNIT_TEST_CHECK( nmask.includes(roster, nid_xx));
817   UNIT_TEST_CHECK( nmask.includes(roster, nid_xxf));
818   UNIT_TEST_CHECK( nmask.includes(roster, nid_xxg));
819   UNIT_TEST_CHECK( nmask.includes(roster, nid_xy));
820   UNIT_TEST_CHECK( nmask.includes(roster, nid_xyf));
821   UNIT_TEST_CHECK( nmask.includes(roster, nid_xyg));
822 
823   UNIT_TEST_CHECK( nmask.includes(roster, nid_y));
824   UNIT_TEST_CHECK( nmask.includes(roster, nid_yf));
825   UNIT_TEST_CHECK( nmask.includes(roster, nid_yg));
826   UNIT_TEST_CHECK( nmask.includes(roster, nid_yx));
827   UNIT_TEST_CHECK( nmask.includes(roster, nid_yxf));
828   UNIT_TEST_CHECK( nmask.includes(roster, nid_yxg));
829   UNIT_TEST_CHECK( nmask.includes(roster, nid_yy));
830   UNIT_TEST_CHECK( nmask.includes(roster, nid_yyf));
831   UNIT_TEST_CHECK( nmask.includes(roster, nid_yyg));
832 
833   // check restricted paths
834 
835   path_restriction pmask(includes, excludes, depth);
836 
837   UNIT_TEST_CHECK(!pmask.empty());
838 
839   // root is included implicitly as the parent of x and y
840   UNIT_TEST_CHECK( pmask.includes(fp_root));
841   UNIT_TEST_CHECK(!pmask.includes(fp_f));
842   UNIT_TEST_CHECK(!pmask.includes(fp_g));
843 
844   UNIT_TEST_CHECK( pmask.includes(fp_x));
845   UNIT_TEST_CHECK( pmask.includes(fp_xf));
846   UNIT_TEST_CHECK( pmask.includes(fp_xg));
847   UNIT_TEST_CHECK( pmask.includes(fp_xx));
848   UNIT_TEST_CHECK( pmask.includes(fp_xxf));
849   UNIT_TEST_CHECK( pmask.includes(fp_xxg));
850   UNIT_TEST_CHECK( pmask.includes(fp_xy));
851   UNIT_TEST_CHECK( pmask.includes(fp_xyf));
852   UNIT_TEST_CHECK( pmask.includes(fp_xyg));
853 
854   UNIT_TEST_CHECK( pmask.includes(fp_y));
855   UNIT_TEST_CHECK( pmask.includes(fp_yf));
856   UNIT_TEST_CHECK( pmask.includes(fp_yg));
857   UNIT_TEST_CHECK( pmask.includes(fp_yx));
858   UNIT_TEST_CHECK( pmask.includes(fp_yxf));
859   UNIT_TEST_CHECK( pmask.includes(fp_yxg));
860   UNIT_TEST_CHECK( pmask.includes(fp_yy));
861   UNIT_TEST_CHECK( pmask.includes(fp_yyf));
862   UNIT_TEST_CHECK( pmask.includes(fp_yyg));
863 }
864 
865 // Local Variables:
866 // mode: C++
867 // fill-column: 76
868 // c-file-style: "gnu"
869 // indent-tabs-mode: nil
870 // End:
871 // vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
872