1#!/usr/bin/env python 2# Copyright 2013 The Chromium 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 6from copy import deepcopy 7import unittest 8 9from file_system import FileNotFoundError, StatInfo 10from patched_file_system import PatchedFileSystem 11from test_file_system import TestFileSystem 12from test_patcher import TestPatcher 13 14_TEST_FS_DATA = { 15 'dir1': { 16 'file1.html': 'This is dir1/file1.html', 17 'unmodified': { 18 '1': '1', 19 '2': '', 20 }, 21 }, 22 'dir2': { 23 'subdir1': { 24 'sub1.txt': 'in subdir(1)', 25 'sub2.txt': 'in subdir(2)', 26 'sub3.txt': 'in subdir(3)', 27 }, 28 }, 29 'dir3': { 30 }, 31 'dir4': { 32 'one.txt': '', 33 }, 34 'dir5': { 35 'subdir': { 36 '1.txt': '555', 37 }, 38 }, 39 'test1.txt': 'test1', 40 'test2.txt': 'test2', 41} 42 43_TEST_PATCH_VERSION = '1001' 44_TEST_PATCH_FILES = ( 45 # Added 46 [ 47 'test3.txt', 48 'dir1/file2.html', 49 'dir1/newsubdir/a.js', 50 'newdir/1.html', 51 ], 52 # Deleted 53 [ 54 'test2.txt', 55 'dir2/subdir1/sub1.txt', 56 'dir4/one.txt', 57 'dir5/subdir/1.txt', 58 ], 59 # Modified 60 [ 61 'dir2/subdir1/sub2.txt', 62 ] 63) 64_TEST_PATCH_DATA = { 65 'test3.txt': 'test3 is added.', 66 'dir1/file2.html': 'This is dir1/file2.html', 67 'dir1/newsubdir/a.js': 'This is a.js', 68 'newdir/1.html': 'This comes from a new dir.', 69 'dir2/subdir1/sub2.txt': 'in subdir', 70} 71 72class PatchedFileSystemTest(unittest.TestCase): 73 def setUp(self): 74 self._patcher = TestPatcher(_TEST_PATCH_VERSION, 75 _TEST_PATCH_FILES, 76 _TEST_PATCH_DATA) 77 self._host_file_system = TestFileSystem(_TEST_FS_DATA) 78 self._file_system = PatchedFileSystem(self._host_file_system, 79 self._patcher) 80 81 def testRead(self): 82 expected = deepcopy(_TEST_PATCH_DATA) 83 # Files that are not modified. 84 expected.update({ 85 'dir2/subdir1/sub3.txt': 'in subdir(3)', 86 'dir1/file1.html': 'This is dir1/file1.html', 87 }) 88 89 for key in expected: 90 self.assertEqual(expected[key], self._file_system.ReadSingle(key).Get()) 91 92 self.assertEqual( 93 expected, 94 self._file_system.Read(expected.keys()).Get()) 95 96 self.assertRaises(FileNotFoundError, 97 self._file_system.ReadSingle('test2.txt').Get) 98 self.assertRaises(FileNotFoundError, 99 self._file_system.ReadSingle('dir2/subdir1/sub1.txt').Get) 100 self.assertRaises(FileNotFoundError, 101 self._file_system.ReadSingle('not_existing').Get) 102 self.assertRaises(FileNotFoundError, 103 self._file_system.ReadSingle('dir1/not_existing').Get) 104 self.assertRaises( 105 FileNotFoundError, 106 self._file_system.ReadSingle('dir1/newsubdir/not_existing').Get) 107 108 def testReadDir(self): 109 self.assertEqual( 110 sorted(self._file_system.ReadSingle('dir1/').Get()), 111 sorted(set(self._host_file_system.ReadSingle('dir1/').Get()) | 112 set(('file2.html', 'newsubdir/')))) 113 114 self.assertEqual( 115 sorted(self._file_system.ReadSingle('dir1/newsubdir/').Get()), 116 sorted(['a.js'])) 117 118 self.assertEqual(sorted(self._file_system.ReadSingle('dir2/').Get()), 119 sorted(self._host_file_system.ReadSingle('dir2/').Get())) 120 121 self.assertEqual( 122 sorted(self._file_system.ReadSingle('dir2/subdir1/').Get()), 123 sorted(set(self._host_file_system.ReadSingle('dir2/subdir1/').Get()) - 124 set(('sub1.txt',)))) 125 126 self.assertEqual(sorted(self._file_system.ReadSingle('newdir/').Get()), 127 sorted(['1.html'])) 128 129 self.assertEqual(self._file_system.ReadSingle('dir3/').Get(), []) 130 131 self.assertEqual(self._file_system.ReadSingle('dir4/').Get(), []) 132 133 self.assertRaises(FileNotFoundError, 134 self._file_system.ReadSingle('not_existing_dir/').Get) 135 136 def testStat(self): 137 version = 'patched_%s' % self._patcher.GetVersion() 138 old_version = self._host_file_system.Stat('dir1/file1.html').version 139 140 # Stat an unmodified file. 141 self.assertEqual(self._file_system.Stat('dir1/file1.html'), 142 self._host_file_system.Stat('dir1/file1.html')) 143 144 # Stat an unmodified directory. 145 self.assertEqual(self._file_system.Stat('dir1/unmodified/'), 146 self._host_file_system.Stat('dir1/unmodified/')) 147 148 # Stat a modified directory. 149 self.assertEqual(self._file_system.Stat('dir2/'), 150 StatInfo(version, {'subdir1/': version})) 151 self.assertEqual(self._file_system.Stat('dir2/subdir1/'), 152 StatInfo(version, {'sub2.txt': version, 153 'sub3.txt': old_version})) 154 155 # Stat a modified directory with new files. 156 expected = self._host_file_system.Stat('dir1/') 157 expected.version = version 158 expected.child_versions.update({'file2.html': version, 159 'newsubdir/': version}) 160 self.assertEqual(self._file_system.Stat('dir1/'), 161 expected) 162 163 # Stat an added directory. 164 self.assertEqual(self._file_system.Stat('dir1/newsubdir/'), 165 StatInfo(version, {'a.js': version})) 166 self.assertEqual(self._file_system.Stat('dir1/newsubdir/a.js'), 167 StatInfo(version)) 168 self.assertEqual(self._file_system.Stat('newdir/'), 169 StatInfo(version, {'1.html': version})) 170 self.assertEqual(self._file_system.Stat('newdir/1.html'), 171 StatInfo(version)) 172 173 # Stat files removed in the patch. 174 self.assertRaises(FileNotFoundError, self._file_system.Stat, 175 'dir2/subdir1/sub1.txt') 176 self.assertRaises(FileNotFoundError, self._file_system.Stat, 177 'dir4/one.txt') 178 179 # Stat empty directories. 180 self.assertEqual(self._file_system.Stat('dir3/'), 181 StatInfo(old_version, {})) 182 self.assertEqual(self._file_system.Stat('dir4/'), 183 StatInfo(version, {})) 184 self.assertEqual(self._file_system.Stat('dir5/subdir/'), 185 StatInfo(version, {})) 186 187 # Stat empty (after patch) directory's parent 188 self.assertEqual(self._file_system.Stat('dir5/'), 189 StatInfo(version, {'subdir/': version})) 190 191 # Stat files that don't exist either before or after patching. 192 self.assertRaises(FileNotFoundError, self._file_system.Stat, 193 'not_existing/') 194 self.assertRaises(FileNotFoundError, self._file_system.Stat, 195 'dir1/not_existing/') 196 self.assertRaises(FileNotFoundError, self._file_system.Stat, 197 'dir1/not_existing') 198 199if __name__ == '__main__': 200 unittest.main() 201