diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:04:04 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:04:04 -0800 |
commit | 9ca1c0b33cc3fc28c21a915730797ec01e71a152 (patch) | |
tree | 86a5d0cea812248b02df654e925f55915e47bdf7 /scripts/test_divide_and_compress.py | |
parent | 1506a206c0a5e3b593c4c61a62b8805b64e98daf (diff) | |
download | sdk-9ca1c0b33cc3fc28c21a915730797ec01e71a152.zip sdk-9ca1c0b33cc3fc28c21a915730797ec01e71a152.tar.gz sdk-9ca1c0b33cc3fc28c21a915730797ec01e71a152.tar.bz2 |
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'scripts/test_divide_and_compress.py')
-rwxr-xr-x | scripts/test_divide_and_compress.py | 490 |
1 files changed, 490 insertions, 0 deletions
diff --git a/scripts/test_divide_and_compress.py b/scripts/test_divide_and_compress.py new file mode 100755 index 0000000..d0d27b3 --- /dev/null +++ b/scripts/test_divide_and_compress.py @@ -0,0 +1,490 @@ +#!/usr/bin/python2.4 +# +# Copyright (C) 2008 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +"""Tests for divide_and_compress.py. + +TODO: Add tests for module methods. +""" + +__author__ = 'jmatt@google.com (Justin Mattson)' + +import os +import stat +import unittest +import zipfile +from zipfile import ZipFile + +import divide_and_compress +from mox import mox + + +class BagOfParts(object): + """Just a generic class that I can use to assign random attributes to.""" + + def NoOp(self): + x = 1 + + +class ValidAndRemoveTests(unittest.TestCase): + """Test the ArchiveIsValid and RemoveLastFile methods.""" + + def setUp(self): + """Prepare the test. + + Construct some mock objects for use with the tests. + """ + self.my_mox = mox.Mox() + file1 = BagOfParts() + file1.filename = 'file1.txt' + file1.contents = 'This is a test file' + file2 = BagOfParts() + file2.filename = 'file2.txt' + file2.contents = ('akdjfk;djsf;kljdslkfjslkdfjlsfjkdvn;kn;2389rtu4i' + 'tn;ghf8:89H*hp748FJw80fu9WJFpwf39pujens;fihkhjfk' + 'sdjfljkgsc n;iself') + self.files = {'file1': file1, 'file2': file2} + + def testArchiveIsValid(self): + """Test the DirectoryZipper.ArchiveIsValid method. + + Run two tests, one that we expect to pass and one that we expect to fail + """ + test_file_size = 1056730 + self.my_mox.StubOutWithMock(os, 'stat') + os.stat('/foo/0.zip').AndReturn([test_file_size]) + self.my_mox.StubOutWithMock(stat, 'ST_SIZE') + stat.ST_SIZE = 0 + os.stat('/baz/0.zip').AndReturn([test_file_size]) + mox.Replay(os.stat) + test_target = divide_and_compress.DirectoryZipper('/foo/', 'bar', + test_file_size - 1, True) + + self.assertEqual(False, test_target.ArchiveIsValid(), + msg=('ERROR: Test failed, ArchiveIsValid should have ' + 'returned false, but returned true')) + + test_target = divide_and_compress.DirectoryZipper('/baz/', 'bar', + test_file_size + 1, True) + self.assertEqual(True, test_target.ArchiveIsValid(), + msg=('ERROR: Test failed, ArchiveIsValid should have' + ' returned true, but returned false')) + + def testRemoveLastFile(self): + """Test DirectoryZipper.RemoveLastFile method. + + Construct a ZipInfo mock object with two records, verify that write is + only called once on the new ZipFile object. + """ + source = self.CreateZipSource() + dest = self.CreateZipDestination() + source_path = ''.join([os.getcwd(), '/0-old.zip']) + dest_path = ''.join([os.getcwd(), '/0.zip']) + test_target = divide_and_compress.DirectoryZipper( + ''.join([os.getcwd(), '/']), 'dummy', 1024*1024, True) + self.my_mox.StubOutWithMock(test_target, 'OpenZipFileAtPath') + test_target.OpenZipFileAtPath(source_path, mode='r').AndReturn(source) + test_target.OpenZipFileAtPath(dest_path, + compress=zipfile.ZIP_DEFLATED, + mode='w').AndReturn(dest) + self.my_mox.StubOutWithMock(os, 'rename') + os.rename(dest_path, source_path) + self.my_mox.StubOutWithMock(os, 'unlink') + os.unlink(source_path) + + self.my_mox.ReplayAll() + test_target.RemoveLastFile() + self.my_mox.VerifyAll() + + def CreateZipSource(self): + """Create a mock zip sourec object. + + Read should only be called once, because the second file is the one + being removed. + + Returns: + A configured mocked + """ + + source_zip = self.my_mox.CreateMock(ZipFile) + source_zip.infolist().AndReturn([self.files['file1'], self.files['file1']]) + source_zip.infolist().AndReturn([self.files['file1'], self.files['file1']]) + source_zip.read(self.files['file1'].filename).AndReturn( + self.files['file1'].contents) + source_zip.close() + return source_zip + + def CreateZipDestination(self): + """Create mock destination zip. + + Write should only be called once, because there are two files in the + source zip and we expect the second to be removed. + + Returns: + A configured mocked + """ + + dest_zip = mox.MockObject(ZipFile) + dest_zip.writestr(self.files['file1'].filename, + self.files['file1'].contents) + dest_zip.close() + return dest_zip + + def tearDown(self): + """Remove any stubs we've created.""" + self.my_mox.UnsetStubs() + + +class FixArchiveTests(unittest.TestCase): + """Tests for the DirectoryZipper.FixArchive method.""" + + def setUp(self): + """Create a mock file object.""" + self.my_mox = mox.Mox() + self.file1 = BagOfParts() + self.file1.filename = 'file1.txt' + self.file1.contents = 'This is a test file' + + def _InitMultiFileData(self): + """Create an array of mock file objects. + + Create three mock file objects that we can use for testing. + """ + self.multi_file_dir = [] + + file1 = BagOfParts() + file1.filename = 'file1.txt' + file1.contents = 'kjaskl;jkdjfkja;kjsnbvjnvnbuewklriujalvjsd' + self.multi_file_dir.append(file1) + + file2 = BagOfParts() + file2.filename = 'file2.txt' + file2.contents = ('He entered the room and there in the center, it was.' + ' Looking upon the thing, suddenly he could not remember' + ' whether he had actually seen it before or whether' + ' his memory of it was merely the effect of something' + ' so often being imagined that it had long since become ' + ' manifest in his mind.') + self.multi_file_dir.append(file2) + + file3 = BagOfParts() + file3.filename = 'file3.txt' + file3.contents = 'Whoa, what is \'file2.txt\' all about?' + self.multi_file_dir.append(file3) + + def testSingleFileArchive(self): + """Test behavior of FixArchive when the archive has a single member. + + We expect that when this method is called with an archive that has a + single member that it will return False and unlink the archive. + """ + test_target = divide_and_compress.DirectoryZipper( + ''.join([os.getcwd(), '/']), 'dummy', 1024*1024, True) + self.my_mox.StubOutWithMock(test_target, 'OpenZipFileAtPath') + test_target.OpenZipFileAtPath( + ''.join([os.getcwd(), '/0.zip']), mode='r').AndReturn( + self.CreateSingleFileMock()) + self.my_mox.StubOutWithMock(os, 'unlink') + os.unlink(''.join([os.getcwd(), '/0.zip'])) + self.my_mox.ReplayAll() + self.assertEqual(False, test_target.FixArchive('SIZE')) + self.my_mox.VerifyAll() + + def CreateSingleFileMock(self): + """Create a mock ZipFile object for testSingleFileArchive. + + We just need it to return a single member infolist twice + + Returns: + A configured mock object + """ + mock_zip = self.my_mox.CreateMock(ZipFile) + mock_zip.infolist().AndReturn([self.file1]) + mock_zip.infolist().AndReturn([self.file1]) + mock_zip.close() + return mock_zip + + def testMultiFileArchive(self): + """Test behavior of DirectoryZipper.FixArchive with a multi-file archive. + + We expect that FixArchive will rename the old archive, adding '-old' before + '.zip', read all the members except the last one of '-old' into a new + archive with the same name as the original, and then unlink the '-old' copy + """ + test_target = divide_and_compress.DirectoryZipper( + ''.join([os.getcwd(), '/']), 'dummy', 1024*1024, True) + self.my_mox.StubOutWithMock(test_target, 'OpenZipFileAtPath') + test_target.OpenZipFileAtPath( + ''.join([os.getcwd(), '/0.zip']), mode='r').AndReturn( + self.CreateMultiFileMock()) + self.my_mox.StubOutWithMock(test_target, 'RemoveLastFile') + test_target.RemoveLastFile(''.join([os.getcwd(), '/0.zip'])) + self.my_mox.StubOutWithMock(os, 'stat') + os.stat(''.join([os.getcwd(), '/0.zip'])).AndReturn([49302]) + self.my_mox.StubOutWithMock(stat, 'ST_SIZE') + stat.ST_SIZE = 0 + self.my_mox.ReplayAll() + self.assertEqual(True, test_target.FixArchive('SIZE')) + self.my_mox.VerifyAll() + + def CreateMultiFileMock(self): + """Create mock ZipFile object for use with testMultiFileArchive. + + The mock just needs to return the infolist mock that is prepared in + InitMultiFileData() + + Returns: + A configured mock object + """ + self._InitMultiFileData() + mock_zip = self.my_mox.CreateMock(ZipFile) + mock_zip.infolist().AndReturn(self.multi_file_dir) + mock_zip.close() + return mock_zip + + def tearDown(self): + """Unset any mocks that we've created.""" + self.my_mox.UnsetStubs() + + +class AddFileToArchiveTest(unittest.TestCase): + """Test behavior of method to add a file to an archive.""" + + def setUp(self): + """Setup the arguments for the DirectoryZipper object.""" + self.my_mox = mox.Mox() + self.output_dir = '%s/' % os.getcwd() + self.file_to_add = 'file.txt' + self.input_dir = '/foo/bar/baz/' + + def testAddFileToArchive(self): + """Test the DirectoryZipper.AddFileToArchive method. + + We are testing a pretty trivial method, we just expect it to look at the + file its adding, so that it possible can through out a warning. + """ + test_target = divide_and_compress.DirectoryZipper(self.output_dir, + self.input_dir, + 1024*1024, True) + self.my_mox.StubOutWithMock(test_target, 'OpenZipFileAtPath') + archive_mock = self.CreateArchiveMock() + test_target.OpenZipFileAtPath( + ''.join([self.output_dir, '0.zip']), + compress=zipfile.ZIP_DEFLATED).AndReturn(archive_mock) + self.StubOutOsModule() + self.my_mox.ReplayAll() + test_target.AddFileToArchive(''.join([self.input_dir, self.file_to_add]), + zipfile.ZIP_DEFLATED) + self.my_mox.VerifyAll() + + def StubOutOsModule(self): + """Create a mock for the os.path and os.stat objects. + + Create a stub that will return the type (file or directory) and size of the + object that is to be added. + """ + self.my_mox.StubOutWithMock(os.path, 'isfile') + os.path.isfile(''.join([self.input_dir, self.file_to_add])).AndReturn(True) + self.my_mox.StubOutWithMock(os, 'stat') + os.stat(''.join([self.input_dir, self.file_to_add])).AndReturn([39480]) + self.my_mox.StubOutWithMock(stat, 'ST_SIZE') + stat.ST_SIZE = 0 + + def CreateArchiveMock(self): + """Create a mock ZipFile for use with testAddFileToArchive. + + Just verify that write is called with the file we expect and that the + archive is closed after the file addition + + Returns: + A configured mock object + """ + archive_mock = self.my_mox.CreateMock(ZipFile) + archive_mock.write(''.join([self.input_dir, self.file_to_add]), + self.file_to_add) + archive_mock.close() + return archive_mock + + def tearDown(self): + self.my_mox.UnsetStubs() + + +class CompressDirectoryTest(unittest.TestCase): + """Test the master method of the class. + + Testing with the following directory structure. + /dir1/ + /dir1/file1.txt + /dir1/file2.txt + /dir1/dir2/ + /dir1/dir2/dir3/ + /dir1/dir2/dir4/ + /dir1/dir2/dir4/file3.txt + /dir1/dir5/ + /dir1/dir5/file4.txt + /dir1/dir5/file5.txt + /dir1/dir5/file6.txt + /dir1/dir5/file7.txt + /dir1/dir6/ + /dir1/dir6/file8.txt + + file1.txt., file2.txt, file3.txt should be in 0.zip + file4.txt should be in 1.zip + file5.txt, file6.txt should be in 2.zip + file7.txt will not be stored since it will be too large compressed + file8.txt should b in 3.zip + """ + + def setUp(self): + """Setup all the mocks for this test.""" + self.my_mox = mox.Mox() + + self.base_dir = '/dir1' + self.output_path = '/out_dir/' + self.test_target = divide_and_compress.DirectoryZipper( + self.output_path, self.base_dir, 1024*1024, True) + + self.InitArgLists() + self.InitOsDotPath() + self.InitArchiveIsValid() + self.InitWriteIndexRecord() + self.InitAddFileToArchive() + + def tearDown(self): + self.my_mox.UnsetStubs() + + def testCompressDirectory(self): + """Test the DirectoryZipper.CompressDirectory method.""" + self.my_mox.ReplayAll() + for arguments in self.argument_lists: + self.test_target.CompressDirectory(None, arguments[0], arguments[1]) + self.my_mox.VerifyAll() + + def InitAddFileToArchive(self): + """Setup mock for DirectoryZipper.AddFileToArchive. + + Make sure that the files are added in the order we expect. + """ + self.my_mox.StubOutWithMock(self.test_target, 'AddFileToArchive') + self.test_target.AddFileToArchive('/dir1/file1.txt', zipfile.ZIP_DEFLATED) + self.test_target.AddFileToArchive('/dir1/file2.txt', zipfile.ZIP_DEFLATED) + self.test_target.AddFileToArchive('/dir1/dir2/dir4/file3.txt', + zipfile.ZIP_DEFLATED) + self.test_target.AddFileToArchive('/dir1/dir5/file4.txt', + zipfile.ZIP_DEFLATED) + self.test_target.AddFileToArchive('/dir1/dir5/file4.txt', + zipfile.ZIP_DEFLATED) + self.test_target.AddFileToArchive('/dir1/dir5/file5.txt', + zipfile.ZIP_DEFLATED) + self.test_target.AddFileToArchive('/dir1/dir5/file5.txt', + zipfile.ZIP_DEFLATED) + self.test_target.AddFileToArchive('/dir1/dir5/file6.txt', + zipfile.ZIP_DEFLATED) + self.test_target.AddFileToArchive('/dir1/dir5/file7.txt', + zipfile.ZIP_DEFLATED) + self.test_target.AddFileToArchive('/dir1/dir5/file7.txt', + zipfile.ZIP_DEFLATED) + self.test_target.AddFileToArchive('/dir1/dir6/file8.txt', + zipfile.ZIP_DEFLATED) + + def InitWriteIndexRecord(self): + """Setup mock for DirectoryZipper.WriteIndexRecord.""" + self.my_mox.StubOutWithMock(self.test_target, 'WriteIndexRecord') + + # we are trying to compress 8 files, but we should only attempt to + # write an index record 7 times, because one file is too large to be stored + self.test_target.WriteIndexRecord().AndReturn(True) + self.test_target.WriteIndexRecord().AndReturn(False) + self.test_target.WriteIndexRecord().AndReturn(False) + self.test_target.WriteIndexRecord().AndReturn(True) + self.test_target.WriteIndexRecord().AndReturn(True) + self.test_target.WriteIndexRecord().AndReturn(False) + self.test_target.WriteIndexRecord().AndReturn(True) + + def InitArchiveIsValid(self): + """Mock out DirectoryZipper.ArchiveIsValid and DirectoryZipper.FixArchive. + + Mock these methods out such that file1, file2, and file3 go into one + archive. file4 then goes into the next archive, file5 and file6 in the + next, file 7 should appear too large to compress into an archive, and + file8 goes into the final archive + """ + self.my_mox.StubOutWithMock(self.test_target, 'ArchiveIsValid') + self.my_mox.StubOutWithMock(self.test_target, 'FixArchive') + self.test_target.ArchiveIsValid().AndReturn(True) + self.test_target.ArchiveIsValid().AndReturn(True) + self.test_target.ArchiveIsValid().AndReturn(True) + + # should be file4.txt + self.test_target.ArchiveIsValid().AndReturn(False) + self.test_target.FixArchive('SIZE').AndReturn(True) + self.test_target.ArchiveIsValid().AndReturn(True) + + # should be file5.txt + self.test_target.ArchiveIsValid().AndReturn(False) + self.test_target.FixArchive('SIZE').AndReturn(True) + self.test_target.ArchiveIsValid().AndReturn(True) + self.test_target.ArchiveIsValid().AndReturn(True) + + # should be file7.txt + self.test_target.ArchiveIsValid().AndReturn(False) + self.test_target.FixArchive('SIZE').AndReturn(True) + self.test_target.ArchiveIsValid().AndReturn(False) + self.test_target.FixArchive('SIZE').AndReturn(False) + self.test_target.ArchiveIsValid().AndReturn(True) + + def InitOsDotPath(self): + """Mock out os.path.isfile. + + Mock this out so the things we want to appear as files appear as files and + the things we want to appear as directories appear as directories. Also + make sure that the order of file visits is as we expect (which is why + InAnyOrder isn't used here). + """ + self.my_mox.StubOutWithMock(os.path, 'isfile') + os.path.isfile('/dir1/dir2').AndReturn(False) + os.path.isfile('/dir1/dir5').AndReturn(False) + os.path.isfile('/dir1/dir6').AndReturn(False) + os.path.isfile('/dir1/file1.txt').AndReturn(True) + os.path.isfile('/dir1/file2.txt').AndReturn(True) + os.path.isfile('/dir1/dir2/dir3').AndReturn(False) + os.path.isfile('/dir1/dir2/dir4').AndReturn(False) + os.path.isfile('/dir1/dir2/dir4/file3.txt').AndReturn(True) + os.path.isfile('/dir1/dir5/file4.txt').AndReturn(True) + os.path.isfile('/dir1/dir5/file4.txt').AndReturn(True) + os.path.isfile('/dir1/dir5/file5.txt').AndReturn(True) + os.path.isfile('/dir1/dir5/file5.txt').AndReturn(True) + os.path.isfile('/dir1/dir5/file6.txt').AndReturn(True) + os.path.isfile('/dir1/dir5/file7.txt').AndReturn(True) + os.path.isfile('/dir1/dir5/file7.txt').AndReturn(True) + os.path.isfile('/dir1/dir6/file8.txt').AndReturn(True) + + def InitArgLists(self): + """Create the directory path => directory contents mappings.""" + self.argument_lists = [] + self.argument_lists.append(['/dir1', + ['file1.txt', 'file2.txt', 'dir2', 'dir5', + 'dir6']]) + self.argument_lists.append(['/dir1/dir2', ['dir3', 'dir4']]) + self.argument_lists.append(['/dir1/dir2/dir3', []]) + self.argument_lists.append(['/dir1/dir2/dir4', ['file3.txt']]) + self.argument_lists.append(['/dir1/dir5', + ['file4.txt', 'file5.txt', 'file6.txt', + 'file7.txt']]) + self.argument_lists.append(['/dir1/dir6', ['file8.txt']]) + +if __name__ == '__main__': + unittest.main() |