exec_tests.py 4.09 KB
Newer Older
1
import hashlib
2 3 4 5 6 7 8
import logging
import os
import shutil
from os import path
from mjtest.environment import TestMode, Environment
from mjtest.test.syntax_tests import BasicSyntaxTest
from mjtest.test.tests import TestCase, BasicDiffTestResult, BasicTestResult
9
from mjtest.util.shell import SigKill
10
from mjtest.util.utils import get_main_class_name
11 12 13 14 15 16 17 18 19 20

_LOG = logging.getLogger("exec_tests")

class JavaExecTest(BasicSyntaxTest):
    """
    The MiniJava compiler should behave the same as javac
    """

    FILE_ENDINGS = [".java"]
    OUTPUT_FILE_ENDING = ".out"
21
    MODE = TestMode.compile_firm
22 23 24 25

    def __init__(self, env: Environment, type: str, file: str, preprocessed_file: str):
        super().__init__(env, type, file, preprocessed_file)
        self._expected_output_file = file + self.OUTPUT_FILE_ENDING
26 27 28 29
        prev_out_dir = path.join(path.dirname(file), ".java_output")
        if not path.exists(prev_out_dir):
            os.mkdir(prev_out_dir)
        self._prev_out_file = path.join(prev_out_dir, path.basename(self._expected_output_file))
30
        self._prev_out_hash_file = self._prev_out_file + "_hash"
31
        self._has_expected_output_file = path.exists(self._expected_output_file)
32
        if not self._has_expected_output_file:
33 34
            if path.exists(self._prev_out_file) and path.exists(self._prev_out_hash_file) \
                    and self._check_hash_sum(self.preprocessed_file, self._prev_out_hash_file):
35 36 37
                self._has_expected_output_file = True
                self._expected_output_file = self._prev_out_file
                _LOG.info("Reuse old java output file \"{}\"".format(path.relpath(self._prev_out_file)))
38 39 40 41
        self._should_succeed = True

    def run(self) -> BasicDiffTestResult:
        base_filename = path.basename(self.file).split(".")[0]
42
        tmp_dir = self.env.create_pid_local_tmpdir()
43 44 45 46
        shutil.copy(self.preprocessed_file, path.join(tmp_dir, base_filename + ".java"))
        cwd = os.getcwd()
        os.chdir(tmp_dir)
        exp_out = None
47
        #print(base_filename, get_main_class_name(base_filename + ".java"))
48 49 50 51 52
        if not self._has_expected_output_file:
            _, _, javac_rtcode = \
                self.env.run_command("javac", base_filename + ".java")
            if javac_rtcode != 0:
                _LOG.error("File \"{}\" isn't valid Java".format(self.preprocessed_file))
53
                os.chdir(cwd)
54 55
                raise InterruptedError()
            exp_out, _, _ = \
56
                self.env.run_command("java", get_main_class_name(base_filename + ".java"))
57
            exp_out = exp_out.decode().strip()
58 59 60
            with open(self._prev_out_file, "w") as f:
                f.write(exp_out)
                f.flush()
61 62 63
            with open(self._prev_out_hash_file, "w") as f:
                f.write(self._hash_sum_for_file(base_filename + ".java"))
                f.flush()
64 65 66
        if self._has_expected_output_file and self.type == self.MODE and self.env.mode == self.MODE:
            with open(self._expected_output_file, "r") as f:
                exp_out = f.read()
67 68 69 70 71 72 73
        try:
            _, err, rtcode = self.env.run_mj_command(self.MODE, base_filename + ".java")
            out, _, _ = self.env.run_command("./" + base_filename)
            out = out.decode().strip()
            os.chdir(cwd)
            if self.type == self.MODE and self.env.mode == self.MODE:
                return BasicDiffTestResult(self, rtcode, out, err.decode(), exp_out)
Johannes Bechberger's avatar
Johannes Bechberger committed
74
            return BasicTestResult(self, rtcode, out, err.decode())
75 76 77
        except SigKill as sig:
            os.chdir(cwd)
            return BasicTestResult(self, sig.retcode, "", exp_out, sig.name)
78 79 80
        except:
            os.chdir(cwd)
            raise
81

82 83 84 85 86
    def _check_hash_sum(self, file: str, hash_sum_file: str) -> bool:
        old_hash = ""
        with open(hash_sum_file, "r") as f:
            old_hash = f.readline().strip()
        return self._hash_sum_for_file(file) == old_hash
87

88 89 90
    def _hash_sum_for_file(self, file: str) -> str:
        with open(file, "r") as f:
            return hashlib.sha256(f.read().encode()).hexdigest()
91

92
TestCase.TEST_CASE_CLASSES[TestMode.compile_firm].append(JavaExecTest)