Welcome to mirror list, hosted at ThFree Co, Russian Federation.

v8_commands.py « clusterfuzz « tools « v8 « deps - github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1956ef2802bc4f2d5bfc6c6788a530e86866fbf5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# Copyright 2016 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Fork from commands.py and output.py in v8 test driver.

import os
import signal
import subprocess
import sys
from threading import Event, Timer

import v8_fuzz_config

PYTHON3 = sys.version_info >= (3, 0)

# List of default flags passed to each d8 run.
DEFAULT_FLAGS = [
  '--correctness-fuzzer-suppressions',
  '--expose-gc',
  '--fuzzing',
  '--allow-natives-for-differential-fuzzing',
  '--invoke-weak-callbacks',
  '--omit-quit',
  '--es-staging',
  '--wasm-staging',
  '--no-wasm-async-compilation',
  '--suppress-asm-messages',
]

BASE_PATH = os.path.dirname(os.path.abspath(__file__))

# List of files passed to each d8 run before the testcase.
DEFAULT_MOCK = os.path.join(BASE_PATH, 'v8_mock.js')

# Suppressions on JavaScript level for known issues.
JS_SUPPRESSIONS = os.path.join(BASE_PATH, 'v8_suppressions.js')

# Config-specific mock files.
ARCH_MOCKS = os.path.join(BASE_PATH, 'v8_mock_archs.js')
WEBASSEMBLY_MOCKS = os.path.join(BASE_PATH, 'v8_mock_webassembly.js')

# Timeout in seconds for one d8 run.
TIMEOUT = 3


def _startup_files(options):
  """Default files and optional config-specific mock files."""
  files = [DEFAULT_MOCK]
  if not options.skip_suppressions:
    files.append(JS_SUPPRESSIONS)
  if options.first.arch != options.second.arch:
    files.append(ARCH_MOCKS)
  # Mock out WebAssembly when comparing with jitless mode.
  if '--jitless' in options.first.flags + options.second.flags:
    files.append(WEBASSEMBLY_MOCKS)
  return files


class Command(object):
  """Represents a configuration for running V8 multiple times with certain
  flags and files.
  """
  def __init__(self, options, label, executable, config_flags):
    self.label = label
    self.executable = executable
    self.config_flags = config_flags
    self.common_flags =  DEFAULT_FLAGS[:]
    self.common_flags.extend(['--random-seed', str(options.random_seed)])

    self.files = _startup_files(options)

  def run(self, testcase, verbose=False):
    """Run the executable with a specific testcase."""
    args = [self.executable] + self.flags + self.files + [testcase]
    if verbose:
      print('# Command line for %s comparison:' % self.label)
      print(' '.join(args))
    if self.executable.endswith('.py'):
      # Wrap with python in tests.
      args = [sys.executable] + args
    return Execute(
        args,
        cwd=os.path.dirname(os.path.abspath(testcase)),
        timeout=TIMEOUT,
    )

  @property
  def flags(self):
    return self.common_flags + self.config_flags


class Output(object):
  def __init__(self, exit_code, timed_out, stdout, pid):
    self.exit_code = exit_code
    self.timed_out = timed_out
    self.stdout = stdout
    self.pid = pid

  def HasCrashed(self):
    # Timed out tests will have exit_code -signal.SIGTERM.
    if self.timed_out:
      return False
    return (self.exit_code < 0 and
            self.exit_code != -signal.SIGABRT)

  def HasTimedOut(self):
    return self.timed_out


def Execute(args, cwd, timeout=None):
  popen_args = [c for c in args if c != ""]
  kwargs = {}
  if PYTHON3:
    kwargs['encoding'] = 'utf-8'
  try:
    process = subprocess.Popen(
      args=popen_args,
      stdout=subprocess.PIPE,
      stderr=subprocess.PIPE,
      cwd=cwd,
      **kwargs
    )
  except Exception as e:
    sys.stderr.write("Error executing: %s\n" % popen_args)
    raise e

  timeout_event = Event()

  def kill_process():
    timeout_event.set()
    try:
      process.kill()
    except OSError:
      sys.stderr.write('Error: Process %s already ended.\n' % process.pid)

  timer = Timer(timeout, kill_process)
  timer.start()
  stdout, _ = process.communicate()
  timer.cancel()

  return Output(
      process.returncode,
      timeout_event.is_set(),
      stdout,
      process.pid,
  )