selftest.pl: Silence verbose tdbsam output.
[kai/samba.git] / selftest / target / Samba3.pm
1 #!/usr/bin/perl
2 # Bootstrap Samba and run a number of tests against it.
3 # Copyright (C) 2005-2007 Jelmer Vernooij <jelmer@samba.org>
4 # Published under the GNU GPL, v3 or later.
5
6 package Samba3;
7
8 use strict;
9 use Cwd qw(abs_path);
10 use FindBin qw($RealBin);
11 use POSIX;
12
13 sub binpath($$)
14 {
15         my ($self, $binary) = @_;
16
17         if (defined($self->{bindir})) {
18                 my $path = "$self->{bindir}/$binary";
19                 -f $path or die("File $path doesn't exist");
20                 return $path;
21         }
22
23         return $binary;
24 }
25
26 sub new($$) {
27         my ($classname, $bindir) = @_;
28         my $self = { bindir => $bindir };
29         bless $self;
30         return $self;
31 }
32
33 sub teardown_env($$)
34 {
35         my ($self, $envvars) = @_;
36
37         my $smbdpid = read_pid($envvars, "smbd");
38         my $nmbdpid = read_pid($envvars, "nmbd");
39 #       my $winbinddpid = read_pid($envvars, "winbindd");
40
41         $self->stop_sig_term($smbdpid);
42         $self->stop_sig_term($nmbdpid);
43 #       $self->stop_sig_term($winbinddpid);
44         $self->stop_sig_kill($smbdpid);
45         $self->stop_sig_kill($nmbdpid);
46 #       $self->stop_sig_kill($winbinddpid);
47
48         return 0;
49 }
50
51 sub getlog_env_app($$$)
52 {
53         my ($self, $envvars, $name) = @_;
54
55         my $title = "$name LOG of: $envvars->{NETBIOSNAME}\n";
56         my $out = $title;
57
58         open(LOG, "<".$envvars->{$name."_TEST_LOG"});
59
60         seek(LOG, $envvars->{$name."_TEST_LOG_POS"}, SEEK_SET);
61         while (<LOG>) {
62                 $out .= $_;
63         }
64         $envvars->{$name."_TEST_LOG_POS"} = tell(LOG);
65         close(LOG);
66
67         return "" if $out eq $title;
68  
69         return $out;
70 }
71
72 sub getlog_env($$)
73 {
74         my ($self, $envvars) = @_;
75         my $ret = "";
76
77         $ret .= $self->getlog_env_app($envvars, "SMBD");
78         $ret .= $self->getlog_env_app($envvars, "NMBD");
79 #       $ret .= $self->getlog_env_app($envvars, "WINBINDD");
80
81         return $ret;
82 }
83
84 sub check_env($$)
85 {
86         my ($self, $envvars) = @_;
87
88         # TODO ...
89         return 1;
90 }
91
92 sub setup_env($$$)
93 {
94         my ($self, $envname, $path) = @_;
95         
96         if ($envname eq "dc") {
97                 return $self->setup_dc("$path/dc");
98         } else {
99                 return undef;
100         }
101 }
102
103 sub setup_dc($$)
104 {
105         my ($self, $path) = @_;
106
107         my $vars = $self->provision($path, "dc");
108
109         $self->check_or_start($vars,
110                               ($ENV{NMBD_MAXTIME} or 2700),
111                               ($ENV{WINBINDD_MAXTIME} or 2700),
112                               ($ENV{SMBD_MAXTIME} or 2700));
113
114         $self->wait_for_start($vars);
115
116         return $vars;
117 }
118
119 sub stop($)
120 {
121         my ($self) = @_;
122 }
123
124 sub stop_sig_term($$) {
125         my ($self, $pid) = @_;
126         kill("USR1", $pid) or kill("ALRM", $pid) or warn("Unable to kill $pid: $!");
127 }
128
129 sub stop_sig_kill($$) {
130         my ($self, $pid) = @_;
131         kill("ALRM", $pid) or warn("Unable to kill $pid: $!");
132 }
133
134 sub write_pid($$$)
135 {
136         my ($env_vars, $app, $pid) = @_;
137
138         open(PID, ">$env_vars->{PIDDIR}/timelimit.$app.pid");
139         print PID $pid;
140         close(PID);
141 }
142
143 sub read_pid($$)
144 {
145         my ($env_vars, $app) = @_;
146
147         open(PID, "<$env_vars->{PIDDIR}/timelimit.$app.pid");
148         my $pid = <PID>;
149         close(PID);
150         return $pid;
151 }
152
153 sub check_or_start($$$$) {
154         my ($self, $env_vars, $nmbd_maxtime, $winbindd_maxtime, $smbd_maxtime) = @_;
155
156         unlink($env_vars->{NMBD_TEST_LOG});
157         print "STARTING NMBD...";
158         my $pid = fork();
159         if ($pid == 0) {
160                 open STDOUT, ">$env_vars->{NMBD_TEST_LOG}";
161                 open STDERR, '>&STDOUT';
162
163                 $ENV{WINBINDD_SOCKET_DIR} = $env_vars->{WINBINDD_SOCKET_DIR};
164
165                 my @optargs = ("-d0");
166                 if (defined($ENV{NMBD_OPTIONS})) {
167                         @optargs = split(/ /, $ENV{NMBD_OPTIONS});
168                 }
169
170                 $ENV{MAKE_TEST_BINARY} = $self->binpath("nmbd");
171
172                 my @preargs = ($self->binpath("timelimit"), $nmbd_maxtime);
173                 if(defined($ENV{NMBD_VALGRIND})) { 
174                         @preargs = split(/ /, $ENV{NMBD_VALGRIND});
175                 }
176
177                 exec(@preargs, $self->binpath("nmbd"), "-F", "-S", "--no-process-group", "-s", $env_vars->{SERVERCONFFILE}, @optargs) or die("Unable to start nmbd: $!");
178         }
179         write_pid($env_vars, "nmbd", $pid);
180         print "DONE\n";
181
182 # disable winbindd until the build-farm faked_users work with it
183 #       unlink($env_vars->{WINBINDD_TEST_LOG});
184 #       print "STARTING WINBINDD...";
185 #       $pid = fork();
186 #       if ($pid == 0) {
187 #               open STDOUT, ">$env_vars->{WINBINDD_TEST_LOG}";
188 #               open STDERR, '>&STDOUT';
189 #
190 #               $ENV{WINBINDD_SOCKET_DIR} = $env_vars->{WINBINDD_SOCKET_DIR};
191 #
192 #               my @optargs = ("-d0");
193 #               if (defined($ENV{WINBINDD_OPTIONS})) {
194 #                       @optargs = split(/ /, $ENV{WINBINDD_OPTIONS});
195 #               }
196 #
197 #               $ENV{MAKE_TEST_BINARY} = $self->binpath("winbindd");
198 #               exec($self->binpath("timelimit"), $winbindd_maxtime, $ENV{WINBINDD_VALGRIND}, $self->binpath("winbindd"), "-F", "-S", "--no-process-group", "-s", $env_vars->{SERVERCONFFILE}, @optargs) or die("Unable to start winbindd: $!");
199 #       }
200 #       write_pid($env_vars, "winbindd", $pid);
201 #       print "DONE\n";
202
203         unlink($env_vars->{SMBD_TEST_LOG});
204         print "STARTING SMBD...";
205         $pid = fork();
206         if ($pid == 0) {
207                 open STDOUT, ">$env_vars->{SMBD_TEST_LOG}";
208                 open STDERR, '>&STDOUT';
209
210                 $ENV{WINBINDD_SOCKET_DIR} = $env_vars->{WINBINDD_SOCKET_DIR};
211
212                 $ENV{MAKE_TEST_BINARY} = $self->binpath("smbd");
213                 my @optargs = ("-d0");
214                 if (defined($ENV{SMBD_OPTIONS})) {
215                         @optargs = split(/ /, $ENV{SMBD_OPTIONS});
216                 }
217                 my @preargs = ($self->binpath("timelimit"), $smbd_maxtime);
218                 if(defined($ENV{SMBD_VALGRIND})) {
219                         @preargs = split(/ /,$ENV{SMBD_VALGRIND});
220                 }
221                 exec(@preargs, $self->binpath("smbd"), "-F", "-S", "--no-process-group", "-s", $env_vars->{SERVERCONFFILE}, @optargs) or die("Unable to start smbd: $!");
222         }
223         write_pid($env_vars, "smbd", $pid);
224         print "DONE\n";
225
226         return 0;
227 }
228
229 sub create_clientconf($$$)
230 {
231         my ($self, $prefix, $domain) = @_;
232
233         my $lockdir = "$prefix/locks";
234         my $logdir = "$prefix/logs";
235         my $piddir = "$prefix/pid";
236         my $privatedir = "$prefix/private";
237         my $scriptdir = "$RealBin/..";
238         my $conffile = "$prefix/smb.conf";
239
240         my $torture_interfaces='127.0.0.6/8,127.0.0.7/8,127.0.0.8/8,127.0.0.9/8,127.0.0.10/8,127.0.0.11/8';
241         open(CONF, ">$conffile");
242         print CONF "
243 [global]
244         workgroup = $domain
245
246         private dir = $privatedir
247         pid directory = $piddir
248         lock directory = $lockdir
249         log file = $logdir/log.\%m
250         log level = 0
251
252         name resolve order = bcast
253
254         netbios name = TORTURE_6
255         interfaces = $torture_interfaces
256         panic action = $scriptdir/gdb_backtrace \%d %\$(MAKE_TEST_BINARY)
257
258         passdb backend = tdbsam
259         ";
260         close(CONF);
261 }
262
263 sub provision($$$)
264 {
265         my ($self, $prefix, $role) = @_;
266
267         ##
268         ## setup the various environment variables we need
269         ##
270
271         my %ret = ();
272         my $server = "LOCALHOST2";
273         my $server_ip = "127.0.0.2";
274         my $domain = "SAMBA-TEST";
275
276         my $username = `PATH=/usr/ucb:$ENV{PATH} whoami`;
277         chomp $username;
278         my $password = "test";
279
280         my $srcdir="$RealBin/..";
281         my $scriptdir="$srcdir/selftest";
282         my $prefix_abs = abs_path($prefix);
283
284         my @dirs = ();
285
286         my $shrdir="$prefix_abs/share";
287         push(@dirs,$shrdir);
288
289         my $libdir="$prefix_abs/lib";
290         push(@dirs,$libdir);
291
292         my $piddir="$prefix_abs/pid";
293         push(@dirs,$piddir);
294
295         my $privatedir="$prefix_abs/private";
296         push(@dirs,$privatedir);
297
298         my $lockdir="$prefix_abs/lockdir";
299         push(@dirs,$lockdir);
300
301         my $logdir="$prefix_abs/logs";
302         push(@dirs,$logdir);
303
304         # this gets autocreated by winbindd
305         my $wbsockdir="$prefix_abs/winbindd";
306         my $wbsockprivdir="$lockdir/winbindd_privileged";
307
308         ## 
309         ## create the test directory layout
310         ##
311         mkdir($prefix_abs, 0777);
312         print "CREATE TEST ENVIRONMENT IN '$prefix'...";
313         system("rm -rf $prefix_abs/*");
314         mkdir($_, 0777) foreach(@dirs);
315
316         my $conffile="$libdir/server.conf";
317
318         open(CONF, ">$conffile") or die("Unable to open $conffile");
319         print CONF "
320 [global]
321         workgroup = $domain
322
323         private dir = $privatedir
324         pid directory = $piddir
325         lock directory = $lockdir
326         log file = $logdir/log.\%m
327         log level = 0
328
329         name resolve order = bcast
330
331         netbios name = $server
332         interfaces = $server_ip/8
333         bind interfaces only = yes
334         panic action = $scriptdir/gdb_backtrace %d %\$(MAKE_TEST_BINARY)
335
336         passdb backend = tdbsam
337
338         ; Necessary to add the build farm hacks
339         add user script = /bin/false
340         add machine script = /bin/false
341
342         kernel oplocks = no
343         kernel change notify = no
344
345         syslog = no
346         printing = bsd
347         printcap name = /dev/null
348
349 ";
350
351         if ($role eq "dc") {
352                 print CONF "\tdomain logons = yes\n";
353                 print CONF "\tdomain master = yes\n";
354         }
355
356 print CONF "
357
358         winbindd:socket dir = $wbsockdir
359
360 [tmp]
361         path = $shrdir
362         read only = no
363         smbd:sharedelay = 100000
364         map hidden = yes
365         map system = yes
366         create mask = 755
367 [hideunread]
368         copy = tmp
369         hide unreadable = yes
370 [hideunwrite]
371         copy = tmp
372         hide unwriteable files = yes
373 [print1]
374         copy = tmp
375         printable = yes
376         printing = test
377 [print2]
378         copy = print1
379 [print3]
380         copy = print1
381 [print4]
382         copy = print1
383         ";
384         close(CONF);
385
386         ##
387         ## create a test account
388         ##
389
390         open(PWD, "|".$self->binpath("smbpasswd")." -c $conffile -L -s -a $username >/dev/null");
391         print PWD "$password\n$password\n";
392         close(PWD) or die("Unable to set password for test account");
393
394         print "DONE\n";
395
396         $ret{SERVER_IP} = $server_ip;
397         $ret{NMBD_TEST_LOG} = "$prefix/nmbd_test.log";
398         $ret{WINBINDD_TEST_LOG} = "$prefix/winbindd_test.log";
399         $ret{SMBD_TEST_LOG} = "$prefix/smbd_test.log";
400         $ret{SERVERCONFFILE} = $conffile;
401         $ret{CONFIGURATION} ="-s $conffile";
402         $ret{SERVER} = $server;
403         $ret{USERNAME} = $username;
404         $ret{DOMAIN} = $domain;
405         $ret{NETBIOSNAME} = $server;
406         $ret{PASSWORD} = $password;
407         $ret{PIDDIR} = $piddir;
408         $ret{WINBINDD_SOCKET_DIR} = $wbsockdir;
409         $ret{WINBINDD_PRIV_PIPE_DIR} = $wbsockprivdir;
410         return \%ret;
411 }
412
413 sub wait_for_start($$)
414 {
415         my ($self, $envvars) = @_;
416
417         # give time for nbt server to register its names
418         print "delaying for nbt name registration\n";
419         sleep(10);
420         # This will return quickly when things are up, but be slow if we need to wait for (eg) SSL init 
421         system($self->binpath("nmblookup") ." $envvars->{CONFIGURATION} -U $envvars->{SERVER_IP} __SAMBA__");
422         system($self->binpath("nmblookup") ." $envvars->{CONFIGURATION} __SAMBA__");
423         system($self->binpath("nmblookup") ." $envvars->{CONFIGURATION} -U 127.255.255.255 __SAMBA__");
424         system($self->binpath("nmblookup") ." $envvars->{CONFIGURATION} -U $envvars->{SERVER_IP} $envvars->{SERVER}");
425         system($self->binpath("nmblookup") ." $envvars->{CONFIGURATION} $envvars->{SERVER}");
426         # make sure smbd is also up set
427         print "wait for smbd\n";
428         system($self->binpath("smbclient") ." $envvars->{CONFIGURATION} -L $envvars->{SERVER_IP} -U% -p 139 | head -2");
429         system($self->binpath("smbclient") ." $envvars->{CONFIGURATION} -L $envvars->{SERVER_IP} -U% -p 139 | head -2");
430
431         print $self->getlog_env($envvars);
432 }
433
434 1;