Пример #1
0
#if (isset($setup_function)) {
#	if ($setup_function() == false)
#		return;
#}
if ($action == '') {
    do_frameset();
} elseif ($action == 'view_control_frame') {
    do_controls();
} elseif ($action == 'start') {
    do_start();
} elseif ($action == 'pause') {
    do_pause();
} elseif ($action == 'resume') {
    do_resume();
} elseif ($action == 'run') {
    do_run();
} elseif ($action == 'test') {
    echo "blah";
} elseif ($action == 'none') {
    echo "";
}
return;
##############################################################
function do_frameset()
{
    ?>
	<html>
	<head><title>Mail Blast</title></head>
	<frameset cols="160,*">
		<frame name="controls" src="<?php 
    echo $_SERVER['PHP_SELF'];
Пример #2
0
// Compile
if ($task['compile'] === "true") {
    $compile_result = do_compile($filelist, $exe_file, $compiler, $task['compiler_options'], $instance);
    if ($compile_result['status'] == COMPILE_SUCCESS) {
        update_status("STA002", "Compile succeeded");
    } else {
        update_status("STA003", "Compile failed");
        done();
    }
} else {
    $exe_file = $task['exe_file'];
    $debug_exe_file = $task['debug_exe_file'];
}
// Run
if ($task['run'] === "true") {
    $run_result = do_run($filelist, $exe_file, $task['running_params'], $compiler, $task['compiler_options'], $instance);
    // Debug
    if ($run_result['status'] == EXECUTION_CRASH && $task['debug'] === "true" && $debugger) {
        update_status("STA004", "Program crashed");
        // Recompile with debug compiler_options
        $compile_result_debug = do_compile($filelist, $debug_exe_file, $compiler, $task['compiler_options_debug'], $instance);
        // If compiler failed with compiler_options_debug but succeeded with compiler_options,
        // most likely options are bad... so we'll skip debugging
        if ($compile_result_debug['status'] === COMPILE_SUCCESS) {
            $debug_result = do_debug($debug_exe_file, $debugger, $run_result['core'], $filelist, $instance);
            update_status("STA006", "Program crashed - debugging finished");
            unlink($run_result['core']);
        }
    } else {
        update_status("STA005", "Program executed successfully");
    }
Пример #3
0
function do_test($filelist, $global_symbols, $test, $compiler, $debugger, $profiler, $task, $instance)
{
    global $conf_max_program_output, $conf_verbosity;
    $test_result = array();
    $test_result['status'] = TEST_SUCCESS;
    $test_result['run_result'] = array();
    $test_result['debug_result'] = array();
    $test_result['profile_result'] = array();
    if ($conf_verbosity > 0) {
        print "Testing...\n";
    }
    // Replacement strings
    $start_string = "====START_TEST_" . $test['id'] . "====";
    $end_string = "====END_TEST_" . $test['id'] . "====";
    $except_string = "====EXCEPTION_TEST_" . $test['id'] . "====";
    // Find symbols that are required by this test
    $includes = array();
    if (!empty($global_symbols)) {
        foreach ($test['require_symbols'] as $symbol) {
            $found = false;
            foreach ($global_symbols as $global => $file) {
                if ($symbol === $global) {
                    array_push($includes, $file);
                    $found = true;
                    break;
                }
            }
            if (!$found) {
                $test_result['status'] = TEST_SYMBOL_NOT_FOUND;
                $test_result['status_object'] = $symbol;
                if ($conf_verbosity > 0) {
                    print "- test " . $test['id'] . " failed - symbol not found ({$symbol})\n";
                }
                return $test_result;
            }
        }
    }
    // TODO symbol renaming
    // Construct a new source file with embedded test
    $main_source_code = $main_filename = "";
    if ($task['language'] == "C" || $task['language'] == "C++") {
        if (!array_key_exists("main", $global_symbols)) {
            // This is a bug in get_global_symbols, as a program without main wouldn't compile!
            $test_result['status'] = TEST_SYMBOL_NOT_FOUND;
            $test_result['status_object'] = "main";
            if ($conf_verbosity > 0) {
                print "- test " . $test['id'] . " failed - main not found\n";
            }
            return $test_result;
        }
        $main_filename = $global_symbols['main'];
        $main_source_code = file_get_contents($main_filename);
        // Rename main
        $newname = "_main";
        while (array_key_exists($newname, $global_symbols)) {
            $newname = "_{$newname}";
        }
        $newname = " {$newname}\${1}";
        $main_source_code = preg_replace("/\\smain(\\W)/", $newname, $main_source_code);
    }
    // Include files containing symbols we need
    $includes_code = "";
    foreach ($includes as $file) {
        if ($task['language'] == "C" || $task['language'] == "C++") {
            $includes_code .= "#include \"{$file}\"\n";
        }
        if ($task['language'] == "Python") {
            $import_file = basename(preg_replace("/\\.py\$/", "", $file));
            // Imported filenames must start with a letter in python
            if (!ctype_alpha($import_file[0])) {
                $import_file = "a" . $import_file;
                $new_file = dirname($file) . "/a" . basename($file);
                rename($file, $new_file);
            }
            $includes_code .= "from {$import_file} import *";
        }
    }
    // Also include stdin/stdout libraries cause they will surely be used in test
    if ($task['language'] == "C") {
        $includes_code .= "#include <stdio.h>\n";
    }
    if ($task['language'] == "C++") {
        $includes_code .= "#include <iostream>\nusing std::cin;\nusing std::cout;\nusing std::cerr;\nusing std::endl;\n";
    }
    // Construct test code
    $test_code = "";
    if ($task['language'] == "C") {
        $test_code .= "int main() {\nprintf(\"{$start_string}\");\n " . $test['code'] . "\n printf(\"{$end_string}\");\nreturn 0;\n}\n";
    } else {
        if ($task['language'] == "C++") {
            $test_code .= "int main() {\ntry {\n std::cout<<\"{$start_string}\";\n " . $test['code'] . "\n std::cout<<\"{$end_string}\";\n } catch (...) {\n std::cout<<\"{$except_string}\";\n }\nreturn 0;\n}\n";
        } else {
            if ($task['language'] == "Python") {
                $test_code .= "print(\"{$start_string}\")\n" . $test['code'] . "\nprint(\"{$end_string}\")\n";
            } else {
                $test_code = $test['code'];
            }
        }
    }
    // Prevent cheating
    $main_source_code = str_replace($start_string, "====cheat_protection====", $main_source_code);
    $main_source_code = str_replace($end_string, "====cheat_protection====", $main_source_code);
    $main_source_code = str_replace($except_string, "====cheat_protection====", $main_source_code);
    // Construct whole file
    $main_length = substr_count($main_source_code, "\n");
    $main_source_code = $includes_code . $test['global_top'] . "\n" . $main_source_code . "\n" . $test['global_above_main'] . "\n" . $test_code . "\n";
    // Choose filename for test
    $test_filename = "bs_test_" . $test['id'];
    if ($task['language'] == "C") {
        $test_filename .= ".c";
    }
    if ($task['language'] == "C++") {
        $test_filename .= ".cpp";
    }
    if ($task['language'] == "Python") {
        $test_filename .= ".py";
    }
    $test_path = instance_path($instance);
    if ($task['language'] == "C" || $task['language'] == "C++") {
        // Locate test file in the same path that mainfile used to be
        $test_path = dirname($main_filename);
    }
    while (in_array($test_path . "/" . $test_filename, $filelist)) {
        $test_filename = "_" . $test_filename;
    }
    $test_filename = $test_path . "/" . $test_filename;
    file_put_contents($test_filename, $main_source_code);
    // Add test file to filelist
    if ($task['language'] == "C" || $task['language'] == "C++") {
        for ($i = 0; $i < count($filelist); $i++) {
            if ($filelist[$i] === $global_symbols['main']) {
                $filelist[$i] = $test_filename;
            }
        }
    } else {
        if ($task['language'] == "Python") {
            // In python we execute just the test file and it includes everything else
            $filelist = array($test_filename);
        } else {
            array_push($filelist, $test_filename);
        }
    }
    // Calculate positions of original code and test code inside sources
    // that will be used to adjust output of compile/debug/profile to something user expects
    $adjustment_data = array();
    $adjustment_data['orig_filename'] = $main_filename;
    $adjustment_data['new_filename'] = $test_filename;
    $adjustment_data['global_top_pos'] = substr_count($includes_code, "\n");
    $adjustment_data['original_source_pos'] = $adjustment_data['global_top_pos'] + substr_count($test['global_top'], "\n") + 1;
    $adjustment_data['global_above_pos'] = $adjustment_data['original_source_pos'] + $main_length + 1;
    $adjustment_data['test_code_pos'] = $adjustment_data['global_above_pos'] + substr_count($test['global_above_main'], "\n") + 1;
    // number of lines added to main per language
    if ($task['language'] == "C") {
        $adjustment_data['test_code_pos'] += 2;
    }
    if ($task['language'] == "C++") {
        $adjustment_data['test_code_pos'] += 3;
    }
    if ($task['language'] == "Python") {
        $adjustment_data['test_code_pos'] += 1;
    }
    // === TESTING COMMENCE ===
    // Compile test
    $test_exe_file = instance_path($instance) . "/bs_test_" . $test['id'];
    $compile_result = do_compile($filelist, $test_exe_file, $compiler, $task['compiler_options_debug'], $instance);
    $test_result['compile_result'] = $compile_result;
    if ($compile_result['status'] !== COMPILE_SUCCESS) {
        $test_result['status'] = TEST_COMPILE_FAILED;
        if ($conf_verbosity > 0) {
            print "- test " . $test['id'] . " failed - compile error\n";
        }
        return $test_result;
    }
    // Execute test
    $run_result = do_run($filelist, $test_exe_file, $test['running_params'], $compiler, $task['compiler_options_debug'], $instance);
    $test_result['run_result'] = $run_result;
    $program_output = $run_result['output'];
    // Shortcut
    // Output was too long and it was cut off... let's pretend it finished ok
    if (strlen($program_output) >= $conf_max_program_output) {
        $program_output .= "\n{$end_string}\n";
    }
    // Find marker strings in program output
    $start_pos = strpos($program_output, $start_string);
    if ($start_pos !== false) {
        $start_pos += strlen($start_string);
    }
    $end_pos = strpos($program_output, $end_string);
    $except_pos = strpos($program_output, $except_string);
    // Remove marker strings from output
    if ($end_pos !== false) {
        $program_output = substr($program_output, $start_pos, $end_pos - $start_pos);
    } else {
        if ($except_pos !== false) {
            $program_output = substr($program_output, $start_pos, $except_pos - $start_pos);
        } else {
            if ($start_pos !== false) {
                $program_output = substr($program_output, $start_pos);
            }
        }
    }
    $test_result['run_result']['output'] = $program_output;
    if ($run_result['status'] === EXECUTION_TIMEOUT) {
        $test_result['status'] = TEST_EXECUTION_TIMEOUT;
        if ($conf_verbosity > 0) {
            print "- test " . $test['id'] . " failed - execution timeout\n";
        }
        // Profiler will simply execute even longer, so we don't go there
        return $test_result;
    }
    if ($run_result['status'] === EXECUTION_CRASH) {
        $test_result['status'] = TEST_EXECUTION_CRASH;
        // Use seldom: crashes are unreliable!
        if ($test['expected_crash'] === "true") {
            $test_result['status'] = TEST_SUCCESS;
            if ($conf_verbosity > 0) {
                print "- test " . $test['id'] . " ok (crash)\n";
            }
        } else {
            if ($conf_verbosity > 0) {
                print "- test " . $test['id'] . " failed - crash\n";
            }
        }
        // Debug in case of crash
        if ($debugger && $task['debug'] === "true") {
            $debug_result = do_debug($test_exe_file, $debugger, $run_result['core'], $filelist, $instance);
            // Adjust filenames and line numbers that were changed for the test
            foreach ($debug_result['parsed_output'] as &$msg) {
                if (instance_path($instance) . "/" . $msg['file'] === $adjustment_data['new_filename']) {
                    test_adjust_lines($msg['file'], $msg['line'], $adjustment_data, $instance);
                }
            }
            $test_result['debug_result'] = $debug_result;
        }
        unlink($run_result['core']);
        // If crash is unexpected, we will go on to profiler cause it can give some more information
        if ($test['expected_crash'] === "true") {
            return $test_result;
        }
    } else {
        // === FINDING EXPECTED OUTPUT IN PROGRAM OUTPUT ===
        // Remove invisible spaces in expected program output
        // Allow to specify newlines in expected output using \n
        foreach ($test['expected'] as &$ex) {
            $ex = str_replace("\r\n", "\n", $ex);
            $ex = str_replace("\\n", "\n", $ex);
            $ex = trim(preg_replace("/\\s+\n/", "\n", $ex));
        }
        // Program finished normally
        if ($start_pos !== false && $end_pos !== false) {
            if ($test['expected_exception'] === "true") {
                $test_result['status'] = TEST_WRONG_OUTPUT;
                if ($conf_verbosity > 0) {
                    print "- test " . $test['id'] . " failed - expected exception\n";
                }
                return $test_result;
            }
            $test_result['run_result']['output'] = $program_output;
            // Don't fail test because of invisible spaces and empty lines
            $program_output = preg_replace("/\\s+\n/", "\n", $program_output);
            $program_output = trim(preg_replace("/\n+/", "\n", $program_output));
            // Ignore whitespace
            if ($test['ignore_whitespace'] === "true") {
                $program_output = str_replace("\n", "", $program_output);
                $program_output = preg_replace("/\\s+/", "", $program_output);
                foreach ($test['expected'] as &$ex) {
                    $ex = preg_replace("/\\s+/", "", $ex);
                }
            }
            // Look for expected outputs in program output
            $test_ok = false;
            $exnr = 1;
            foreach ($test['expected'] as &$ex) {
                // Why do we need a reference here???
                if ($program_output == $ex) {
                    if ($conf_verbosity > 0) {
                        print "- test " . $test['id'] . " ok (exact match {$exnr})\n";
                    }
                    $test_ok = true;
                    break;
                } else {
                    if ($test['substring'] === "true" && strstr($program_output, $ex)) {
                        if ($conf_verbosity > 0) {
                            print "- test " . $test['id'] . " ok (substring {$exnr})\n";
                        }
                        $test_ok = true;
                        break;
                    } else {
                        if ($test['regex'] === "true" && preg_match("/{$ex}/", $program_output)) {
                            if ($conf_verbosity > 0) {
                                print "- test " . $test['id'] . " ok (regex {$exnr})\n";
                            }
                            $test_ok = true;
                            break;
                        }
                    }
                }
                $exnr++;
            }
            if (!$test_ok) {
                $test_result['status'] = TEST_WRONG_OUTPUT;
                if ($conf_verbosity > 0) {
                    print "- test " . $test['id'] . " failed\n";
                }
                if ($conf_verbosity > 2) {
                    print "Output:\n{$program_output}\nExpected:\n" . $test['expected'][0];
                }
                // We will continue to profiler as it may give us some explanation of result
            }
        } else {
            if ($start_pos !== false && $except_pos !== false) {
                // TODO check type of exception
                if ($test['expected_exception'] === "false") {
                    $test_result['status'] = TEST_UNEXPECTED_EXCEPTION;
                    if ($conf_verbosity > 0) {
                        print "- test " . $test['id'] . " failed - exception not expected\n";
                    }
                    // We won't continue to profiler because unexpected exception usually causes memleaks
                    // which won't exist after the reason for this exception is removed.
                    // Otherwise programmer might be confused that memleak caused the exception
                    return $test_result;
                }
                if ($conf_verbosity > 0) {
                    print "- test " . $test['id'] . " ok (exception)\n";
                }
            } else {
                $test_result['status'] = TEST_OUTPUT_NOT_FOUND;
                if ($conf_verbosity > 0) {
                    print "- test " . $test['id'] . " failed - output not found ({$start_pos}, {$end_pos}, {$except_pos})\n";
                }
            }
        }
    }
    // if ($run_result['status'] === EXECUTION_CRASH) { ... } else {
    // Profile
    if ($profiler && $task['profile'] === "true") {
        $profile_result = do_profile($test_exe_file, $profiler, $filelist, $test['running_params'], $instance);
        // Adjust filenames and line numbers that were changed for the test
        foreach ($profile_result['parsed_output'] as &$msg) {
            // Valgrind always returns just the base file name
            if ($msg['file'] === basename($adjustment_data['new_filename'])) {
                test_adjust_lines($msg['file'], $msg['line'], $adjustment_data, $instance);
            }
            if (array_key_exists('file_alloced', $msg) && instance_path($instance) . "/" . $msg['file_alloced'] === $adjustment_data['new_filename']) {
                test_adjust_lines($msg['file_alloced'], $msg['line_alloced'], $adjustment_data, $instance);
            }
        }
        // If there are no errors, we will disregard profiler output
        if ($profile_result['status'] !== PROFILER_OK) {
            $test_result['profile_result'] = $profile_result;
            if ($test_result['status'] === TEST_SUCCESS) {
                $test_result['status'] = TEST_PROFILER_ERROR;
                if ($conf_verbosity > 0) {
                    print "- test " . $test['id'] . " failed - profiler error\n";
                }
            }
        }
    }
    return $test_result;
}