15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/env python
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import json
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import unittest
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from extensions_paths import SERVER2
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from fake_url_fetcher import FakeUrlFetcher
12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)from file_system import FileSystemError, StatInfo
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from subversion_file_system import SubversionFileSystem
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from test_util import ReadFile, Server2Path
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)_SHARED_FILE_SYSTEM_TEST_DATA = Server2Path('test_data', 'file_system')
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)_SUBVERSION_FILE_SYSTEM_TEST_DATA = Server2Path(
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    'test_data', 'subversion_file_system')
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochdef _CreateSubversionFileSystem(path):
232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  fetcher = FakeUrlFetcher(path)
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return SubversionFileSystem(fetcher, fetcher, path), fetcher
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochclass SubversionFileSystemTest(unittest.TestCase):
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testReadFiles(self):
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected = {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'test1.txt': 'test1\n',
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'test2.txt': 'test2\n',
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      'test3.txt': 'test3\n',
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    file_system, fetcher = _CreateSubversionFileSystem(
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        _SHARED_FILE_SYSTEM_TEST_DATA)
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    read_future = file_system.Read(['test1.txt', 'test2.txt', 'test3.txt'])
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self.assertTrue(*fetcher.CheckAndReset(async_count=3))
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self.assertEqual(expected, read_future.Get())
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self.assertTrue(*fetcher.CheckAndReset(async_resolve_count=3))
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testListDir(self):
42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    expected = ['dir/'] + ['file%d.html' % i for i in range(7)]
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    file_system, fetcher = _CreateSubversionFileSystem(
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        _SHARED_FILE_SYSTEM_TEST_DATA)
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    list_future = file_system.ReadSingle('list/')
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self.assertTrue(*fetcher.CheckAndReset(async_count=1))
474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self.assertEqual(expected, sorted(list_future.Get()))
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self.assertTrue(*fetcher.CheckAndReset(async_resolve_count=1))
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  def testListSubDir(self):
51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    expected = ['empty.txt'] + ['file%d.html' % i for i in range(3)]
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    file_system, fetcher = _CreateSubversionFileSystem(
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        _SHARED_FILE_SYSTEM_TEST_DATA)
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    list_future = file_system.ReadSingle('list/dir/')
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self.assertTrue(*fetcher.CheckAndReset(async_count=1))
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self.assertEqual(expected, sorted(list_future.Get()))
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self.assertTrue(*fetcher.CheckAndReset(async_resolve_count=1))
58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  def testDirStat(self):
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    file_system, fetcher = _CreateSubversionFileSystem(
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        _SHARED_FILE_SYSTEM_TEST_DATA)
627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    stat_info = file_system.Stat('stat/')
63e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    self.assertTrue(*fetcher.CheckAndReset(async_count=1,
64e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                           async_resolve_count=1))
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    expected = StatInfo(
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      '151113',
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      child_versions=json.loads(ReadFile(
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          SERVER2, 'test_data', 'file_system', 'stat_result.json')))
69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    self.assertEqual(expected, stat_info)
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  def testFileStat(self):
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    file_system, fetcher = _CreateSubversionFileSystem(
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        _SHARED_FILE_SYSTEM_TEST_DATA)
74b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    stat_info = file_system.Stat('stat/extension_api.h')
75e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    self.assertTrue(*fetcher.CheckAndReset(async_count=1,
76e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                           async_resolve_count=1))
77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    self.assertEqual(StatInfo('146163'), stat_info)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  def testRevisions(self):
80a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    # This is a super hacky test. Record the path that was fetched then exit the
81a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    # test. Compare.
82a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    class ValueErrorFetcher(object):
83a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      def __init__(self):
84a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        self.last_fetched = None
85a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
86a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      def FetchAsync(self, path):
872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        class ThrowsValueError(object):
88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          def Get(self): raise ValueError()
89a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        self.last_fetched = path
902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        return ThrowsValueError()
91a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      def Fetch(self, path, **kwargs):
93a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        self.last_fetched = path
94a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        raise ValueError()
95a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
96a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    file_fetcher = ValueErrorFetcher()
97a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    stat_fetcher = ValueErrorFetcher()
98a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    svn_path = 'svn:'
99a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
100a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    svn_file_system = SubversionFileSystem(file_fetcher,
101a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           stat_fetcher,
102a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           svn_path,
103a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           revision=42)
104a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self.assertRaises(FileSystemError,
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                      svn_file_system.ReadSingle('dir/file').Get)
107a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    self.assertEqual('dir/file?p=42', file_fetcher.last_fetched)
108a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    # Stat() will always stat directories.
109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    self.assertRaises(FileSystemError, svn_file_system.Stat, 'dir/file')
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    self.assertEqual('dir?pathrev=42', stat_fetcher.last_fetched)
111a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    self.assertRaises(FileSystemError,
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                      svn_file_system.ReadSingle('dir/').Get)
114a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    self.assertEqual('dir/?p=42', file_fetcher.last_fetched)
115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    self.assertRaises(FileSystemError, svn_file_system.Stat, 'dir/')
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    self.assertEqual('dir?pathrev=42', stat_fetcher.last_fetched)
117a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  def testDirectoryVersionOnDeletion(self):
1192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    '''Tests the case when the most recent operation on a directory is the
1202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    deletion of a file. Here it is not enough to take the maximum version of all
1212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    files in the directory, as we used to, for obvious reasons.
1222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    '''
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    file_system, _ = _CreateSubversionFileSystem(
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        _SUBVERSION_FILE_SYSTEM_TEST_DATA)
1252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    dir_stat = file_system.Stat('docs_public_extensions_214898/')
1262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    self.assertEqual('214692', dir_stat.version)
1272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  def testEmptyDirectory(self):
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    file_system, _ = _CreateSubversionFileSystem(
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        _SUBVERSION_FILE_SYSTEM_TEST_DATA)
1312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    dir_stat = file_system.Stat('api_icons_214898/')
1322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    self.assertEqual('193838', dir_stat.version)
1332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    self.assertEqual({}, dir_stat.child_versions)
1342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
135e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    def testSkipNotFound(self):
136e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      file_system, _ = _CreateSubversionFileSystem(
137e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          _SUBVERSION_FILE_SYSTEM_TEST_DATA)
138e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      self.assertEqual({}, file_system.Read(('fakefile',),
139e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                            skip_not_found=True).Get())
140e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
141e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__':
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unittest.main()
144