Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / native_client / toolchain_build / once_test.py
1 #!/usr/bin/python
2 # Copyright (c) 2012 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 a network memoizer."""
7
8 import os
9 import subprocess
10 import shutil
11 import sys
12 import unittest
13
14 sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
15 import pynacl.directory_storage
16 import pynacl.fake_storage
17 import pynacl.file_tools
18 import pynacl.gsd_storage
19 import pynacl.working_directory
20
21 import command
22 import once
23
24
25 class TestOnce(unittest.TestCase):
26
27   def GenerateTestData(self, noise, work_dir):
28     self._input_dirs = {}
29     self._input_files = []
30     for i in range(2):
31       dir_name = os.path.join(work_dir, noise + 'input%d_dir' % i)
32       os.mkdir(dir_name)
33       filename = os.path.join(dir_name, 'in%d' % i)
34       pynacl.file_tools.WriteFile(noise + 'data%d' % i, filename)
35       self._input_dirs['input%d' % i] = dir_name
36       self._input_files.append(filename)
37     self._output_dirs = []
38     self._output_files = []
39     for i in range(2):
40       dir_name = os.path.join(work_dir, noise + 'output%d_dir' % i)
41       os.mkdir(dir_name)
42       filename = os.path.join(dir_name, 'out')
43       self._output_dirs.append(dir_name)
44       self._output_files.append(filename)
45
46   def test_FirstTime(self):
47     # Test that the computation is always performed if the cache is empty.
48     with pynacl.working_directory.TemporaryWorkingDirectory() as work_dir:
49       self.GenerateTestData('FirstTime', work_dir)
50       o = once.Once(storage=pynacl.fake_storage.FakeStorage(),
51                     system_summary='test')
52       o.Run('test', self._input_dirs, self._output_dirs[0],
53             [command.Copy('%(input0)s/in0', '%(output)s/out')])
54       self.assertEquals('FirstTimedata0',
55                         pynacl.file_tools.ReadFile(self._output_files[0]))
56
57   def test_HitsCacheSecondTime(self):
58     # Test that the computation is not performed on a second instance.
59     with pynacl.working_directory.TemporaryWorkingDirectory() as work_dir:
60       self.GenerateTestData('HitsCacheSecondTime', work_dir)
61       self._tally = 0
62       def Copy(logger, subst, src, dst):
63         self._tally += 1
64         shutil.copyfile(subst.SubstituteAbsPaths(src),
65                         subst.SubstituteAbsPaths(dst))
66       self._url = None
67       def stash_url(urls):
68         self._url = urls
69       o = once.Once(storage=pynacl.fake_storage.FakeStorage(),
70                     print_url=stash_url, system_summary='test')
71       o.Run('test', self._input_dirs, self._output_dirs[0],
72             [command.Runnable(None, Copy,'%(input0)s/in0', '%(output)s/out')])
73       initial_url = self._url
74       self._url = None
75       o.Run('test', self._input_dirs, self._output_dirs[1],
76             [command.Runnable(None, Copy,'%(input0)s/in0', '%(output)s/out')])
77       self.assertEquals(pynacl.file_tools.ReadFile(self._input_files[0]),
78                         pynacl.file_tools.ReadFile(self._output_files[0]))
79       self.assertEquals(pynacl.file_tools.ReadFile(self._input_files[0]),
80                         pynacl.file_tools.ReadFile(self._output_files[1]))
81       self.assertEquals(1, self._tally)
82       self.assertEquals(initial_url, self._url)
83
84   def test_CachedCommandRecorded(self):
85     with pynacl.working_directory.TemporaryWorkingDirectory() as work_dir:
86       self.GenerateTestData('CachedCommand', work_dir)
87       o = once.Once(storage=pynacl.fake_storage.FakeStorage(),
88                     system_summary='test')
89       o.Run('test', self._input_dirs, self._output_dirs[0],
90             [command.Copy('%(input0)s/in0', '%(output)s/out')])
91       self.assertEquals(len(o.GetCachedCloudItems()), 1)
92
93   def test_UncachedCommandsNotRecorded(self):
94     with pynacl.working_directory.TemporaryWorkingDirectory() as work_dir:
95       self.GenerateTestData('CachedCommand', work_dir)
96       o = once.Once(storage=pynacl.fake_storage.FakeStorage(),
97                     system_summary='test', cache_results=False)
98       o.Run('test', self._input_dirs, self._output_dirs[0],
99             [command.Copy('%(input0)s/in0', '%(output)s/out')])
100       self.assertEquals(len(o.GetCachedCloudItems()), 0)
101
102   def FileLength(self, src, dst, **kwargs):
103     """Command object to write the length of one file into another."""
104     return command.Command([
105         sys.executable, '-c',
106           'import sys; open(sys.argv[2], "wb").write('
107           'str(len(open(sys.argv[1], "rb").read())))', src, dst
108         ], **kwargs)
109
110   def test_RecomputeHashMatches(self):
111     # Test that things don't get stored to the output cache if they exist
112     # already.
113     with pynacl.working_directory.TemporaryWorkingDirectory() as work_dir:
114       # Setup test data in input0, input1 using memory storage.
115       self.GenerateTestData('RecomputeHashMatches', work_dir)
116       fs = pynacl.fake_storage.FakeStorage()
117       o = once.Once(storage=fs, system_summary='test')
118
119       # Run the computation (compute the length of a file) from input0 to
120       # output0.
121       o.Run('test', self._input_dirs, self._output_dirs[0],
122             [self.FileLength(
123                 '%(input0)s/in0', '%(output)s/out')])
124
125       # Check that 3 writes have occurred. One to write a mapping from in->out,
126       # one for the output data, and one for the log file.
127       self.assertEquals(3, fs.WriteCount())
128
129       # Run the computation again from input1 to output1.
130       # (These should have the same length.)
131       o.Run('test', self._input_dirs, self._output_dirs[1],
132             [self.FileLength(
133                 '%(input1)s/in1', '%(output)s/out')])
134
135       # Write count goes up by one as an in->out hash is added,
136       # but no new output is stored (as it is the same).
137       self.assertEquals(4, fs.WriteCount())
138
139       # Check that the test is still valid:
140       #   - in0 and in1 have equal length.
141       #   - out0 and out1 have that length in them.
142       #   - out0 and out1 agree.
143       self.assertEquals(
144           str(len(pynacl.file_tools.ReadFile(self._input_files[0]))),
145           pynacl.file_tools.ReadFile(self._output_files[0])
146       )
147       self.assertEquals(
148           str(len(pynacl.file_tools.ReadFile(self._input_files[1]))),
149           pynacl.file_tools.ReadFile(self._output_files[1])
150       )
151       self.assertEquals(
152           pynacl.file_tools.ReadFile(self._output_files[0]),
153           pynacl.file_tools.ReadFile(self._output_files[1])
154       )
155
156   def test_FailsWhenWritingFails(self):
157     # Check that once doesn't eat the storage layer failures for writes.
158     with pynacl.working_directory.TemporaryWorkingDirectory() as work_dir:
159       self.GenerateTestData('FailsWhenWritingFails', work_dir)
160       def call(cmd, **kwargs):
161         # Cause gsutil commands to fail.
162         return 1
163       bad_storage = pynacl.gsd_storage.GSDStorage(
164           gsutil=['mygsutil'],
165           write_bucket='mybucket',
166           read_buckets=[],
167           call=call)
168       o = once.Once(storage=bad_storage, system_summary='test')
169       self.assertRaises(pynacl.gsd_storage.GSDStorageError, o.Run, 'test',
170           self._input_dirs, self._output_dirs[0],
171           [command.Copy('%(input0)s/in0', '%(output)s/out')])
172
173   def test_UseCachedResultsFalse(self):
174     # Check that the use_cached_results=False does indeed cause computations
175     # to be redone, even when present in the cache.
176     with pynacl.working_directory.TemporaryWorkingDirectory() as work_dir:
177       self.GenerateTestData('UseCachedResultsFalse', work_dir)
178       self._tally = 0
179       def Copy(logger, subst, src, dst):
180         self._tally += 1
181         shutil.copyfile(subst.SubstituteAbsPaths(src),
182                         subst.SubstituteAbsPaths(dst))
183       o = once.Once(storage=pynacl.fake_storage.FakeStorage(),
184                     use_cached_results=False,
185                     system_summary='test')
186       o.Run('test', self._input_dirs, self._output_dirs[0],
187             [command.Runnable(None, Copy,'%(input0)s/in0', '%(output)s/out')])
188       o.Run('test', self._input_dirs, self._output_dirs[1],
189             [command.Runnable(None, Copy,'%(input0)s/in0', '%(output)s/out')])
190       self.assertEquals(2, self._tally)
191       self.assertEquals(pynacl.file_tools.ReadFile(self._input_files[0]),
192                         pynacl.file_tools.ReadFile(self._output_files[0]))
193       self.assertEquals(pynacl.file_tools.ReadFile(self._input_files[0]),
194                         pynacl.file_tools.ReadFile(self._output_files[1]))
195
196   def test_CacheResultsFalse(self):
197     # Check that setting cache_results=False prevents results from being written
198     # to the cache.
199     with pynacl.working_directory.TemporaryWorkingDirectory() as work_dir:
200       self.GenerateTestData('CacheResultsFalse', work_dir)
201       storage = pynacl.fake_storage.FakeStorage()
202       o = once.Once(storage=storage, cache_results=False, system_summary='test')
203       o.Run('test', self._input_dirs, self._output_dirs[0],
204             [command.Copy('%(input0)s/in0', '%(output)s/out')])
205       self.assertEquals(0, storage.ItemCount())
206       self.assertEquals(pynacl.file_tools.ReadFile(self._input_files[0]),
207                         pynacl.file_tools.ReadFile(self._output_files[0]))
208
209   def test_Mkdir(self):
210     # Test the Mkdir convenience wrapper works.
211     with pynacl.working_directory.TemporaryWorkingDirectory() as work_dir:
212       self.GenerateTestData('Mkdir', work_dir)
213       foo = os.path.join(work_dir, 'foo')
214       o = once.Once(storage=pynacl.fake_storage.FakeStorage(),
215                     cache_results=False, system_summary='test')
216       o.Run('test', self._input_dirs, foo,
217             [command.Mkdir('%(output)s/hi')])
218       self.assertTrue(os.path.isdir(os.path.join(foo, 'hi')))
219
220   def test_Command(self):
221     # Test a plain command.
222     with pynacl.working_directory.TemporaryWorkingDirectory() as work_dir:
223       self.GenerateTestData('Command', work_dir)
224       o = once.Once(storage=pynacl.fake_storage.FakeStorage(),
225                     system_summary='test')
226       o.Run('test', self._input_dirs, self._output_dirs[0],
227             [command.Command([
228                 sys.executable, '-c',
229                 'import sys; open(sys.argv[1], "wb").write("hello")',
230                 '%(output)s/out'])])
231       self.assertEquals(
232           'hello',
233           pynacl.file_tools.ReadFile(self._output_files[0])
234       )
235
236   def test_NumCores(self):
237     # Test that the core count is substituted. Since we don't know how many
238     # cores the test machine will have, just check that it's an integer.
239     with pynacl.working_directory.TemporaryWorkingDirectory() as work_dir:
240       self.GenerateTestData('NumCores', work_dir)
241       o = once.Once(storage=pynacl.fake_storage.FakeStorage(),
242                     system_summary='test')
243       def CheckCores(logger, subst):
244         self.assertNotEquals(0, int(subst.Substitute('%(cores)s')))
245       o.Run('test', {}, self._output_dirs[0], [command.Runnable(None,
246                                                                 CheckCores)])
247
248   def test_RunConditionsFalse(self):
249     # Test that a command uses run conditions to decide whether or not to run.
250     with pynacl.working_directory.TemporaryWorkingDirectory() as work_dir:
251       self.GenerateTestData('Command', work_dir)
252       o = once.Once(storage=pynacl.fake_storage.FakeStorage(),
253                     system_summary='test')
254       o.Run('test', self._input_dirs, self._output_dirs[0],
255             [command.Command([
256                 sys.executable, '-c',
257                 'import sys; open(sys.argv[1], "wb").write("hello")',
258                 '%(output)s/out'],
259                 run_cond=lambda cmd_opts: True),
260              command.Command([
261                  sys.executable, '-c',
262                  'import sys; open(sys.argv[1], "wb").write("not hello")',
263                  '%(output)s/out'],
264                  run_cond=lambda cmd_opts: False)])
265       self.assertEquals(
266           'hello',
267           pynacl.file_tools.ReadFile(self._output_files[0])
268       )
269
270   def test_OutputsFlushPathHashCache(self):
271     # Test that commands that output to a directory that has an input hash
272     # value cached raise an error indicating an input output cycle.
273     with pynacl.working_directory.TemporaryWorkingDirectory() as work_dir:
274       self.GenerateTestData('CacheFlush', work_dir)
275       o = once.Once(storage=pynacl.fake_storage.FakeStorage(),
276                     system_summary='test')
277       self.assertRaises(
278           once.UserError, o.Run,
279           'test', self._input_dirs, self._input_dirs['input0'],
280           [command.Copy('%(input0)s/in0', '%(output)s/out')])
281
282
283 if __name__ == '__main__':
284   unittest.main()