1 # Copyright (c) 2006 Zmanda Inc. All Rights Reserved.
3 # This program is free software; you can redistribute it and/or modify it
4 # under the terms of the GNU General Public License version 2 as published
5 # by the Free Software Foundation.
7 # This program is distributed in the hope that it will be useful, but
8 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 # You should have received a copy of the GNU General Public License along
13 # with this program; if not, write to the Free Software Foundation, Inc.,
14 # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 # Contact information: Zmanda Inc, 505 N Mathlida Ave, Suite 120
17 # Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
19 use Test::More qw(no_plan);
23 use lib "@amperldir@";
25 use Amanda::Config qw( :init :getconf );
30 # Try starting with no configuration at all
31 ok(config_init(0, ''), "Initialize with no configuration");
34 # Parse up a basic configuration
36 # invent "large" values for CONFTYPE_AM64 and CONFTYPE_SIZE
37 my $am64_num = '171801575472'; # 0xA000B000C000 / 1024
38 my $size_t_num = '2147483647'; # 0x7fffffff
40 $testconf = Amconfig->new();
41 $testconf->add_param('reserve', '75');
42 $testconf->add_param('autoflush', 'yes');
43 $testconf->add_param('tapedev', '"/dev/foo"');
44 $testconf->add_param('bumpsize', $am64_num);
45 $testconf->add_param('bumpmult', '1.4');
46 $testconf->add_param('reserved-udp-port', '100,200');
47 $testconf->add_param('device_output_buffer_size', $size_t_num);
48 $testconf->add_param('taperalgo', 'last');
49 $testconf->add_param('device_property', '"foo" "bar"');
50 $testconf->add_param('device_property', '"blue" "car"');
51 $testconf->add_param('displayunit', '"m"');
52 $testconf->add_param('debug_auth', '1');
53 $testconf->add_tapetype('mytapetype', [
54 'comment' => '"mine"',
57 $testconf->add_dumptype('mydumptype', [
58 'comment' => '"mine"',
59 'priority' => 'high', # == 2
60 'bumpsize' => $am64_num,
63 'holdingdisk' => 'required',
64 'compress' => 'client best',
65 'encrypt' => 'server',
66 'strategy' => 'incronly',
67 'comprate' => '0.25,0.75',
68 'exclude list' => '"foo" "bar"',
69 'exclude list append' => '"true" "star"',
70 'exclude file' => '"foolist"',
71 'include list' => '"bing" "ting"',
72 'include list append' => '"string" "fling"',
73 'include file optional' => '"rhyme"',
75 $testconf->add_interface('inyoface', [
76 'comment' => '"mine"',
79 $testconf->add_interface('inherface', [
80 'comment' => '"empty"',
82 $testconf->add_holdingdisk('hd1', [
83 'comment' => '"mine"',
84 'directory' => '"/mnt/hd1"',
86 'chunksize' => '1024k',
88 $testconf->add_holdingdisk('hd2', [
89 'comment' => '"empty"',
93 my $cfg_ok = config_init($CONFIG_INIT_EXPLICIT_NAME, 'TESTCONF');
94 ok($cfg_ok, "Load test configuration");
97 skip "error loading config", unless $cfg_ok;
99 is(Amanda::Config::get_config_name(), "TESTCONF",
101 is(Amanda::Config::get_config_dir(), "$CONFIG_DIR/TESTCONF",
103 is(Amanda::Config::get_config_filename(),
104 "$CONFIG_DIR/TESTCONF/amanda.conf",
105 "config_filename set");
108 SKIP: { # global parameters
109 skip "error loading config", unless $cfg_ok;
111 is(getconf($CNF_RESERVE), 75,
112 "integer global confparm");
113 is(getconf($CNF_BUMPSIZE), $am64_num+0,
114 "am64 global confparm");
115 is(getconf($CNF_TAPEDEV), "/dev/foo",
116 "string global confparm");
117 is(getconf($CNF_DEVICE_OUTPUT_BUFFER_SIZE), $size_t_num+0,
118 "size global confparm");
119 ok(getconf($CNF_AUTOFLUSH),
120 "boolean global confparm");
121 is(getconf($CNF_TAPERALGO), $Amanda::Config::ALGO_LAST,
122 "taperalgo global confparam");
123 is_deeply([getconf($CNF_RESERVED_UDP_PORT)], [100,200],
124 "intrange global confparm");
125 is(getconf($CNF_DISPLAYUNIT), "M",
126 "displayunit is correctly uppercased");
127 is_deeply(getconf($CNF_DEVICE_PROPERTY),
128 { "foo" => "bar", "blue" => "car" },
129 "proplist global confparm");
131 ok(getconf_seen($CNF_TAPEDEV),
132 "'tapedev' parm was seen");
133 ok(!getconf_seen($CNF_NETUSAGE),
134 "'netusage' parm was not seen");
137 SKIP: { # derived values
138 skip "error loading config", unless $cfg_ok;
140 is(Amanda::Config::getconf_unit_divisor(), 1024,
141 "correct unit divisor (from displayunit -> KB)");
142 ok($Amanda::Config::debug_auth,
143 "debug_auth setting reflected in global variable");
144 ok(!$Amanda::Config::debug_amandad,
145 "debug_amandad defaults to false");
149 skip "error loading config", unless $cfg_ok;
150 my $ttyp = lookup_tapetype("mytapetype");
151 ok($ttyp, "found mytapetype");
152 is(tapetype_getconf($ttyp, $TAPETYPE_COMMENT), 'mine',
154 is(tapetype_getconf($ttyp, $TAPETYPE_LENGTH), 128 * 1024,
157 ok(tapetype_seen($ttyp, $TAPETYPE_COMMENT),
158 "tapetype comment was seen");
159 ok(!tapetype_seen($ttyp, $TAPETYPE_LBL_TEMPL),
160 "tapetype lbl_templ was not seen");
162 is_deeply([ sort(+getconf_list("tapetype")) ],
163 [ sort("mytapetype", "TEST-TAPE") ],
164 "getconf_list lists all tapetypes");
168 skip "error loading config", unless $cfg_ok;
170 my $dtyp = lookup_dumptype("mydumptype");
171 ok($dtyp, "found mydumptype");
172 is(dumptype_getconf($dtyp, $DUMPTYPE_COMMENT), 'mine',
174 is(dumptype_getconf($dtyp, $DUMPTYPE_PRIORITY), 2,
175 "dumptype priority");
176 is(dumptype_getconf($dtyp, $DUMPTYPE_BUMPSIZE), $am64_num+0,
178 is(dumptype_getconf($dtyp, $DUMPTYPE_BUMPMULT), 1.75,
180 is(dumptype_getconf($dtyp, $DUMPTYPE_STARTTIME), 1829,
182 is(dumptype_getconf($dtyp, $DUMPTYPE_HOLDINGDISK), $HOLD_REQUIRED,
183 "dumptype holdingdisk");
184 is(dumptype_getconf($dtyp, $DUMPTYPE_COMPRESS), $COMP_BEST,
185 "dumptype compress");
186 is(dumptype_getconf($dtyp, $DUMPTYPE_ENCRYPT), $ENCRYPT_SERV_CUST,
188 is(dumptype_getconf($dtyp, $DUMPTYPE_STRATEGY), $DS_INCRONLY,
189 "dumptype strategy");
190 is_deeply([dumptype_getconf($dtyp, $DUMPTYPE_COMPRATE)], [0.25, 0.75],
191 "dumptype comprate");
192 is_deeply(dumptype_getconf($dtyp, $DUMPTYPE_INCLUDE),
193 { 'file' => [ 'rhyme' ],
194 'list' => [ 'bing', 'ting', 'string', 'fling' ],
196 "dumptype include list");
197 is_deeply(dumptype_getconf($dtyp, $DUMPTYPE_EXCLUDE),
198 { 'file' => [ 'foolist' ],
199 'list' => [ 'foo', 'bar', 'true', 'star' ],
201 "dumptype exclude list");
203 ok(dumptype_seen($dtyp, $DUMPTYPE_EXCLUDE),
204 "'exclude' parm was seen");
205 ok(!dumptype_seen($dtyp, $DUMPTYPE_RECORD),
206 "'record' parm was not seen");
208 is_deeply([ sort(+getconf_list("dumptype")) ],
211 NO-COMPRESS COMPRESS-FAST COMPRESS-BEST COMPRESS-CUST
212 SRVCOMPRESS BSD-AUTH KRB4-AUTH NO-RECORD NO-HOLD
215 "getconf_list lists all dumptypes (including defaults)");
219 skip "error loading config" unless $cfg_ok;
220 my $iface = lookup_interface("inyoface");
221 ok($iface, "found inyoface");
222 is(interface_name($iface), "inyoface",
223 "interface knows its name");
224 is(interface_getconf($iface, $INTER_COMMENT), 'mine',
225 "interface comment");
226 is(interface_getconf($iface, $INTER_MAXUSAGE), 100,
227 "interface maxusage");
229 $iface = lookup_interface("inherface");
230 ok($iface, "found inherface");
231 ok(interface_seen($iface, $INTER_COMMENT),
232 "seen set for parameters that appeared");
233 ok(!interface_seen($iface, $INTER_MAXUSAGE),
234 "seen not set for parameters that did not appear");
236 is_deeply([ sort(+getconf_list("interface")) ],
237 [ sort('inyoface', 'inherface', 'default') ],
238 "getconf_list lists all interfaces (in any order)");
241 SKIP: { # holdingdisks
242 skip "error loading config" unless $cfg_ok;
243 my $hdisk = lookup_holdingdisk("hd1");
244 ok($hdisk, "found hd1");
245 is(holdingdisk_name($hdisk), "hd1",
246 "hd1 knows its name");
247 is(holdingdisk_getconf($hdisk, $HOLDING_COMMENT), 'mine',
248 "holdingdisk comment");
249 is(holdingdisk_getconf($hdisk, $HOLDING_DISKDIR), '/mnt/hd1',
250 "holdingdisk diskdir (directory)");
251 is(holdingdisk_getconf($hdisk, $HOLDING_DISKSIZE), 100*1024,
252 "holdingdisk disksize (use)");
253 is(holdingdisk_getconf($hdisk, $HOLDING_CHUNKSIZE), 1024,
254 "holdingdisk chunksize");
256 $hdisk = lookup_holdingdisk("hd2");
257 ok($hdisk, "found hd2");
258 ok(holdingdisk_seen($hdisk, $HOLDING_COMMENT),
259 "seen set for parameters that appeared");
260 ok(!holdingdisk_seen($hdisk, $HOLDING_CHUNKSIZE),
261 "seen not set for parameters that did not appear");
263 # only holdingdisks have this linked-list structure
265 $hdisk = getconf_holdingdisks();
266 like(holdingdisk_name($hdisk), qr/hd[12]/,
267 "one disk is first in list of holdingdisks");
268 $hdisk = holdingdisk_next($hdisk);
269 like(holdingdisk_name($hdisk), qr/hd[12]/,
270 "another is second in list of holdingdisks");
271 ok(!holdingdisk_next($hdisk),
272 "no third holding disk");
274 is_deeply([ sort(+getconf_list("holdingdisk")) ],
275 [ sort('hd1', 'hd2') ],
276 "getconf_list lists all holdingdisks (in any order)");
280 # Test configuration dumping
282 # (uses the config from the previous section)
284 # fork a child and capture its stdout
285 my $pid = open(my $kid, "-|");
286 die "Can't fork: $!" unless defined($pid);
288 Amanda::Config::dump_configuration();
291 my $dump = join'', <$kid>;
294 my $fn = Amanda::Config::get_config_filename();
295 like($dump, qr/AMANDA CONFIGURATION FROM FILE "$fn"/,
296 "config filename is included correctly");
298 like($dump, qr/DEVICE_PROPERTY\s+"foo" "bar"\n/i,
299 "DEVICE_PROPERTY appears in dump output");
301 like($dump, qr/AMRECOVER_CHECK_LABEL\s+(yes|no)/i,
302 "AMRECOVER_CHECK_LABEL has a trailing space");
304 like($dump, qr/AMRECOVER_CHECK_LABEL\s+(yes|no)/i,
305 "AMRECOVER_CHECK_LABEL has a trailing space");
307 like($dump, qr/EXCLUDE\s+LIST "foo" "bar" "true" "star"/i,
308 "EXCLUDE LIST is in the dump");
309 like($dump, qr/EXCLUDE\s+FILE "foolist"/i,
310 "EXCLUDE FILE is in the dump");
311 like($dump, qr/INCLUDE\s+LIST OPTIONAL "bing" "ting" "string" "fling"/i,
312 "INCLUDE LIST is in the dump");
313 like($dump, qr/INCLUDE\s+FILE OPTIONAL "rhyme"/i,
314 "INCLUDE FILE is in the dump");
317 # Explore a quirk of exinclude parsing. Only the last
318 # exclude (or include) directive affects the 'optional' flag.
319 # We may want to change this, but we should do so intentionally.
320 # This is also tested by the 'amgetconf' installcheck.
322 $testconf = Amconfig->new();
323 $testconf->add_dumptype('mydumptype', [
324 'exclude list' => '"foo" "bar"',
325 'exclude list optional append' => '"true" "star"',
326 'exclude list append' => '"true" "star"',
330 $cfg_ok = config_init($CONFIG_INIT_EXPLICIT_NAME, "TESTCONF");
332 skip "error loading config", unless $cfg_ok;
334 my $dtyp = lookup_dumptype("mydumptype");
335 ok($dtyp, "found mydumptype");
336 is(dumptype_getconf($dtyp, $DUMPTYPE_EXCLUDE)->{'optional'}, 0,
337 "'optional' has no effect when not on the last occurrence");
340 $testconf = Amconfig->new();
341 $testconf->add_dumptype('mydumptype', [
342 'exclude file' => '"foo" "bar"',
343 'exclude file optional append' => '"true" "star"',
344 'exclude list append' => '"true" "star"',
348 $cfg_ok = config_init($CONFIG_INIT_EXPLICIT_NAME, "TESTCONF");
350 skip "error loading config", unless $cfg_ok;
352 my $dtyp = lookup_dumptype("mydumptype");
353 ok($dtyp, "found mydumptype");
354 is(dumptype_getconf($dtyp, $DUMPTYPE_EXCLUDE)->{'optional'}, 0,
355 "'optional' has no effect when not on the last occurrence of 'file'");