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