<commit_before># BenchExec is a framework for reliable benchmarking.
# This file is part of BenchExec.
#
# Copyright (C) 2007-2015  <NAME>
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# prepare for Python 3
from __future__ import absolute_import, division, print_function, unicode_literals

import glob
import logging
import os
import re
import subprocess
import sys
import tempfile
import threading
import time
import unittest
import shutil
sys.dont_write_bytecode = True # prevent creation of .pyc files

from benchexec import container
from benchexec import containerexecutor
from benchexec import filehierarchylimit
from benchexec.runexecutor import RunExecutor
from benchexec import runexecutor
from benchexec import util

try:
    from subprocess import DEVNULL
except ImportError:
    DEVNULL = open(os.devnull, 'wb')

try:
    unichr(0)
except NameError:
    unichr = chr

here = os.path.dirname(__file__)
base_dir = os.path.join(here, '..')
bin_dir = os.path.join(base_dir, 'bin')
runexec = os.path.join(bin_dir, 'runexec')
python = 'python2' if sys.version_info[0] == 2 else 'python3'

class TestRunExecutor(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.longMessage = True
        cls.maxDiff = None
        logging.disable(logging.CRITICAL)
        if not hasattr(cls, 'assertRegex'):
            cls.assertRegex = cls.assertRegexpMatches
        if not hasattr(cls, 'assertRaisesRegex'):
            cls.assertRaisesRegex = cls.assertRaisesRegexp

    def setUp(self, *args, **kwargs):
        self.runexecutor = RunExecutor(*args, **kwargs)

    def execute_run(self, *args, **kwargs):
        (output_fd, output_filename) = tempfile.mkstemp('.log', 'output_', text=True)
        try:
            result = self.runexecutor.execute_run(list(args), output_filename, **kwargs)
            output_lines = os.read(output_fd, 4096).decode().splitlines()
            return (result, output_lines)
        finally:
            os.close(output_fd)
            os.remove(output_filename)

    def execute_run_extern(self, *args, **kwargs):
        (output_fd, output_filename) = tempfile.mkstemp('.log', 'output_', text=True)
        try:
            runexec_output = subprocess.check_output(
                    args=[python, runexec] + list(args) + ['--output', output_filename],
                    stderr=DEVNULL,
                    **kwargs
                    ).decode()
            output_lines = os.read(output_fd, 4096).decode().splitlines()
        except subprocess.CalledProcessError as e:
            print(e.output.decode())
            raise e
        finally:
            os.close(output_fd)
            os.remove(output_filename)

        result={key.strip(): value.strip() for (key, _, value) in (line.partition('=') for line in runexec_output.splitlines())}
        return (result, output_lines)

    def check_command_in_output(self, output, cmd):
        self.assertEqual(output[0], cmd, 'run output misses executed command')

    def check_result_keys(self, result, *additional_keys):
        expected_keys = {'cputime', 'walltime', 'memory', 'exitcode',
                         'cpuenergy',
                         'blkio-read', 'blkio-write',
                         }
        expected_keys.update(additional_keys)
        for key in result.keys():
            if key.startswith('cputime-cpu'):
                self.assertRegex(key, '^cputime-cpu[0-9]+$',
                                 "unexpected result entry '{}={}'".format(key, result[key]))
            elif key.startswith('cpuenergy-'):
                self.assertRegex(key, '^cpuenergy-pkg[0-9]+(-(core|uncore|dram))?$',
                                 "unexpected result entry '{}={}'".format(key, result[key]))
            else:
                self.assertIn(key, expected_keys,
                              "unexpected result entry '{}={}'".format(key, result[key]))

    def check_exitcode(self, result, exitcode, msg=None):
        self.assertEqual(int(result['exitcode']), exitcode, msg)

    def test_command_output(self):
        if not os.path.exists('/bin/echo'):
            self.skipTest('missing /bin/echo')
        (_, output) = self.execute_run('/bin/echo', 'TEST_TOKEN')
        self.check_command_in_output(output, '/bin/echo TEST_TOKEN')
        self.assertEqual(output[-1], 'TEST_TOKEN', 'run output misses command output')
        for line in output[1:-1]:
            self.assertRegex(line, '^-*$', 'unexpected text in run output')

    def test_command_error_output(self):
        if not os.path.exists('/bin/echo'):
            self.skipTest('missing /bin/echo')
        if not os.path.exists('/bin/sh'):
            self.skipTest('missing /bin/sh')

        def execute_Run_intern(cmd):
            (output_fd, output_filename) = tempfile.mkstemp('.log', 'output_', text=True)
            (error_fd, error_filename) = tempfile.mkstemp('.log', 'error_', text=True)
            try:
                self.runexecutor.execute_run(cmd,
                                             output_filename=output_filename,
                                             error_filename=error_filename)
                output_lines = os.read(output_fd, 4096).decode().splitlines()
                error_lines = os.read(error_fd, 4096).decode().splitlines()
                return (output_lines, error_lines)
            finally:
                os.close(output_fd)
                os.remove(output_filename)
                os.close(error_fd)
                os.remove(error_filename)

        (output_lines, error_lines) = execute_Run_intern(['/bin/sh', '-c', '""/bin/echo ERROR_TOKEN >&2""'])
        self.assertEqual(error_lines[-1], 'ERROR_TOKEN', 'run error output misses command output')
        for line in output_lines[1:]:
            self.assertRegex(line, '^-*$', 'unexpected text in run output')
        for line in error_lines[1:-1]:
            self.assertRegex(line, '^-*$', 'unexpected text in run error output')

        (output_lines, error_lines) = execute_Run_intern(['/bin/echo', 'OUT_TOKEN'])
        self.check_command_in_output(output_lines, '/bin/echo OUT_TOKEN')
        self.check_command_in_output(error_lines, '/bin/echo OUT_TOKEN')
        self.assertEqual(output_lines[-1], 'OUT_TOKEN', 'run output misses command output')
        for line in output_lines[1:-1]:
            self.assertRegex(line, '^-*$', 'unexpected text in run output')
        for line in error_lines[1:]:
            self.assertRegex(line, '^-*$', 'unexpected text in run error output')
<commit_msg>Fix test from #274: It did not work when executed in /tmp<commit_after># BenchExec is a framework for reliable benchmarking.
# This file is part of BenchExec.
#
# Copyright (C) 2007-2015  <NAME>
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# prepare for Python 3
from __future__ import absolute_import, division, print_function, unicode_literals

import glob
import logging
import os
import re
import subprocess
import sys
import tempfile
import threading
import time
import unittest
import shutil
sys.dont_write_bytecode = True # prevent creation of .pyc files

from benchexec import container
from benchexec import containerexecutor
from benchexec import filehierarchylimit
from benchexec.runexecutor import RunExecutor
from benchexec import runexecutor
from benchexec import util

try:
    from subprocess import DEVNULL
except ImportError:
    DEVNULL = open(os.devnull, 'wb')

try:
    unichr(0)
except NameError:
    unichr = chr

here = os.path.dirname(__file__)
base_dir = os.path.join(here, '..')
bin_dir = os.path.join(base_dir, 'bin')
runexec = os.path.join(bin_dir, 'runexec')
python = 'python2' if sys.version_info[0] == 2 else 'python3'

class TestRunExecutor(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.longMessage = True
        cls.maxDiff = None
        logging.disable(logging.CRITICAL)
        if not hasattr(cls, 'assertRegex'):
            cls.assertRegex = cls.assertRegexpMatches
        if not hasattr(cls, 'assertRaisesRegex'):
            cls.assertRaisesRegex = cls.assertRaisesRegexp

    def setUp(self, *args, **kwargs):
        self.runexecutor = RunExecutor(*args, **kwargs)

    def execute_run(self, *args, **kwargs):
        (output_fd, output_filename) = tempfile.mkstemp('.log', 'output_', text=True)
        try:
            result = self.runexecutor.execute_run(list(args), output_filename, **kwargs)
            output_lines = os.read(output_fd, 4096).decode().splitlines()
            return (result, output_lines)
        finally:
            os.close(output_fd)
            os.remove(output_filename)

    def execute_run_extern(self, *args, **kwargs):
        (output_fd, output_filename) = tempfile.mkstemp('.log', 'output_', text=True)
        try:
            runexec_output = subprocess.check_output(
                    args=[python, runexec] + list(args) + ['--output', output_filename],
                    stderr=DEVNULL,
                    **kwargs
                    ).decode()
            output_lines = os.read(output_fd, 4096).decode().splitlines()
        except subprocess.CalledProcessError as e:
            print(e.output.decode())
            raise e
        finally:
            os.close(output_fd)
            os.remove(output_filename)

        result={key.strip(): value.strip() for (key, _, value) in (line.partition('=') for line in runexec_output.splitlines())}
        return (result, output_lines)

    def check_command_in_output(self, output, cmd):
        self.assertEqual(output[0], cmd, 'run output misses executed command')

    def check_result_keys(self, result, *additional_keys):
        expected_keys = {'cputime', 'walltime', 'memory', 'exitcode',
                         'cpuenergy',
                         'blkio-read', 'blkio-write',
                         }
        expected_keys.update(additional_keys)
        for key in result.keys():
            if key.startswith('cputime-cpu'):
                self.assertRegex(key, '^cputime-cpu[0-9]+$',
                                 "unexpected result entry '{}={}'".format(key, result[key]))
            elif key.startswith('cpuenergy-'):
                self.assertRegex(key, '^cpuenergy-pkg[0-9]+(-(core|uncore|dram))?$',
                                 "unexpected result entry '{}={}'".format(key, result[key]))
            else:
                self.assertIn(key, expected_keys,
                              "unexpected result entry '{}={}'".format(key, result[key]))

    def check_exitcode(self, result, exitcode, msg=None):
        self.assertEqual(int(result['exitcode']), exitcode, msg)

    def test_command_output(self):
        if not os.path.exists('/bin/echo'):
            self.skipTest('missing /bin/echo')
        (_, output) = self.execute_run('/bin/echo', 'TEST_TOKEN')
        self.check_command_in_output(output, '/bin/echo TEST_TOKEN')
        self.assertEqual(output[-1], 'TEST_TOKEN', 'run output misses command output')
        for line in output[1:-1]:
            self.assertRegex(line, '^-*$', 'unexpected text in run output')

    def test_command_error_output(self):
        if not os.path.exists('/bin/echo'):
            self.skipTest('missing /bin/echo')
        if not os.path.exists('/bin/sh'):
            self.skipTest('missing /bin/sh')

        def execute_Run_intern(*args, **kwargs):
            (error_fd, error_filename) = tempfile.mkstemp('.log', 'error_', text=True)
            try:
                (_, output_lines) = self.execute_run(*args, **kwargs, error_filename=error_filename)
                error_lines = os.read(error_fd, 4096).decode().splitlines()
                return (output_lines, error_lines)
            finally:
                os.close(error_fd)
                os.remove(error_filename)

        (output_lines, error_lines) = execute_Run_intern('/bin/sh', '-c', '/bin/echo ERROR_TOKEN >&2')
        self.assertEqual(error_lines[-1], 'ERROR_TOKEN', 'run error output misses command output')
        for line in output_lines[1:]:
            self.assertRegex(line, '^-*$', 'unexpected text in run output')
        for line in error_lines[1:-1]:
            self.assertRegex(line, '^-*$', 'unexpected text in run error output')

        (output_lines, error_lines) = execute_Run_intern('/bin/echo', 'OUT_TOKEN')
        self.check_command_in_output(output_lines, '/bin/echo OUT_TOKEN')
        self.check_command_in_output(error_lines, '/bin/echo OUT_TOKEN')
        self.assertEqual(output_lines[-1], 'OUT_TOKEN', 'run output misses command output')
        for line in output_lines[1:-1]:
            self.assertRegex(line, '^-*$', 'unexpected text in run output')
        for line in error_lines[1:]:
            self.assertRegex(line, '^-*$', 'unexpected text in run error output')

{'fraction_non_alphanumeric': 0.11922352600318702, 'fraction_numerical': 0.007315659858032739, 'mean_word_length': 2.6613630336780694, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '217027', 'n_tokens_mistral': 4080, 'n_tokens_neox': 3979, 'n_words': 1009}