diff options
-rwxr-xr-x | tools/testing/ktest/ktest.pl | 409 |
1 files changed, 388 insertions, 21 deletions
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 7b6f8e1a82a4..0d1080548ea6 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 | ||
948 | sub run_bisect { | 947 | # returns 1 on success, 0 on failure |
949 | my ($type) = @_; | 948 | sub 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 | |||
998 | sub 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 | ||
1009 | sub bisect { | 1022 | sub 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 | |||
1125 | my %config_ignore; | ||
1126 | my %config_set; | ||
1127 | |||
1128 | my %config_list; | ||
1129 | my %null_config; | ||
1130 | |||
1131 | my %dependency; | ||
1132 | |||
1133 | sub 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 | |||
1148 | sub 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 | |||
1169 | sub 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 | |||
1187 | sub 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 | |||
1211 | sub 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 | |||
1231 | sub run_config_bisect_test { | ||
1232 | my ($type) = @_; | ||
1233 | |||
1234 | return run_bisect_test $type, "oldconfig"; | ||
1235 | } | ||
1236 | |||
1237 | sub 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 | |||
1252 | sub process_failed { | ||
1253 | my ($config) = @_; | ||
1254 | |||
1255 | doprint "\n\n***************************************\n"; | ||
1256 | doprint "Found bad config: $config\n"; | ||
1257 | doprint "***************************************\n\n"; | ||
1258 | } | ||
1259 | |||
1260 | sub 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 | |||
1361 | sub 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; |