aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-11-08 11:14:10 -0500
committerSteven Rostedt <rostedt@goodmis.org>2010-11-18 11:23:11 -0500
commit0a05c769a9de554aefa773061c592c7054d5e7a0 (patch)
treefef21fc177ac4774ab9f6a5c3a9147f01982c01e /tools/testing
parente48c5293bde398e253f83fdd0247fb2bc71cc92f (diff)
ktest: Added config_bisect test type
Added the ability to do a config_bisect. It starts with a bad config and does the following loop. Enable half the configs. if none of the configs to check are not enabled (caused by missing dependencies) enable the other half. Run the test if the test passes, remove the configs from the check but enabled them for further tests (to satisfy dependencies). else Remove any config that was not enabled, as we have found a new config that can cause a failure. loop till we have only one config left. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'tools/testing')
-rwxr-xr-xtools/testing/ktest/ktest.pl409
1 files changed, 388 insertions, 21 deletions
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index 7b6f8e1a82a..0d1080548ea 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -106,7 +106,6 @@ sub set_value {
106 if (defined($opt{$lvalue})) { 106 if (defined($opt{$lvalue})) {
107 die "Error: Option $lvalue defined more than once!\n"; 107 die "Error: Option $lvalue defined more than once!\n";
108 } 108 }
109 $opt{$lvalue} = $rvalue;
110 if ($rvalue =~ /^\s*$/) { 109 if ($rvalue =~ /^\s*$/) {
111 delete $opt{$lvalue}; 110 delete $opt{$lvalue};
112 } else { 111 } else {
@@ -945,20 +944,18 @@ sub run_git_bisect {
945 return 1; 944 return 1;
946} 945}
947 946
948sub run_bisect { 947# returns 1 on success, 0 on failure
949 my ($type) = @_; 948sub run_bisect_test {
949 my ($type, $buildtype) = @_;
950 950
951 my $failed = 0; 951 my $failed = 0;
952 my $result; 952 my $result;
953 my $output; 953 my $output;
954 my $ret; 954 my $ret;
955 955
956 if (defined($minconfig)) { 956 $in_bisect = 1;
957 build "useconfig:$minconfig" or $failed = 1; 957
958 } else { 958 build $buildtype or $failed = 1;
959 # ?? no config to use?
960 build "oldconfig" or $failed = 1;
961 }
962 959
963 if ($type ne "build") { 960 if ($type ne "build") {
964 dodie "Failed on build" if $failed; 961 dodie "Failed on build" if $failed;
@@ -980,7 +977,7 @@ sub run_bisect {
980 } 977 }
981 978
982 if ($failed) { 979 if ($failed) {
983 $result = "bad"; 980 $result = 0;
984 981
985 # reboot the box to a good kernel 982 # reboot the box to a good kernel
986 if ($type ne "build") { 983 if ($type ne "build") {
@@ -991,19 +988,35 @@ sub run_bisect {
991 end_monitor; 988 end_monitor;
992 } 989 }
993 } else { 990 } else {
994 $result = "good"; 991 $result = 1;
992 }
993 $in_bisect = 0;
994
995 return $result;
996}
997
998sub run_bisect {
999 my ($type) = @_;
1000 my $buildtype = "oldconfig";
1001
1002 # We should have a minconfig to use?
1003 if (defined($minconfig)) {
1004 $buildtype = "useconfig:$minconfig";
995 } 1005 }
996 1006
1007 my $ret = run_bisect_test $type, $buildtype;
1008
1009
997 # Are we looking for where it worked, not failed? 1010 # Are we looking for where it worked, not failed?
998 if ($reverse_bisect) { 1011 if ($reverse_bisect) {
999 if ($failed) { 1012 $ret = !$ret;
1000 $result = "good";
1001 } else {
1002 $result = "bad";
1003 }
1004 } 1013 }
1005 1014
1006 return $result; 1015 if ($ret) {
1016 return "good";
1017 } else {
1018 return "bad";
1019 }
1007} 1020}
1008 1021
1009sub bisect { 1022sub bisect {
@@ -1033,8 +1046,6 @@ sub bisect {
1033 $reverse_bisect = 0; 1046 $reverse_bisect = 0;
1034 } 1047 }
1035 1048
1036 $in_bisect = 1;
1037
1038 # Can't have a test without having a test to run 1049 # Can't have a test without having a test to run
1039 if ($type eq "test" && !defined($run_test)) { 1050 if ($type eq "test" && !defined($run_test)) {
1040 $type = "boot"; 1051 $type = "boot";
@@ -1108,7 +1119,359 @@ sub bisect {
1108 1119
1109 doprint "Bad commit was [$bisect_bad]\n"; 1120 doprint "Bad commit was [$bisect_bad]\n";
1110 1121
1111 $in_bisect = 0; 1122 success $i;
1123}
1124
1125my %config_ignore;
1126my %config_set;
1127
1128my %config_list;
1129my %null_config;
1130
1131my %dependency;
1132
1133sub process_config_ignore {
1134 my ($config) = @_;
1135
1136 open (IN, $config)
1137 or dodie "Failed to read $config";
1138
1139 while (<IN>) {
1140 if (/^(.*?(CONFIG\S*)(=.*| is not set))/) {
1141 $config_ignore{$2} = $1;
1142 }
1143 }
1144
1145 close(IN);
1146}
1147
1148sub read_current_config {
1149 my ($config_ref) = @_;
1150
1151 %{$config_ref} = ();
1152 undef %{$config_ref};
1153
1154 my @key = keys %{$config_ref};
1155 if ($#key >= 0) {
1156 print "did not delete!\n";
1157 exit;
1158 }
1159 open (IN, "$output_config");
1160
1161 while (<IN>) {
1162 if (/^(CONFIG\S+)=(.*)/) {
1163 ${$config_ref}{$1} = $2;
1164 }
1165 }
1166 close(IN);
1167}
1168
1169sub get_dependencies {
1170 my ($config) = @_;
1171
1172 my $arr = $dependency{$config};
1173 if (!defined($arr)) {
1174 return ();
1175 }
1176
1177 my @deps = @{$arr};
1178
1179 foreach my $dep (@{$arr}) {
1180 print "ADD DEP $dep\n";
1181 @deps = (@deps, get_dependencies $dep);
1182 }
1183
1184 return @deps;
1185}
1186
1187sub create_config {
1188 my @configs = @_;
1189
1190 open(OUT, ">$output_config") or dodie "Can not write to $output_config";
1191
1192 foreach my $config (@configs) {
1193 print OUT "$config_set{$config}\n";
1194 my @deps = get_dependencies $config;
1195 foreach my $dep (@deps) {
1196 print OUT "$config_set{$dep}\n";
1197 }
1198 }
1199
1200 foreach my $config (keys %config_ignore) {
1201 print OUT "$config_ignore{$config}\n";
1202 }
1203 close(OUT);
1204
1205# exit;
1206 run_command "$make oldnoconfig" or
1207 dodie "failed make config oldconfig";
1208
1209}
1210
1211sub compare_configs {
1212 my (%a, %b) = @_;
1213
1214 foreach my $item (keys %a) {
1215 if (!defined($b{$item})) {
1216 print "diff $item\n";
1217 return 1;
1218 }
1219 delete $b{$item};
1220 }
1221
1222 my @keys = keys %b;
1223 if ($#keys) {
1224 print "diff2 $keys[0]\n";
1225 }
1226 return -1 if ($#keys >= 0);
1227
1228 return 0;
1229}
1230
1231sub run_config_bisect_test {
1232 my ($type) = @_;
1233
1234 return run_bisect_test $type, "oldconfig";
1235}
1236
1237sub process_passed {
1238 my (%configs) = @_;
1239
1240 doprint "These configs had no failure: (Enabling them for further compiles)\n";
1241 # Passed! All these configs are part of a good compile.
1242 # Add them to the min options.
1243 foreach my $config (keys %configs) {
1244 if (defined($config_list{$config})) {
1245 doprint " removing $config\n";
1246 $config_ignore{$config} = $config_list{$config};
1247 delete $config_list{$config};
1248 }
1249 }
1250}
1251
1252sub process_failed {
1253 my ($config) = @_;
1254
1255 doprint "\n\n***************************************\n";
1256 doprint "Found bad config: $config\n";
1257 doprint "***************************************\n\n";
1258}
1259
1260sub run_config_bisect {
1261
1262 my @start_list = keys %config_list;
1263
1264 if ($#start_list < 0) {
1265 doprint "No more configs to test!!!\n";
1266 return -1;
1267 }
1268
1269 doprint "***** RUN TEST ***\n";
1270 my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"};
1271 my $ret;
1272 my %current_config;
1273
1274 my $count = $#start_list + 1;
1275 doprint " $count configs to test\n";
1276
1277 my $half = int($#start_list / 2);
1278
1279 do {
1280 my @tophalf = @start_list[0 .. $half];
1281
1282 create_config @tophalf;
1283 read_current_config \%current_config;
1284
1285 $count = $#tophalf + 1;
1286 doprint "Testing $count configs\n";
1287 my $found = 0;
1288 # make sure we test something
1289 foreach my $config (@tophalf) {
1290 if (defined($current_config{$config})) {
1291 logit " $config\n";
1292 $found = 1;
1293 }
1294 }
1295 if (!$found) {
1296 # try the other half
1297 doprint "Top half produced no set configs, trying bottom half\n";
1298 @tophalf = @start_list[$half .. $#start_list];
1299 create_config @tophalf;
1300 read_current_config \%current_config;
1301 foreach my $config (@tophalf) {
1302 if (defined($current_config{$config})) {
1303 logit " $config\n";
1304 $found = 1;
1305 }
1306 }
1307 if (!$found) {
1308 doprint "Failed: Can't make new config with current configs\n";
1309 foreach my $config (@start_list) {
1310 doprint " CONFIG: $config\n";
1311 }
1312 return -1;
1313 }
1314 $count = $#tophalf + 1;
1315 doprint "Testing $count configs\n";
1316 }
1317
1318 $ret = run_config_bisect_test $type;
1319
1320 if ($ret) {
1321 process_passed %current_config;
1322 return 0;
1323 }
1324
1325 doprint "This config had a failure.\n";
1326 doprint "Removing these configs that were not set in this config:\n";
1327
1328 # A config exists in this group that was bad.
1329 foreach my $config (keys %config_list) {
1330 if (!defined($current_config{$config})) {
1331 doprint " removing $config\n";
1332 delete $config_list{$config};
1333 }
1334 }
1335
1336 @start_list = @tophalf;
1337
1338 if ($#start_list == 0) {
1339 process_failed $start_list[0];
1340 return 1;
1341 }
1342
1343 # remove half the configs we are looking at and see if
1344 # they are good.
1345 $half = int($#start_list / 2);
1346 } while ($half > 0);
1347
1348 # we found a single config, try it again
1349 my @tophalf = @start_list[0 .. 0];
1350
1351 $ret = run_config_bisect_test $type;
1352 if ($ret) {
1353 process_passed %current_config;
1354 return 0;
1355 }
1356
1357 process_failed $start_list[0];
1358 return 1;
1359}
1360
1361sub config_bisect {
1362 my ($i) = @_;
1363
1364 my $start_config = $opt{"CONFIG_BISECT[$i]"};
1365
1366 my $tmpconfig = "$tmpdir/use_config";
1367
1368 # Make the file with the bad config and the min config
1369 if (defined($minconfig)) {
1370 # read the min config for things to ignore
1371 run_command "cp $minconfig $tmpconfig" or
1372 dodie "failed to copy $minconfig to $tmpconfig";
1373 } else {
1374 unlink $tmpconfig;
1375 }
1376
1377 # Add other configs
1378 if (defined($addconfig)) {
1379 run_command "cat $addconfig >> $tmpconfig" or
1380 dodie "failed to append $addconfig";
1381 }
1382
1383 my $defconfig = "";
1384 if (-f $tmpconfig) {
1385 $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig";
1386 process_config_ignore $tmpconfig;
1387 }
1388
1389 # now process the start config
1390 run_command "cp $start_config $output_config" or
1391 dodie "failed to copy $start_config to $output_config";
1392
1393 # read directly what we want to check
1394 my %config_check;
1395 open (IN, $output_config)
1396 or dodie "faied to open $output_config";
1397
1398 while (<IN>) {
1399 if (/^((CONFIG\S*)=.*)/) {
1400 $config_check{$2} = $1;
1401 }
1402 }
1403 close(IN);
1404
1405 # Now run oldconfig with the minconfig (and addconfigs)
1406 run_command "$defconfig $make oldnoconfig" or
1407 dodie "failed make config oldconfig";
1408
1409 # check to see what we lost (or gained)
1410 open (IN, $output_config)
1411 or dodie "Failed to read $start_config";
1412
1413 my %removed_configs;
1414 my %added_configs;
1415
1416 while (<IN>) {
1417 if (/^((CONFIG\S*)=.*)/) {
1418 # save off all options
1419 $config_set{$2} = $1;
1420 if (defined($config_check{$2})) {
1421 if (defined($config_ignore{$2})) {
1422 $removed_configs{$2} = $1;
1423 } else {
1424 $config_list{$2} = $1;
1425 }
1426 } elsif (!defined($config_ignore{$2})) {
1427 $added_configs{$2} = $1;
1428 $config_list{$2} = $1;
1429 }
1430 }
1431 }
1432 close(IN);
1433
1434 my @confs = keys %removed_configs;
1435 if ($#confs >= 0) {
1436 doprint "Configs overridden by default configs and removed from check:\n";
1437 foreach my $config (@confs) {
1438 doprint " $config\n";
1439 }
1440 }
1441 @confs = keys %added_configs;
1442 if ($#confs >= 0) {
1443 doprint "Configs appearing in make oldconfig and added:\n";
1444 foreach my $config (@confs) {
1445 doprint " $config\n";
1446 }
1447 }
1448
1449 my %config_test;
1450 my $once = 0;
1451
1452 # Sometimes kconfig does weird things. We must make sure
1453 # that the config we autocreate has everything we need
1454 # to test, otherwise we may miss testing configs, or
1455 # may not be able to create a new config.
1456 # Here we create a config with everything set.
1457 create_config (keys %config_list);
1458 read_current_config \%config_test;
1459 foreach my $config (keys %config_list) {
1460 if (!defined($config_test{$config})) {
1461 if (!$once) {
1462 $once = 1;
1463 doprint "Configs not produced by kconfig (will not be checked):\n";
1464 }
1465 doprint " $config\n";
1466 delete $config_list{$config};
1467 }
1468 }
1469 my $ret;
1470 do {
1471 $ret = run_config_bisect;
1472 } while (!$ret);
1473
1474 return $ret if ($ret < 0);
1112 1475
1113 success $i; 1476 success $i;
1114} 1477}
@@ -1341,7 +1704,6 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
1341 $dmesg = "$tmpdir/dmesg-$machine"; 1704 $dmesg = "$tmpdir/dmesg-$machine";
1342 $make = "$makecmd O=$outputdir"; 1705 $make = "$makecmd O=$outputdir";
1343 $output_config = "$outputdir/.config"; 1706 $output_config = "$outputdir/.config";
1344 $output_config = "$outputdir/.config";
1345 1707
1346 if ($reboot_type eq "grub") { 1708 if ($reboot_type eq "grub") {
1347 dodie "GRUB_MENU not defined" if (!defined($grub_menu)); 1709 dodie "GRUB_MENU not defined" if (!defined($grub_menu));
@@ -1354,6 +1716,8 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
1354 $run_type = $opt{"PATCHCHECK_TYPE[$i]"}; 1716 $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
1355 } elsif ($test_type eq "bisect") { 1717 } elsif ($test_type eq "bisect") {
1356 $run_type = $opt{"BISECT_TYPE[$i]"}; 1718 $run_type = $opt{"BISECT_TYPE[$i]"};
1719 } elsif ($test_type eq "config_bisect") {
1720 $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"};
1357 } 1721 }
1358 1722
1359 # mistake in config file? 1723 # mistake in config file?
@@ -1385,6 +1749,9 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
1385 if ($test_type eq "bisect") { 1749 if ($test_type eq "bisect") {
1386 bisect $i; 1750 bisect $i;
1387 next; 1751 next;
1752 } elsif ($test_type eq "config_bisect") {
1753 config_bisect $i;
1754 next;
1388 } elsif ($test_type eq "patchcheck") { 1755 } elsif ($test_type eq "patchcheck") {
1389 patchcheck $i; 1756 patchcheck $i;
1390 next; 1757 next;