Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / native_client / pnacl / driver / tests / path_length_test.py
1 #!/usr/bin/python
2 # Copyright (c) 2014 The Native Client Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """Tests of the pnacl driver.
7
8 This tests that we give useful errors when paths are too long, and don't
9 unnecessarily generate temp file names that are too long ourselves.
10
11 """
12
13 import driver_log
14 from driver_env import env
15 import driver_test_utils
16 import driver_tools
17
18 import cStringIO
19 import os
20 import shutil
21 import sys
22
23 class TestPathNames(driver_test_utils.DriverTesterCommon):
24   def setUp(self):
25     super(TestPathNames, self).setUp()
26     driver_test_utils.ApplyTestEnvOverrides(env)
27     self.backup_exit = sys.exit
28     sys.exit = driver_test_utils.FakeExit
29     cwd_len = len(os.getcwd())
30     # Create a directory whose path will be exactly 240 chars long
31     dir_len = 240 - cwd_len - 1
32     self.cwd_backup = os.getcwd()
33     self.LongTempDir = os.path.join(self.cwd_backup, 'a' * dir_len)
34     os.mkdir(self.LongTempDir)
35
36   def tearDown(self):
37     super(TestPathNames, self).tearDown()
38     os.chdir(self.cwd_backup)
39     sys.exit = self.backup_exit
40     shutil.rmtree(self.LongTempDir)
41
42   def WriteCFile(self, filename):
43     with open(filename, 'w') as f:
44       f.write('int main() { return 0; }')
45
46   def AssertRaisesAndReturnOutput(self, exc, func, *args):
47     capture_out = cStringIO.StringIO()
48     driver_log.Log.CaptureToStream(capture_out)
49     self.assertRaises(exc, func, *args)
50     driver_log.Log.ResetStreams()
51     return capture_out.getvalue()
52
53   def test_InputPathTooLong(self):
54     '''Test that clang and ld reject input paths that are too long
55
56      Test that compiling and linking paths shorter than 255 succeeds and paths
57      longer than 255 fails.
58      Operations in python (e.g. rename) on long paths don't work on Windows,
59      so just run the tests on Linux/Mac (the checks are enabled in unittest
60      mode)
61      '''
62     if not driver_test_utils.CanRunHost() or driver_tools.IsWindowsPython():
63       return
64
65     shortname = os.path.join(self.LongTempDir, 'a' * 10)
66     longname = os.path.join(self.LongTempDir, 'a' * 32)
67
68     assert len(shortname) + 2 < 255
69     assert len(longname) + 2 > 255
70     self.WriteCFile(shortname + '.c')
71
72     driver_tools.RunDriver('pnacl-clang',
73                            [shortname + '.c', '-c', '-o', shortname + '.o'])
74
75     driver_tools.RunDriver('pnacl-ld',
76                            [shortname + '.o'])
77
78     os.rename(shortname + '.c', longname + '.c')
79     os.rename(shortname + '.o', longname + '.o')
80
81
82     output = self.AssertRaisesAndReturnOutput(
83         driver_test_utils.DriverExitException,
84         driver_tools.RunDriver,
85         'pnacl-clang',
86         [longname + '.c', '-c', '-o', longname + '.o'])
87
88     self.assertIn('too long', output)
89
90     output = self.AssertRaisesAndReturnOutput(
91         driver_test_utils.DriverExitException,
92         driver_tools.RunDriver,
93         'pnacl-ld',
94         [longname + '.o'])
95
96     self.assertIn('too long', output)
97
98   def test_ExpandedPathTooLong(self):
99     '''Test that the expanded path is checked with a short relative path'''
100     if not driver_test_utils.CanRunHost() or driver_tools.IsWindowsPython():
101       return
102
103     os.chdir(self.LongTempDir)
104
105     shortname = 'a' * 10
106     longname = 'a' * 32
107
108     # Now we are in a state where the file can be referred to by a relative
109     # path or a normalized absolute path. For 'shortname', both are short
110     # enough
111     assert len(os.path.join(self.LongTempDir, shortname)) + 2 < 255
112     assert len(os.path.join(self.LongTempDir, longname)) + 2 > 255
113     self.WriteCFile(shortname + '.c')
114
115     # Test that using a relative almost-too-long path works
116     driver_tools.RunDriver('pnacl-clang',
117                            [shortname + '.c', '-c', '-o', shortname + '.o'])
118
119     driver_tools.RunDriver('pnacl-ld',
120                            [shortname + '.o'])
121
122     # This name has a short-enough relative path and a short-enough normalized
123     # final path, but the intermediate concatenation of pwd + rel path is too
124     # long
125     name_with_traversals = os.path.join('..',
126                                         os.path.basename(self.LongTempDir),
127                                         shortname)
128
129     output = self.AssertRaisesAndReturnOutput(
130         driver_test_utils.DriverExitException,
131         driver_tools.RunDriver,
132         'pnacl-clang',
133         [name_with_traversals + '.c', '-c', '-o', shortname + '.o'])
134     self.assertIn('expanded', output)
135
136     # The previous test only gives a long input name. Also test that the output
137     # name is checked.
138     output = self.AssertRaisesAndReturnOutput(
139         driver_test_utils.DriverExitException,
140         driver_tools.RunDriver,
141         'pnacl-clang',
142         [shortname + '.c', '-c', '-o', name_with_traversals + '.o'])
143     self.assertIn('expanded', output)
144
145
146   def test_TempFileNotTooLong(self):
147     '''Test that temp files with too-long names are not generated'''
148     if not driver_test_utils.CanRunHost() or driver_tools.IsWindowsPython():
149       return
150
151     # This name is chosen such that the .c file has the maximum length. pnacl-ld
152     # should not generate any temp names longer than that.
153     shortname =  os.path.join(self.LongTempDir, 'a' * 12)
154
155     self.WriteCFile(shortname + '.c')
156     driver_tools.RunDriver('pnacl-clang',
157                            [shortname + '.c', '-c', '-o', shortname + '.o'])
158
159     driver_tools.RunDriver('pnacl-ld',
160                            [shortname + '.o', '-o', shortname])
161
162     # If it's impossible to generate a temp file short enough using our scheme
163     # (i.e. the directory name is so long that 8 chars will be over the limit),
164     # make sure we still fail the right way.
165     longerdir = os.path.join(self.LongTempDir, 'a' * 8)
166     os.mkdir(longerdir)
167     longname = os.path.join(longerdir, 'a' * 3)
168     os.rename(shortname + '.o', longname + '.o')
169
170     output = self.AssertRaisesAndReturnOutput(
171         driver_test_utils.DriverExitException,
172         driver_tools.RunDriver,
173         'pnacl-ld',
174         [longname + '.o', '-o', longname])
175
176     self.assertIn('.pexe is too long', output)