5 # Copyright (C) Intel Corp, 2004
7 # Author: Yin Hu <hu.yin@intel.com>
8 # Kay Sievers <kay.sievers@vrfy.org>
10 # Provides automated testing of the udevd binary.This test script is self-contained.
11 # Before you run this script please modify $sysfs to locate your sysfs filesystem,
12 # modify $udevd_bin to locate your udevsend binary,
13 # modify $udev_bin to locate dummy udev script,
14 # modify $udev_bin2 to locate another dummy udev script ( amplify the execution time for test),
15 # modify $log_file to locate where udev script have placed the log file,
16 # modify $time_out to decide the time out for events,
17 # modify $udev_exe_time to decide the execution time for dummy udev script.
19 # Detail information of each test case please refer to the header of corresponding
23 # This program is free software; you can redistribute it and/or modify it
24 # under the terms of the GNU General Public License as published by the
25 # Free Software Foundation version 2 of the License.
27 # This program is distributed in the hope that it will be useful, but
28 # WITHOUT ANY WARRANTY; without even the implied warranty of
29 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 # General Public License for more details.
32 # You should have received a copy of the GNU General Public License along
33 # with this program; if not, write to the Free Software Foundation, Inc.,
34 # 675 Mass Ave, Cambridge, MA 02139, USA.
42 my $udevd_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 system("killall udevd");
56 system("rm -f $log_file");
61 # This function prepares corresponding environment variables
62 # and then call $udevd_bin to send event.
64 my ($seqnum, $devpath, $action, $subsystem, $udev_bin_tmp) = @_;
66 $ENV{DEVPATH} = $devpath;
67 $ENV{ACTION} = $action;
68 $udev_bin_tmp = $udev_bin if ( not $udev_bin_tmp );
69 $ENV{UDEV_BIN} = $udev_bin_tmp;
71 $ENV{SEQNUM} = $seqnum;
76 return system("$udevd_bin $subsystem");
80 # Get current date function
81 # If we want GTM time, simply pass GMT as first argument to this function.
86 if( $format =~ /GMT/i ) {
87 $date = gmtime() . " GMT";
96 # This function should return a difference betweent date1 and date2
98 my ($date1, $date2) = @_;
99 my @monList = ( "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
100 "Aug", "Sep", "Oct", "Nov", "Dec" );
101 my ( $m1, $m2, $tmp );
103 $date1 =~ s/([\D]*)$//g;
104 $date2 =~ s/([\D]*)$//g;
106 return if( (not $date1) or (not $date2) );
111 ( $date1 =~ /([\d]+)[\s]+([\d]+):([\d]+):([\d]+)[\s]+([\d]+)/g );
113 ( $date2 =~ /([\d]+)[\s]+([\d]+):([\d]+):([\d]+)[\s]+([\d]+)/g );
115 foreach $tmp (@monList) {
116 $m1 = sprintf("%2.2d",$mon) if( $date1 =~ /$tmp/i );
117 $m2 = sprintf("%2.2d",$mon) if( $date2 =~ /$tmp/i );
121 my $dt1 = sprintf("%4.4d%s%2.2d%2.2d%2.2d%2.2d", $T1[4], $m1, $T1[0],
122 $T1[1], $T1[2], $T1[3]);
123 my $dt2 = sprintf("%4.4d%s%2.2d%2.2d%2.2d%2.2d", $T2[4], $m2, $T2[0],
124 $T2[1], $T2[2], $T2[3]);
126 my $ret = $dt1 - $dt2;
135 sub check_count_and_time {
138 my $log_ln_count = 0;
144 ($event_recv_time) = @_;
146 print " event receiving time: $event_recv_time\n\n";
148 open(LOGF, $log_file) || die "Opening file $log_file: $!";
150 foreach $line ( @content ) {
151 @line_items = split(/,/,$line);
152 print " device: $line_items[0], action: $line_items[1] \n";
153 print " forking udev time: $line_items[-1]";
154 $diff = cmpDate($line_items[-1], $event_recv_time);
155 print " the delay time is: $diff s \n\n";
156 if ( $diff > $time_out ) {
157 print " the delay time is: $diff \n";
158 print " udevd doesn't act properly. \n";
165 return $log_ln_count;
168 sub check_sysfs_device_exist {
169 # check if the designated devices exist
173 foreach $dev (@dev_list) {
175 print "the designated device $dev doesn't exist. please change a device!\n";
189 ($event_recv_time) = @_;
191 print " event receiving time: $event_recv_time\n\n";
193 open(LOGF, $log_file) || die "Opening file $log_file: $!";
195 foreach $line ( @content ) {
196 @line_items = split(/,/,$line);
197 print " device: $line_items[0], action: $line_items[1] \n";
198 print " forking udev time: $line_items[-1]";
199 $diff = cmpDate($line_items[-1], $event_recv_time);
200 print " the delay time is: $diff s \n\n";
205 sub show_result_tm_out {
213 ($event_recv_time) = @_;
215 print " event receiving time: $event_recv_time\n\n";
217 open(LOGF, $log_file) || die "Opening file $log_file: $!";
219 foreach $line ( @content ) {
220 @line_items = split(/,/,$line);
221 print " device: $line_items[0], action: $line_items[1] \n";
222 print " forking udev time: $line_items[-1]";
223 $diff = cmpDate($line_items[-1], $event_recv_time);
224 print " the delay time is: $diff s \n\n";
225 if ( $diff < $time_out ) {
226 print " the delay time is: $diff \n";
227 print " udevd doesn't act properly. \n";
234 sub show_result_immediate {
242 ($event_recv_time) = @_;
244 print " event receiving time: $event_recv_time\n\n";
246 open(LOGF, $log_file) || die "Opening file $log_file: $!";
248 foreach $line ( @content ) {
249 @line_items = split(/,/,$line);
250 print " device: $line_items[0], action: $line_items[1] \n";
251 print " forking udev time: $line_items[-1]";
252 $diff = cmpDate($line_items[-1], $event_recv_time);
253 print " the delay time is: $diff s \n\n";
254 if ( $diff > $time_out ) {
255 print " the delay time is: $diff \n";
256 print " udevd doesn't act properly. \n";
271 open(LOGF, $log_file) || die "Opening file $log_file: $!";
274 foreach $line ( @content ) {
275 @line_items = split(/,/,$line);
276 $exe_time[$i] = $line_items[-1];
279 $diff = cmpDate($exe_time[1], $exe_time[0]);
280 if ( $diff < $udev_exe_time ) {
281 print " there are more than one udev instance for a single device at the same time. \n";
284 print " there is just one udev instance for a single device at the same time. \n";
288 # test case functions
289 sub run_no_seq_test {
290 print "Test case name: no sequence number test\n";
291 print "Test case purpose: check whether udevd forks udev immediately when environment variable SEQNUM is null.\n";
292 print "Test expected visible results: \n";
293 print " the delay time between event receiving and forking udev for udevd should be negligible, \n";
294 print " that is, udev should be forked at once. please notice the following time...\n\n";
300 # add devices event test
304 # check if devices /block/sda exist
305 check_sysfs_device_exist("$sysfs/block/sda");
307 # log current system date/time
311 udevsend(-1, "/block/sda", "add", "block");
313 # check if execution is successful in time
315 show_result_immediate($time);
316 print " fork udev (add device) at once successfully.\n\n";
319 # remove devices event test
321 system("rm -f $log_file");
323 # log current system date/time
327 udevsend(-1, "/block/sda", "remove", "block");
329 # check if execution is successful in time
331 show_result_immediate($time);
332 print " fork udev (remove device) at once successfully.\n\n";
333 print "this case is ok\n\n";
336 sub run_normal_seq_test {
337 print "Test case name: normal sequence number stress test\n";
338 print "Test case purpose: check whether udevd can fork massive udev instances for \n";
339 print " massive sequential events successfully. \n";
340 print "Test expected visible results: \n";
341 print " Populate all the devices in directory $sysfs/class/tty, fork udved to send add/remove \n";
342 print " event to udev for each device. \n";
343 print " We can see the delay time for each device should be negligible. \n\n";
354 @file_list = glob "$sysfs/class/tty/*";
356 # log current system date/time for device add events
360 # add devices event test
362 print "add device events test: \n";
363 foreach $file (@file_list) {
364 udevsend($seq, substr($file, length($sysfs), length($file)-length($sysfs)), "add", "tty");
365 # check if execution is successful
369 print "add event: error\n\n";
374 # we'd better wait the udev to create all the device for a few seconds
375 print " wait for udevd processing about $time_out s... \n\n";
378 $ret_seq = check_count_and_time($time);
379 if ( $ret_seq != $seq ) {
380 print " add event: failed. some device-adding events fail to execute.\n\n";
383 print " $seq pieces of device-adding events have executed successfully.\n\n";
386 # log current system date/time for device remove events
390 # remove devices event test
392 print "remove device events test: \n";
394 @file_list = glob "$sysfs/class/tty/*";
396 foreach $file (@file_list) {
397 udevsend($seq, substr($file, length($sysfs), length($file)-length($sysfs)), "remove", "tty");
398 # check if execution is successful
402 print "remove event: error\n\n";
407 # we'd better wait the udev to create all the device for a few seconds
408 print " waiting for udev removing devices (about $time_out s)...\n";
412 $ret_seq = check_count_and_time($time);
413 if ( $ret_seq != $seq ) {
414 print " remove event: failed. some device-removing events fail to execute.\n\n";
417 print " $seq pieces of device-removing events have executed successfully.\n\n";
418 print "this case is ok.\n\n";
422 sub run_random_seq_test {
423 print "Test case name: random sequence number test case,\n";
424 print "Test case purpose: check whether udevd can order the events with random sequence number \n";
425 print " and fork udev correctly. \n";
426 print "Test expected visible results: \n";
427 print " We have disordered the events sent to udevd, if udevd can order them correctly, the devices' \n";
428 print " add/remove sequence should be tty0, tty1, tty2. \n\n";
433 # check if devices /class/tty/tty0, tty1, tty2 exist
434 check_sysfs_device_exist("$sysfs/class/tty/tty0", "$sysfs/class/tty/tty1", "$sysfs/class/tty/tty2");
437 # add device events test
439 print "add device events test: \n";
442 # log current system date/time for device remove events
445 # parameters: 1 sequence number, 2 device, 3 action, 4 subsystem
446 udevsend(3, "/class/tty/tty2", "add", "tty");
447 udevsend(1, "/class/tty/tty0", "add", "tty");
448 udevsend(2, "/class/tty/tty1", "add", "tty");
449 print " wait for udevd processing about $time_out s... \n\n";
451 show_result_tm_out($time);
454 # remove device events test
456 print "\nremove device events test: \n";
459 # log current system date/time for device remove events
463 udevsend(3, "/class/tty/tty2", "remove", "tty");
464 udevsend(2, "/class/tty/tty1", "remove", "tty");
465 udevsend(1, "/class/tty/tty0", "remove", "tty");
468 print " wait for udevd processing about $time_out s... \n\n";
470 show_result_tm_out($time);
471 print "this case is ok.\n\n";
474 sub run_expected_seq_test {
475 print "Test case name: expected sequence number test \n";
476 print "Test case purpose: check whether udevd fork udev immediately when the incoming event\n";
477 print " is exactly the expected event sequence number.\n";
478 print "Test expected visible results:\n";
479 print " first, udevd disposes disorder events(sequence number is 3,1,2,5,4,6),\n";
480 print " thus after disposed the expected event number for udevd is 7, when incoming event is 7, udevd\n";
481 print " should fork udev immediately, the delay time should be negligible. \n";
482 print " where: event 7 is (add device /class/tty/tty2) \n\n";
487 # check if devices /class/tty0, tty1, tty2 exist
488 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";
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";
536 # check if device exists
537 check_sysfs_device_exist("$sysfs/block/sda");
539 # log current system date/time
543 udevsend(-1, "/block/sda", "add", "block", $udev_bin2);
544 udevsend(-1, "/block/sda", "remove", "block", $udev_bin2);
547 print " wait for udevd processing about $udev_exe_time s... \n\n";
548 sleep $udev_exe_time+1;
549 show_result_immediate($time);
551 print "this case is ok\n\n";
554 sub run_same_events_test {
555 print "Test case name: event sequence number overlap test \n";
556 print "Test case purpose: check whether udevd doesn't fork udev untill time out\n";
557 print " when encountering a event with sequence number same as the pevious event. \n";
558 print "Test expected visible results:\n";
559 print " event ( remove device /block/sda ) should be no delay, \n";
560 print " event ( add device /class/tty/tty1 ) should be delayed for $time_out s than its previous \n";
561 print " event ( remove device /block/sda ) \n\n";
569 # check if device exist
570 check_sysfs_device_exist("$sysfs/block/sda", "$sysfs/class/tty/tty1");
573 udevsend(0, "/block/sda", "add", "block");
575 # log current system date/time
578 system("rm -f $log_file");
581 udevsend(1, "/block/sda", "remove", "block");
582 udevsend(1, "/class/tty/tty1", "add", "tty");
585 print " wait for udevd processing about $time_out s... \n\n";
588 print "this case is ok\n\n";
591 sub run_missing_seq_test {
592 print "Test case name: missing sequence number test \n";
593 print "Test case purpose: check whether udevd doesn't fork udev untill time out\n";
594 print " when certain event sequence number is missing.\n";
595 print "Test expected visible results:\n";
596 print " the delay time for event(add device /block/sda) should be about $time_out s.\n\n";
604 # check if device exist
605 check_sysfs_device_exist("$sysfs/block/sda", "$sysfs/class/tty/tty1");
608 udevsend(0, "/class/tty/tty1", "add", "tty");
609 udevsend(1, "/class/tty/tty1", "remove", "tty");
612 # log current system date/time
614 system("rm -f $log_file");
617 udevsend(3, "/block/sda", "add", "block");
620 print " wait for udevd processing about $time_out s... \n\n";
623 print "this case is ok\n\n";
626 sub run_all_cases_test {
628 run_normal_seq_test();
629 run_random_seq_test();
630 run_missing_seq_test();
631 run_expected_seq_test();
632 run_same_events_test();
633 run_single_instance_test();
638 $test_case = $ARGV[0];
640 if ($test_case == 1) {
642 } elsif ($test_case == 2) {
643 run_normal_seq_test();
644 } elsif ($test_case == 3) {
645 run_random_seq_test();
646 } elsif ($test_case == 4) {
647 run_missing_seq_test();
648 } elsif ($test_case == 5) {
649 run_expected_seq_test();
650 } elsif ($test_case == 6) {
651 run_single_instance_test();
652 } elsif ($test_case == 7) {
653 run_same_events_test();
655 run_all_cases_test();
659 print "command format: perl udevd-test.pl <case number>\n";
660 print " test case:\n";
661 print " 1: no event sequence number\n";
662 print " 2: sequential event sequence number\n";
663 print " 3: random event sequence number\n";
664 print " 4: missing event sequence number\n";
665 print " 5: the incoming event sequence number is right the expected sequence number\n";
666 print " 6: single udev instance on a single device at the same time\n";
667 print " 7: test event sequence number overlap\n";
668 print " 9: all the cases\n\n";