summaryrefslogtreecommitdiffstats
path: root/tools/isolate/trace_inputs_test.py
blob: 77c6bdc6bd86fb55b03dd8c99b28ec628c9a349b (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
#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import logging
import os
import shutil
import subprocess
import sys
import tempfile
import unittest

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

VERBOSE = False


class CalledProcessError(subprocess.CalledProcessError):
  """Makes 2.6 version act like 2.7"""
  def __init__(self, returncode, cmd, output, cwd):
    super(CalledProcessError, self).__init__(returncode, cmd)
    self.output = output
    self.cwd = cwd

  def __str__(self):
    return super(CalledProcessError, self).__str__() + (
        '\n'
        'cwd=%s\n%s') % (self.cwd, self.output)


class TraceInputs(unittest.TestCase):
  def setUp(self):
    self.tempdir = tempfile.mkdtemp()
    self.log = os.path.join(self.tempdir, 'log')

  def tearDown(self):
    shutil.rmtree(self.tempdir)

  def _execute(self, args):
    cmd = [
      sys.executable, os.path.join(ROOT_DIR, 'trace_inputs.py'),
      '--log', self.log,
      '--root-dir', ROOT_DIR,
    ] + args
    p = subprocess.Popen(
        cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=ROOT_DIR)
    out = p.communicate()[0]
    if p.returncode:
      raise CalledProcessError(p.returncode, cmd, out, ROOT_DIR)
    return out

  @staticmethod
  def _gyp():
    return [
      '--gyp', os.path.join('data', 'trace_inputs'),
      '--product', '.',  # Not tested.
    ]

  def test_trace(self):
    if sys.platform not in ('linux2', 'darwin'):
      print 'WARNING: unsupported: %s' % sys.platform
      return
    expected_end = [
      "Interesting: 4 reduced to 3",
      "  data/trace_inputs/",
      "  trace_inputs.py",
      "  trace_inputs_test.py",
    ]
    actual = self._execute(['trace_inputs_test.py', '--child1']).splitlines()
    self.assertTrue(actual[0].startswith('Tracing... ['))
    self.assertTrue(actual[1].startswith('Loading traces... '))
    self.assertTrue(actual[2].startswith('Total: '))
    self.assertEquals("Non existent: 0", actual[3])
    # Ignore any Unexpected part.
    # TODO(maruel): Make sure there is no Unexpected part, even in the case of
    # virtualenv usage.
    self.assertEquals(expected_end, actual[-len(expected_end):])

  def test_trace_gyp(self):
    if sys.platform not in ('linux2', 'darwin'):
      print 'WARNING: unsupported: %s' % sys.platform
      return
    expected = (
        "{\n"
        "  'variables': {\n"
        "    'isolate_files': [\n"
        "      '<(DEPTH)/trace_inputs.py',\n"
        "      '<(DEPTH)/trace_inputs_test.py',\n"
        "    ],\n"
        "    'isolate_dirs': [\n"
        "      './',\n"
        "    ],\n"
        "  },\n"
        "},\n")
    actual = self._execute(self._gyp() + ['trace_inputs_test.py', '--child1'])
    self.assertEquals(expected, actual)


def child1():
  print 'child1'
  # Implicitly force file opening.
  import trace_inputs  # pylint: disable=W0612
  # Do not wait for the child to exit.
  # Use relative directory.
  subprocess.Popen(
      ['python', 'child2.py'], cwd=os.path.join('data', 'trace_inputs'))
  return 0


def main():
  global VERBOSE
  VERBOSE = '-v' in sys.argv
  level = logging.DEBUG if VERBOSE else logging.ERROR
  logging.basicConfig(level=level)
  if len(sys.argv) == 1:
    unittest.main()

  if sys.argv[1] == '--child1':
    return child1()

  unittest.main()


if __name__ == '__main__':
  sys.exit(main())