5 # Copyright (C) Intel Corp, 2004
7 # Author: Yin Hu <hu.yin@intel.com>
9 # Provides automated testing of the udevd binary.This test script is self-contained.
10 # Before you run this script please modify $sysfs to locate your sysfs filesystem,
11 # modify $udevsend_bin to locate your udevsend binary,
12 # modify $udev_bin to locate dummy udev script,
13 # modify $udev_bin2 to locate another dummy udev script ( amplify the execution time for test),
14 # modify $log_file to locate where udev script have placed the log file,
15 # modify $time_out to decide the time out for events,
16 # modify $udev_exe_time to decide the execution time for dummy udev script.
18 # Detail information of each test case please refer to the header of corresponding
22 # This program is free software; you can redistribute it and/or modify it
23 # under the terms of the GNU General Public License as published by the
24 # Free Software Foundation version 2 of the License.
26 # This program is distributed in the hope that it will be useful, but
27 # WITHOUT ANY WARRANTY; without even the implied warranty of
28 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 # General Public License for more details.
31 # You should have received a copy of the GNU General Public License along
32 # with this program; if not, write to the Free Software Foundation, Inc.,
33 # 675 Mass Ave, Cambridge, MA 02139, USA.
41 my $udevd_bin = "../../udevd";
42 my $udevsend_bin = "../../udevsend";
43 my $udev_bin = "$ENV{'PWD'}/udev-log-script.pl";
44 my $udev_bin2 = "$ENV{'PWD'}/udev-log-amplify.pl";
45 my $log_file = "/tmp/udev_log.txt";
47 my $udev_exe_time = 5;
55 my ($udev_binary) = @_;
57 system("killall udevd");
58 system("rm -f $log_file");
61 if (!defined($udev_binary)) {
62 $udev_binary = $udev_bin;
65 $ENV{'UDEV_BIN'} = $udev_binary;
66 system("/bin/sh -c $udevd_bin&");
71 # This function prepares corresponding environment variables
72 # and then call $udevsend_bin to send event.
74 my ($seqnum, $devpath, $action, $subsystem, $script) = @_;
77 $ENV{'DEVPATH'} = $devpath;
78 $ENV{'ACTION'} = $action;
79 $ENV{'SUBSYSTEM'} = $subsystem;
82 $ENV{SEQNUM} = $seqnum;
85 return system("$udevsend_bin $subsystem");
89 # Get current date function
90 # If we want GTM time, simply pass GMT as first argument to this function.
95 if( $format =~ /GMT/i ) {
96 $date = gmtime() . " GMT";
105 # This function should return a difference betweent date1 and date2
107 my ($date1, $date2) = @_;
108 my @monList = ( "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
109 "Aug", "Sep", "Oct", "Nov", "Dec" );
110 my ( $m1, $m2, $tmp );
112 $date1 =~ s/([\D]*)$//g;
113 $date2 =~ s/([\D]*)$//g;
115 return if( (not $date1) or (not $date2) );
120 ( $date1 =~ /([\d]+)[\s]+([\d]+):([\d]+):([\d]+)[\s]+([\d]+)/g );
122 ( $date2 =~ /([\d]+)[\s]+([\d]+):([\d]+):([\d]+)[\s]+([\d]+)/g );
124 foreach $tmp (@monList) {
125 $m1 = sprintf("%2.2d",$mon) if( $date1 =~ /$tmp/i );
126 $m2 = sprintf("%2.2d",$mon) if( $date2 =~ /$tmp/i );
130 my $dt1 = sprintf("%4.4d%s%2.2d%2.2d%2.2d%2.2d", $T1[4], $m1, $T1[0],
131 $T1[1], $T1[2], $T1[3]);
132 my $dt2 = sprintf("%4.4d%s%2.2d%2.2d%2.2d%2.2d", $T2[4], $m2, $T2[0],
133 $T2[1], $T2[2], $T2[3]);
135 my $ret = $dt1 - $dt2;
144 sub check_count_and_time {
147 my $log_ln_count = 0;
153 ($event_recv_time) = @_;
155 print " event receiving time: $event_recv_time\n\n";
157 open(LOGF, $log_file) || die "Opening file $log_file: $!";
159 foreach $line ( @content ) {
160 @line_items = split(/,/,$line);
161 print " device: $line_items[0], action: $line_items[1] \n";
162 print " forking udev time: $line_items[-1]";
163 $diff = cmpDate($line_items[-1], $event_recv_time);
164 print " the delay time is: $diff s \n\n";
165 if ( $diff > $time_out+10 ) {
166 print " the delay time is: $diff \n";
167 print " udevd doesn't act properly. \n";
174 return $log_ln_count;
177 sub check_sysfs_device_exist {
178 # check if the designated devices exist
182 foreach $dev (@dev_list) {
184 print "the designated device $dev doesn't exist. please change a device!\n";
198 ($event_recv_time) = @_;
200 print " event receiving time: $event_recv_time\n\n";
202 open(LOGF, $log_file) || die "Opening file $log_file: $!";
204 foreach $line ( @content ) {
205 @line_items = split(/,/,$line);
206 print " device: $line_items[0], action: $line_items[1] \n";
207 print " forking udev time: $line_items[-1]";
208 $diff = cmpDate($line_items[-1], $event_recv_time);
209 print " the delay time is: $diff s \n\n";
214 sub show_result_tm_out {
222 ($event_recv_time) = @_;
224 print " event receiving time: $event_recv_time\n\n";
226 open(LOGF, $log_file) || die "Opening file $log_file: $!";
228 foreach $line ( @content ) {
229 @line_items = split(/,/,$line);
230 print " device: $line_items[0], action: $line_items[1] \n";
231 print " forking udev time: $line_items[-1]";
232 $diff = cmpDate($line_items[-1], $event_recv_time);
233 print " the delay time is: $diff s \n\n";
234 if ( $diff < $time_out ) {
235 print " the delay time is: $diff \n";
236 print " udevd doesn't act properly. \n";
243 sub show_result_immediate {
251 ($event_recv_time) = @_;
253 print " event receiving time: $event_recv_time\n\n";
255 open(LOGF, $log_file) || die "Opening file $log_file: $!";
257 foreach $line ( @content ) {
258 @line_items = split(/,/,$line);
259 print " device: $line_items[0], action: $line_items[1] \n";
260 print " forking udev time: $line_items[-1]";
261 $diff = cmpDate($line_items[-1], $event_recv_time);
262 print " the delay time is: $diff s \n\n";
263 if ( $diff > $time_out ) {
264 print " the delay time is: $diff \n";
265 print " udevd doesn't act properly. \n";
280 open(LOGF, $log_file) || die "Opening file $log_file: $!";
283 foreach $line ( @content ) {
284 @line_items = split(/,/,$line);
285 $exe_time[$i] = $line_items[-1];
288 $diff = cmpDate($exe_time[1], $exe_time[0]);
289 if ( $diff < $udev_exe_time ) {
290 print " there are more than one udev instance for a single device at the same time. \n";
293 print " there is just one udev instance for a single device at the same time. \n";
297 # test case functions
298 sub run_no_seq_test {
299 print "Test case name: no sequence number test\n";
300 print "Test case purpose: check whether udevd forks udev immediately when environment variable SEQNUM is null.\n";
301 print "Test expected visible results: \n";
302 print " the delay time between event receiving and forking udev for udevd should be negligible, \n";
303 print " that is, udev should be forked at once. please notice the following time...\n\n";
308 # add devices event test
312 # check if devices /block/sda exist
313 check_sysfs_device_exist("$sysfs/block/sda");
315 # log current system date/time
318 udevsend(-1, "/block/sda", "add", "block");
320 # check if execution is successful in time
322 show_result_immediate($time);
323 print " fork udev (add device) at once successfully.\n\n";
326 # remove devices event test
328 system("rm -f $log_file");
330 # log current system date/time
333 udevsend(-1, "/block/sda", "remove", "block");
335 # check if execution is successful in time
337 show_result_immediate($time);
338 print " fork udev (remove device) at once successfully.\n\n";
339 print "this case is ok\n\n";
342 sub run_normal_seq_test {
343 print "Test case name: normal sequence number stress test\n";
344 print "Test case purpose: check whether udevd can fork massive udev instances for \n";
345 print " massive sequential events successfully. \n";
346 print "Test expected visible results: \n";
347 print " Populate all the devices in directory $sysfs/class/tty, fork udved to send add/remove \n";
348 print " event to udev for each device. \n";
349 print " We can see the delay time for each device should be negligible. \n\n";
358 @file_list = glob "$sysfs/class/tty/*";
360 # log current system date/time for device add events
364 # add devices event test
366 print "add device events test: \n";
367 foreach $file (@file_list) {
368 udevsend($seq, substr($file, length($sysfs), length($file)-length($sysfs)), "add", "tty");
369 # check if execution is successful
373 print "add event: error\n\n";
378 # we'd better wait the udev to create all the device for a few seconds
379 print " wait for udevd processing about $time_out s... \n\n";
382 $ret_seq = check_count_and_time($time);
383 if ( $ret_seq != $seq ) {
384 print " add event: failed. some device-adding events fail to execute.\n\n";
387 print " $seq pieces of device-adding events have executed successfully.\n\n";
390 # log current system date/time for device remove events
394 # remove devices event test
396 print "remove device events test: \n";
398 @file_list = glob "$sysfs/class/tty/*";
400 foreach $file (@file_list) {
401 udevsend($seq, substr($file, length($sysfs), length($file)-length($sysfs)), "remove", "tty");
402 # check if execution is successful
406 print "remove event: error\n\n";
411 # we'd better wait the udev to create all the device for a few seconds
412 print " waiting for udev removing devices (about $time_out s)...\n";
416 $ret_seq = check_count_and_time($time);
417 if ( $ret_seq != $seq ) {
418 print " remove event: failed. some device-removing events fail to execute.\n\n";
421 print " $seq pieces of device-removing events have executed successfully.\n\n";
422 print "this case is ok.\n\n";
426 sub run_random_seq_test {
427 print "Test case name: random sequence number test case,\n";
428 print "Test case purpose: check whether udevd can order the events with random sequence number \n";
429 print " and fork udev correctly. \n";
430 print "Test expected visible results: \n";
431 print " We have disordered the events sent to udevd, if udevd can order them correctly, the devices' \n";
432 print " add/remove sequence should be tty0, tty1, tty2. \n\n";
436 # check if devices /class/tty/tty0, tty1, tty2 exist
437 check_sysfs_device_exist("$sysfs/class/tty/tty0", "$sysfs/class/tty/tty1", "$sysfs/class/tty/tty2");
440 # add device events test
442 print "add device events test: \n";
445 # log current system date/time for device remove events
448 # parameters: 1 sequence number, 2 device, 3 action, 4 subsystem
449 udevsend(3, "/class/tty/tty2", "add", "tty");
450 udevsend(1, "/class/tty/tty0", "add", "tty");
451 udevsend(2, "/class/tty/tty1", "add", "tty");
452 print " wait for udevd processing about $time_out s... \n\n";
454 show_result_tm_out($time);
457 # remove device events test
459 print "\nremove device events test: \n";
462 # log current system date/time for device remove events
465 udevsend(3, "/class/tty/tty2", "remove", "tty");
466 udevsend(2, "/class/tty/tty1", "remove", "tty");
467 udevsend(1, "/class/tty/tty0", "remove", "tty");
470 print " wait for udevd processing about $time_out s... \n\n";
472 show_result_tm_out($time);
473 print "this case is ok.\n\n";
476 sub run_expected_seq_test {
477 print "Test case name: expected sequence number test \n";
478 print "Test case purpose: check whether udevd fork udev immediately when the incoming event\n";
479 print " is exactly the expected event sequence number.\n";
480 print "Test expected visible results:\n";
481 print " first, udevd disposes disorder events(sequence number is 3,1,2,5,4,6),\n";
482 print " thus after disposed the expected event number for udevd is 7, when incoming event is 7, udevd\n";
483 print " should fork udev immediately, the delay time should be negligible. \n";
484 print " where: event 7 is (add device /class/tty/tty2) \n\n";
488 # check if devices /class/tty0, tty1, tty2 exist
489 check_sysfs_device_exist("$sysfs/class/tty/tty0", "$sysfs/class/tty/tty1", "$sysfs/class/tty/tty2");
493 # parameters: 1 sequence number, 2 device, 3 action, 4 subsystem
494 udevsend(3, "/class/tty/tty2", "add", "tty");
495 udevsend(1, "/class/tty/tty0", "add", "tty");
496 udevsend(2, "/class/tty/tty1", "add", "tty");
497 udevsend(5, "/class/tty/tty1", "remove", "tty");
498 udevsend(4, "/class/tty/tty0", "remove", "tty");
499 udevsend(6, "/class/tty/tty2", "remove", "tty");
501 print " wait for udevd timing out for disorder events (about $time_out s) \n\n";
502 sleep $udev_exe_time + $time_out+1;
503 system("rm -f $log_file");
505 # log current system date/time for device remove events
509 udevsend(7, "/class/tty/tty2", "add", "tty");
511 print " event sequence number: 7 \n";
512 show_result_immediate($time);
514 print "this case is ok.\n\n";
517 sub run_single_instance_test {
518 print "Test case name: single instance running for a single device test \n";
519 print "Test case purpose: check whether udevd only fork one udev instance for a single\n";
520 print " device at the same time. For each event a udev instance is \n";
521 print " executed in the background. All further events for the same \n";
522 print " device are delayed until the execution is finished. This way \n";
523 print " there will never be more than one instance running for a single \n";
524 print " device at the same time.\n";
525 print "Test expected visible results:\n";
526 print " In this test we amplify the execution time of udev (about 5 seconds), first, \n";
527 print " we send a add event for device /block/sda, and then we send a remove event, so the \n";
528 print " execution of remove event should be delayed until add is finished. \n\n";
532 restart_daemon($udev_bin2);
534 # check if device exists
535 check_sysfs_device_exist("$sysfs/block/sda");
537 # log current system date/time
540 udevsend(-1, "/block/sda", "add", "block");
541 udevsend(-1, "/block/sda", "remove", "block");
544 print " wait for udevd processing about $udev_exe_time s... \n\n";
545 sleep $udev_exe_time+1;
546 show_result_immediate($time);
548 print "this case is ok\n\n";
551 sub run_same_events_test {
552 print "Test case name: event sequence number overlap test \n";
553 print "Test case purpose: check whether udevd doesn't fork udev untill time out\n";
554 print " when encountering a event with sequence number same as the pevious event. \n";
555 print "Test expected visible results:\n";
556 print " event ( remove device /block/sda ) should be no delay, \n";
557 print " event ( add device /class/tty/tty1 ) should be delayed for $time_out s than its previous \n";
558 print " event ( remove device /block/sda ) \n\n";
564 # check if device exist
565 check_sysfs_device_exist("$sysfs/block/sda", "$sysfs/class/tty/tty1");
567 udevsend(0, "/block/sda", "add", "block");
569 # log current system date/time
572 system("rm -f $log_file");
574 udevsend(1, "/block/sda", "remove", "block");
575 udevsend(1, "/class/tty/tty1", "add", "tty");
578 print " wait for udevd processing about $time_out s... \n\n";
581 print "this case is ok\n\n";
584 sub run_missing_seq_test {
585 print "Test case name: missing sequence number test \n";
586 print "Test case purpose: check whether udevd doesn't fork udev untill time out\n";
587 print " when certain event sequence number is missing.\n";
588 print "Test expected visible results:\n";
589 print " the delay time for event(add device /block/sda) should be about $time_out s.\n\n";
595 # check if device exist
596 check_sysfs_device_exist("$sysfs/block/sda", "$sysfs/class/tty/tty1");
598 udevsend(0, "/class/tty/tty1", "add", "tty");
599 udevsend(1, "/class/tty/tty1", "remove", "tty");
602 # log current system date/time
604 system("rm -f $log_file");
606 udevsend(3, "/block/sda", "add", "block");
609 print " wait for udevd processing about $time_out s... \n\n";
612 print "this case is ok\n\n";
615 sub run_all_cases_test {
617 run_normal_seq_test();
618 run_random_seq_test();
619 run_missing_seq_test();
620 run_expected_seq_test();
621 run_same_events_test();
622 run_single_instance_test();
627 $test_case = $ARGV[0];
629 if ($test_case == 1) {
631 } elsif ($test_case == 2) {
632 run_normal_seq_test();
633 } elsif ($test_case == 3) {
634 run_random_seq_test();
635 } elsif ($test_case == 4) {
636 run_missing_seq_test();
637 } elsif ($test_case == 5) {
638 run_expected_seq_test();
639 } elsif ($test_case == 6) {
640 run_single_instance_test();
641 } elsif ($test_case == 7) {
642 run_same_events_test();
644 run_all_cases_test();
648 print "command format: perl udevd-test.pl <case number>\n";
649 print " test case:\n";
650 print " 1: no event sequence number\n";
651 print " 2: sequential event sequence number\n";
652 print " 3: random event sequence number\n";
653 print " 4: missing event sequence number\n";
654 print " 5: the incoming event sequence number is right the expected sequence number\n";
655 print " 6: single udev instance on a single device at the same time\n";
656 print " 7: test event sequence number overlap\n";
657 print " 9: all the cases\n\n";