<commit_before>#!/usr/bin/env python

#  Copyright 2014 Nokia Solutions and Networks Oyj
#
#  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.

import os, sys, time, datetime
import multiprocessing
from glob import glob
from StringIO import StringIO
import shutil
import subprocess
from robot import run, rebot
from robot import __version__ as ROBOT_VERSION
from robot.api import ExecutionResult
from robot.result.visitor import ResultVisitor
from multiprocessing.pool import ThreadPool
from robot.run import USAGE
from robot.utils import ArgumentParser
import signal

CTRL_C_PRESSED = False

def execute_and_wait_with(args):
    global CTRL_C_PRESSED
    if CTRL_C_PRESSED:
        # Keyboard interrupt has happened!
        return
    time.sleep(0)
    datasources, outs_dir, options, suite_name, command, verbose = args
    outs_dir = os.path.join(outs_dir, suite_name)
    cmd = command + _options_for_custom_executor(options, outs_dir, suite_name) + datasources
    cmd = [c if ' ' not in c else '"%s"' % c for c in cmd]

    process = subprocess.Popen(' '.join(cmd),
                          shell=True,
                          stderr=subprocess.PIPE,
                          stdout=subprocess.PIPE)
    if verbose:
        print '[PID:%s] EXECUTING PARALLEL SUITE %s with command:\n%s' % (process.pid, suite_name, ' '.join(cmd))
    else:
        print '[PID:%s] EXECUTING %s' % (process.pid, suite_name)
    rc = None
    while rc is None:
        rc = process.poll()
        time.sleep(0.1)
    if rc != 0:
        print _execution_failed_message(suite_name, process, rc, verbose)
    else:
        print 'PASSED %s' % suite_name

def _execution_failed_message(suite_name, process, rc, verbose):
    if not verbose:
        return 'FAILED %s' % suite_name
    msg = ['Execution failed in %s with %d failing test(s)' % (suite_name, rc)]
    stderr = process.stderr.read().strip()
    if stderr:
        msg += ['<< STDERR >>', stderr, '<< END OF STDERR >>']
    return '\n'.join(msg)

def _options_for_custom_executor(*args):
    return _options_to_cli_arguments(_options_for_executor(*args))

def _options_for_executor(options, outs_dir, suite_name):
    options = options.copy()
    options['log'] = 'NONE'
    options['report'] = 'NONE'
    options['suite'] = suite_name
    options['outputdir'] = outs_dir
    options['monitorcolors'] = 'off'
    if ROBOT_VERSION >= '2.8':<commit_msg>redirect stdout and stderr to files<commit_after>#!/usr/bin/env python

#  Copyright 2014 Nokia Solutions and Networks Oyj
#
#  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.

import os, sys, time, datetime
import multiprocessing
from glob import glob
from StringIO import StringIO
import shutil
import subprocess
from robot import run, rebot
from robot import __version__ as ROBOT_VERSION
from robot.api import ExecutionResult
from robot.result.visitor import ResultVisitor
from multiprocessing.pool import ThreadPool
from robot.run import USAGE
from robot.utils import ArgumentParser
import signal

CTRL_C_PRESSED = False


def execute_and_wait_with(args):
    global CTRL_C_PRESSED
    if CTRL_C_PRESSED:
        # Keyboard interrupt has happened!
        return
    time.sleep(0)
    datasources, outs_dir, options, suite_name, command, verbose = args
    outs_dir = os.path.join(outs_dir, suite_name)
    cmd = command + _options_for_custom_executor(options, outs_dir, suite_name) + datasources
    cmd = [c if ' ' not in c else '"%s"' % c for c in cmd]
    os.makedirs(outs_dir)
    with open(os.path.join(outs_dir, 'stdout.txt'), 'w') as stdout, \
        open(os.path.join(outs_dir, 'stderr.txt'), 'w') as stderr:
            process, rc = _run(cmd, stderr, stdout, suite_name, verbose)
    if rc != 0:
        print _execution_failed_message(suite_name, process, rc, verbose)
    else:
        print 'PASSED %s' % suite_name

def _run(cmd, stderr, stdout, suite_name, verbose):
    process = subprocess.Popen(' '.join(cmd),
                               shell=True,
                               stderr=stderr,
                               stdout=stdout)
    if verbose:
        print '[PID:%s] EXECUTING PARALLEL SUITE %s with command:\n%s' % (process.pid, suite_name, ' '.join(cmd))
    else:
        print '[PID:%s] EXECUTING %s' % (process.pid, suite_name)
    rc = None
    while rc is None:
        rc = process.poll()
        time.sleep(0.1)
    return process, rc

def _execution_failed_message(suite_name, process, rc, verbose):
    if not verbose:
        return 'FAILED %s' % suite_name
    return 'Execution failed in %s with %d failing test(s)' % (suite_name, rc)

def _options_for_custom_executor(*args):
    return _options_to_cli_arguments(_options_for_executor(*args))

def _options_for_executor(options, outs_dir, suite_name):
    options = options.copy()
    options['log'] = 'NONE'
    options['report'] = 'NONE'
    options['suite'] = suite_name
    options['outputdir'] = outs_dir
    options['monitorcolors'] = 'off'
    if ROBOT_VERSION >= '2.8':
{'fraction_non_alphanumeric': 0.09584237769243613, 'fraction_numerical': 0.0046752379362163966, 'mean_word_length': 3.3531976744186047, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4842646', 'n_tokens_mistral': 1874, 'n_tokens_neox': 1812, 'n_words': 596}