zipTestWrite.cpp
Engine/source/core/util/zip/test/zipTestWrite.cpp
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23/* 24#include "core/strings/stringFunctions.h" 25#include "core/util/zip/zipArchive.h" 26#include "core/util/zip/unitTests/zipTest.h" 27 28#include "unit/test.h" 29#include "unit/memoryTester.h" 30 31 32using namespace UnitTesting; 33using namespace Zip; 34 35CreateUnitTest(ZipTestWrite, "Zip/Write") 36{ 37private: 38 StringTableEntry mWriteFilename; 39 StringTableEntry mBaselineFilename; 40 StringTableEntry mWorkingFilename; 41 42public: 43 /// Number of files to write for testing large numbers of files in a zip 44 static const U32 mTons = 5000; 45 46 ZipTestWrite() 47 { 48 mWriteFilename = makeTestPath(ZIPTEST_WRITE_FILENAME); 49 mBaselineFilename = makeTestPath(ZIPTEST_BASELINE_FILENAME); 50 mWorkingFilename = makeTestPath(ZIPTEST_WORKING_FILENAME); 51 } 52 53 void run() 54 { 55 MemoryTester m; 56 m.mark(); 57 58 // Clean up from a previous run 59 cleanup(); 60 61 // Test writing to zip files without the zip file existing 62 testWriting(mWriteFilename, ZipArchive::Read); 63 testWriting(mWriteFilename, ZipArchive::ReadWrite); 64 65 // Cleanup to try write without existing file 66 cleanup(); 67 testWriting(mWriteFilename, ZipArchive::Write); 68 69 // Now use previous file to test everything again with an existing file 70 testWriting(mWriteFilename, ZipArchive::ReadWrite); 71 testWriting(mWriteFilename, ZipArchive::Write); 72 testWriting(mWriteFilename, ZipArchive::Read); 73 74 testWritingTons(makeTestPath("WriteTons.zip")); 75 76 test(m.check(), "Zip write test leaked memory!"); 77 } 78 79private: 80 81 //----------------------------------------------------------------------------- 82 83 void cleanup() 84 { 85 if(Platform::isFile(mWriteFilename)) 86 dFileDelete(mWriteFilename); 87 if(Platform::isFile(mWorkingFilename)) 88 dFileDelete(mWorkingFilename); 89 } 90 91 //----------------------------------------------------------------------------- 92 93 bool writeFile(ZipArchive *zip, const char *filename, char *fileBuf, U32 bufSize, bool mustNotExist = false, const char *contents = NULL) 94 { 95 if(mustNotExist && fileBuf && bufSize > 0) 96 { 97 // Find a unique filename 98 U32 count = 1; 99 dStrcpy(fileBuf, filename, bufSize); 100 101 while(zip->findFileInfo(fileBuf)) 102 { 103 dSprintf(fileBuf, bufSize, "%s.%04x", filename, count++); 104 105 if(count == 0) 106 { 107 fail("writeFile - got stuck in an infinite loop looking for a unique filename"); 108 return false; 109 } 110 } 111 } 112 else if(fileBuf && bufSize > 0) 113 dStrcpy(fileBuf, filename, bufSize); 114 115 // Try and write to the file 116 Stream * stream = zip->openFile(fileBuf ? fileBuf : filename, ZipArchive::Write); 117 if(stream != NULL) 118 { 119 stream->writeLine(contents ? (U8 *)contents : (U8 *)"This is a test of writing to a file."); 120 zip->closeFile(stream); 121 122 return true; 123 } 124 125 return false; 126 } 127 128 //----------------------------------------------------------------------------- 129 130 bool testWriting(const char *zipfile, ZipArchive::AccessMode mode) 131 { 132 ZipArchive *zip = new ZipArchive; 133 134 if(! zip->openArchive(zipfile, mode)) 135 { 136 delete zip; 137 138 // This is only an error if we're not trying to open as read 139 140 if(mode != ZipArchive::Read) 141 fail("Unable to open zip file"); 142 143 return mode == ZipArchive::Read; 144 } 145 146 char fileBuf[1024]; 147 148 // Write to file that doesn't already exist 149 if(!writeFile(zip, "testWriteNew.txt", fileBuf, sizeof(fileBuf), true)) 150 { 151 fail("Couldn't write to a file that didn't already exist"); 152 goto bail; 153 } 154 155 // Write to file that we've already written to 156 if(!writeFile(zip, fileBuf, NULL, 0, false, "This is a test of overwriting the file.")) 157 { 158 if(mode != ZipArchive::Read) 159 fail("Couldn't write to a file that we've already written to"); 160 goto bail; 161 } 162 163 // Write to file that already exists, but we haven't written to 164 // To do this, we need to close and re-open the zipfile 165 166 zip->closeArchive(); 167 delete zip; 168 169 zip = new ZipArchive; 170 if(! zip->openArchive(zipfile, mode)) 171 { 172 delete zip; 173 fail("Unable to re-open zip file. Strange!"); 174 return false; 175 } 176 177 // Use the file we already overwrote since we are sure of it's filename 178 if(!writeFile(zip, fileBuf, NULL, 0, false, "This is a test of overwriting the file again.")) 179 { 180 if(mode != ZipArchive::Read) 181 fail("Couldn't write to a file that already existed"); 182 goto bail; 183 } 184 185 { 186 // Move this into its own scope to deal with goto 'crosses initialization' errors 187 // Attempt to open a file for write that's already open for write (should fail) 188 Stream * stream1 = zip->openFile("writeLockTest.txt", ZipArchive::Write); 189 if(stream1 != NULL) 190 { 191 stream1->writeLine((U8 *)"Test text to make a valid file"); 192 193 // This next open should fail 194 Stream * stream2 = zip->openFile("writeLockTest.txt", ZipArchive::Write); 195 if(stream2 != NULL) 196 { 197 if(mode != ZipArchive::Read) 198 fail("Opening a file for write multiple times should have failed"); 199 zip->closeFile(stream2); 200 } 201 zip->closeFile(stream1); 202 } 203 } 204 205bail: 206 zip->closeArchive(); 207 delete zip; 208 209 return true; 210 } 211 212 //----------------------------------------------------------------------------- 213 214 bool testWritingTons(const char *zipfile) 215 { 216 ZipArchive zip; 217 218 if(! zip.openArchive(zipfile, ZipArchive::Write)) 219 { 220 fail("Unable to open zip file"); 221 return false; 222 } 223 224 bool ret = true; 225 226 for(U32 i = 0;i < mTons;++i) 227 { 228 char fname[256]; 229 dSprintf(fname, sizeof(fname), "file%04x.txt", i); 230 231 if(! writeFile(&zip, fname, NULL, 0)) 232 { 233 fail("Failed to write file"); 234 fail(fname); 235 236 ret = false; 237 238 break; 239 } 240 } 241 242 zip.closeArchive(); 243 return ret; 244 } 245}; 246*/ 247