Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python2 | 1 #!/usr/bin/env python2 |
| 2 # -*- coding: utf-8 -*- | 2 # -*- coding: utf-8 -*- |
| 3 | 3 |
| 4 # Copyright 2016 Google Inc. All Rights Reserved. | 4 # Copyright 2016 Google Inc. All Rights Reserved. |
| 5 # | 5 # |
| 6 # Licensed under the Apache License, Version 2.0 (the "License"); | 6 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 7 # you may not use this file except in compliance with the License. | 7 # you may not use this file except in compliance with the License. |
| 8 # You may obtain a copy of the License at | 8 # You may obtain a copy of the License at |
| 9 # | 9 # |
| 10 # http://www.apache.org/licenses/LICENSE-2.0 | 10 # http://www.apache.org/licenses/LICENSE-2.0 |
| 11 # | 11 # |
| 12 # Unless required by applicable law or agreed to in writing, software | 12 # Unless required by applicable law or agreed to in writing, software |
| 13 # distributed under the License is distributed on an "AS IS" BASIS, | 13 # distributed under the License is distributed on an "AS IS" BASIS, |
| 14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 # See the License for the specific language governing permissions and | 15 # See the License for the specific language governing permissions and |
| 16 # limitations under the License. | 16 # limitations under the License. |
| 17 | 17 |
| 18 """End-to-end tests for Caterpillar.""" | 18 """End-to-end tests for Caterpillar.""" |
| 19 | 19 |
| 20 from __future__ import print_function, division, unicode_literals | 20 from __future__ import print_function, division, unicode_literals |
| 21 | 21 |
| 22 import difflib | 22 import difflib |
| 23 import os | 23 import os |
| 24 import re | 24 import re |
| 25 import shutil | |
| 25 import subprocess | 26 import subprocess |
| 26 import sys | 27 import sys |
| 28 import tempfile | |
| 27 import unittest | 29 import unittest |
| 28 | 30 |
| 29 import caterpillar | 31 import caterpillar |
| 30 import caterpillar_test | |
| 31 | 32 |
| 32 TEST_DIR = os.path.dirname(os.path.realpath(__file__)) | 33 TEST_DIR = os.path.dirname(os.path.realpath(__file__)) |
| 33 CATERPILLAR_PATH = os.path.join(TEST_DIR, 'caterpillar.py') | 34 CATERPILLAR_PATH = os.path.join(TEST_DIR, 'caterpillar.py') |
| 34 TTS_APP_NAME = 'test_app_tts' | 35 TTS_APP_NAME = 'test_app_tts' |
| 35 TTS_REFERENCE_NAME = 'test_app_tts_output' | 36 TTS_REFERENCE_NAME = 'test_app_tts_output' |
| 36 TTS_PATH = os.path.join( | 37 TTS_PATH = os.path.join( |
| 37 os.path.dirname(TEST_DIR), 'tests', TTS_APP_NAME) | 38 os.path.dirname(TEST_DIR), 'tests', TTS_APP_NAME) |
| 38 TTS_REFERENCE_PATH = os.path.join( | 39 TTS_REFERENCE_PATH = os.path.join( |
| 39 os.path.dirname(TEST_DIR), 'tests', TTS_REFERENCE_NAME) | 40 os.path.dirname(TEST_DIR), 'tests', TTS_REFERENCE_NAME) |
| 40 | 41 |
| 41 | 42 |
| 42 class TestEndToEndConvert(caterpillar_test.TestCaseWithTempDir): | 43 class TestEndToEndConvert(unittest.TestCase): |
|
Matt Giuca
2016/02/05 00:23:49
Why no longer using TestCaseWithTempDir?
| |
| 43 """Converts an entire Chrome App and checks the output is correct.""" | 44 """Converts an entire Chrome App and checks the output is correct.""" |
| 44 | 45 |
| 45 def setUp(self): | 46 @classmethod |
| 47 def setUpClass(cls): | |
| 46 """Converts a test Chrome App.""" | 48 """Converts a test Chrome App.""" |
| 47 super(TestEndToEndConvert, self).setUp() | 49 cls.temp_path = tempfile.mkdtemp() |
| 48 self.input_dir = TTS_PATH | 50 cls.input_dir = TTS_PATH |
| 49 self.output_dir = os.path.join(self.temp_path, 'tts test output') | 51 cls.output_dir = os.path.join(cls.temp_path, 'tts test output') |
| 50 self.config_path = os.path.join(self.temp_path, 'config.json') | 52 cls.config_path = os.path.join(cls.temp_path, 'config.json') |
| 51 | 53 |
| 52 encoding = sys.getfilesystemencoding() | 54 encoding = sys.getfilesystemencoding() |
| 53 | 55 |
| 54 self.boilerplate_dir = 'caterpillar-📂' | 56 cls.boilerplate_dir = 'caterpillar-📂' |
| 55 self.report_dir = 'report ✓✓✓' | 57 cls.report_dir = 'report ✓✓✓' |
| 56 self.start_url = 'ttstest.html' | 58 cls.start_url = 'ttstest.html' |
| 57 config_input = '{}\n{}\n{}\n'.format( | 59 config_input = '{}\n{}\n{}\n'.format( |
| 58 self.boilerplate_dir, self.report_dir, self.start_url).encode(encoding) | 60 cls.boilerplate_dir, cls.report_dir, cls.start_url).encode(encoding) |
| 59 | 61 |
| 60 # Generate a config file using Caterpillar. | 62 # Generate a config file using Caterpillar. |
| 61 process = subprocess.Popen( | 63 process = subprocess.Popen( |
| 62 [CATERPILLAR_PATH, 'config', '-i', self.config_path], | 64 [CATERPILLAR_PATH, 'config', '-i', cls.config_path], |
| 63 stdin=subprocess.PIPE, | 65 stdin=subprocess.PIPE, |
| 64 stdout=subprocess.PIPE, | 66 stdout=subprocess.PIPE, |
| 65 stderr=subprocess.STDOUT) | 67 stderr=subprocess.STDOUT) |
| 66 process.communicate(input=config_input) | 68 process.communicate(input=config_input) |
| 67 process.wait() | 69 process.wait() |
| 68 | 70 |
| 69 if not os.path.exists(self.config_path): | 71 if not os.path.exists(cls.config_path): |
| 72 raise RuntimeError('Configuration file generation failed.') | |
| 73 if process.wait(): | |
| 74 raise subprocess.CalledProcessError() | |
| 75 | |
| 76 if not os.path.exists(cls.config_path): | |
| 70 raise RuntimeError('Configuration file generation failed.') | 77 raise RuntimeError('Configuration file generation failed.') |
| 71 | 78 |
| 72 process = subprocess.Popen( | 79 output = subprocess.check_output( |
|
Matt Giuca
2016/02/05 00:23:49
It's really quite strange that you run the entire
| |
| 73 [CATERPILLAR_PATH, 'convert', '-c', self.config_path, self.input_dir, | 80 [CATERPILLAR_PATH, 'convert', '-c', cls.config_path, cls.input_dir, |
| 74 self.output_dir], | 81 cls.output_dir]) |
| 75 stdin=subprocess.PIPE, | 82 |
| 76 stdout=subprocess.PIPE, | 83 @classmethod |
| 77 stderr=subprocess.STDOUT) | 84 def tearDownClass(cls): |
| 78 process.wait() | 85 """Removes the converted test Chrome App.""" |
| 86 shutil.rmtree(cls.temp_path) | |
| 87 | |
| 88 def get_relative_filepaths(self, directory, ignore_directories=None): | |
| 89 """Returns all relative filepaths in a directory and children. | |
| 90 | |
| 91 Args: | |
| 92 directory: Path to directory. | |
| 93 ignore_directories: Set of directory names to ignore. Note that all | |
| 94 children will be ignored too. | |
| 95 | |
| 96 Returns: | |
| 97 set of relative filepaths. | |
| 98 """ | |
| 99 if not ignore_directories: | |
| 100 ignore_directories = set() | |
| 101 | |
| 102 filepaths = set() | |
| 103 for dirname, dirnames, filenames in os.walk(directory, topdown=True): | |
| 104 basename = os.path.basename(os.path.normpath(dirname)) | |
| 105 if basename in ignore_directories: | |
| 106 dirnames[:] = [] | |
| 107 continue | |
| 108 | |
| 109 for filename in filenames: | |
| 110 relpath = os.path.relpath(os.path.join(dirname, filename), directory) | |
| 111 filepaths.add(relpath) | |
| 112 | |
| 113 return filepaths | |
| 79 | 114 |
| 80 def test_output_matches_reference(self): | 115 def test_output_matches_reference(self): |
| 81 """Tests that the output matches the reference output.""" | 116 """Tests that the output matches the reference output.""" |
| 82 expected_files = set() | 117 expected_files = self.get_relative_filepaths(TTS_REFERENCE_PATH, |
| 83 for dirname, _, filenames in os.walk(TTS_REFERENCE_PATH): | 118 {'bower_components'}) |
| 84 for filename in filenames: | 119 actual_files = self.get_relative_filepaths(self.output_dir, |
| 85 relpath = os.path.relpath( | 120 {'bower_components'}) |
| 86 os.path.join(dirname, filename), TTS_REFERENCE_PATH) | 121 self.assertEqual(expected_files, actual_files) |
| 87 expected_files.add(relpath) | |
| 88 | |
| 89 for dirname, _, filenames in os.walk(self.output_dir): | |
| 90 for filename in filenames: | |
| 91 relpath = os.path.relpath( | |
| 92 os.path.join(dirname, filename), self.output_dir) | |
| 93 self.assertIn(relpath, expected_files) | |
| 94 | |
| 95 expected_files = set() | |
| 96 for dirname, _, filenames in os.walk(self.output_dir): | |
| 97 for filename in filenames: | |
| 98 relpath = os.path.relpath( | |
| 99 os.path.join(dirname, filename), self.output_dir) | |
| 100 expected_files.add(relpath) | |
| 101 | |
| 102 for dirname, _, filenames in os.walk(TTS_REFERENCE_PATH): | |
| 103 for filename in filenames: | |
| 104 relpath = os.path.relpath( | |
| 105 os.path.join(dirname, filename), TTS_REFERENCE_PATH) | |
| 106 self.assertIn(relpath, expected_files) | |
| 107 | 122 |
| 108 def test_all_correct_contents(self): | 123 def test_all_correct_contents(self): |
| 109 """Tests that the content of all non-static output files is expected.""" | 124 """Tests that the content of all non-static output files is expected.""" |
| 110 for dirname, _, filenames in os.walk(TTS_REFERENCE_PATH): | 125 for dirname, _, filenames in os.walk(TTS_REFERENCE_PATH): |
| 111 for filename in filenames: | 126 for filename in filenames: |
| 112 if filename == caterpillar.SW_SCRIPT_NAME: | 127 if filename == caterpillar.SW_SCRIPT_NAME: |
| 113 # Service worker is partly random, so test it elsewhere. | 128 # Service worker is partly random, so test it elsewhere. |
| 114 continue | 129 continue |
| 115 | 130 |
| 116 reference_path = os.path.join(dirname, filename) | 131 reference_path = os.path.join(dirname, filename) |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 '\n'.join(difflib.unified_diff( | 170 '\n'.join(difflib.unified_diff( |
| 156 output_data.split('\n'), | 171 output_data.split('\n'), |
| 157 reference_data.split('\n'), | 172 reference_data.split('\n'), |
| 158 fromfile=reference_sw_path, | 173 fromfile=reference_sw_path, |
| 159 tofile=output_sw_path, | 174 tofile=output_sw_path, |
| 160 n=0)))) | 175 n=0)))) |
| 161 | 176 |
| 162 | 177 |
| 163 if __name__ == '__main__': | 178 if __name__ == '__main__': |
| 164 unittest.main() | 179 unittest.main() |
| OLD | NEW |