xpcom/tests/TestFile.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "prio.h"
michael@0 7 #include "prsystem.h"
michael@0 8
michael@0 9 #include "TestHarness.h"
michael@0 10
michael@0 11 #include "nsIFile.h"
michael@0 12 #include "nsDirectoryServiceDefs.h"
michael@0 13 #include "nsDirectoryServiceUtils.h"
michael@0 14
michael@0 15 static const char* gFunction = "main";
michael@0 16
michael@0 17 static bool VerifyResult(nsresult aRV, const char* aMsg)
michael@0 18 {
michael@0 19 if (NS_FAILED(aRV)) {
michael@0 20 fail("%s %s, rv=%x", gFunction, aMsg, aRV);
michael@0 21 return false;
michael@0 22 }
michael@0 23 return true;
michael@0 24 }
michael@0 25
michael@0 26 static already_AddRefed<nsIFile> NewFile(nsIFile* aBase)
michael@0 27 {
michael@0 28 nsresult rv;
michael@0 29 nsCOMPtr<nsIFile> file =
michael@0 30 do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
michael@0 31 VerifyResult(rv, "Creating nsIFile");
michael@0 32 rv = file->InitWithFile(aBase);
michael@0 33 VerifyResult(rv, "InitWithFile");
michael@0 34 return file.forget();
michael@0 35 }
michael@0 36
michael@0 37 static nsCString FixName(const char* aName)
michael@0 38 {
michael@0 39 nsCString name;
michael@0 40 for (uint32_t i = 0; aName[i]; ++i) {
michael@0 41 char ch = aName[i];
michael@0 42 // PR_GetPathSeparator returns the wrong value on Mac so don't use it
michael@0 43 #if defined(XP_WIN)
michael@0 44 if (ch == '/') {
michael@0 45 ch = '\\';
michael@0 46 }
michael@0 47 #endif
michael@0 48 name.Append(ch);
michael@0 49 }
michael@0 50 return name;
michael@0 51 }
michael@0 52
michael@0 53 // Test nsIFile::AppendNative, verifying that aName is not a valid file name
michael@0 54 static bool TestInvalidFileName(nsIFile* aBase, const char* aName)
michael@0 55 {
michael@0 56 gFunction = "TestInvalidFileName";
michael@0 57 nsCOMPtr<nsIFile> file = NewFile(aBase);
michael@0 58 if (!file)
michael@0 59 return false;
michael@0 60
michael@0 61 nsCString name = FixName(aName);
michael@0 62 nsresult rv = file->AppendNative(name);
michael@0 63 if (NS_SUCCEEDED(rv)) {
michael@0 64 fail("%s AppendNative with invalid filename %s", gFunction, name.get());
michael@0 65 return false;
michael@0 66 }
michael@0 67
michael@0 68 return true;
michael@0 69 }
michael@0 70
michael@0 71 // Test nsIFile::Create, verifying that the file exists and did not exist before,
michael@0 72 // and leaving it there for future tests
michael@0 73 static bool TestCreate(nsIFile* aBase, const char* aName, int32_t aType, int32_t aPerm)
michael@0 74 {
michael@0 75 gFunction = "TestCreate";
michael@0 76 nsCOMPtr<nsIFile> file = NewFile(aBase);
michael@0 77 if (!file)
michael@0 78 return false;
michael@0 79
michael@0 80 nsCString name = FixName(aName);
michael@0 81 nsresult rv = file->AppendNative(name);
michael@0 82 if (!VerifyResult(rv, "AppendNative"))
michael@0 83 return false;
michael@0 84
michael@0 85 bool exists;
michael@0 86 rv = file->Exists(&exists);
michael@0 87 if (!VerifyResult(rv, "Exists (before)"))
michael@0 88 return false;
michael@0 89 if (exists) {
michael@0 90 fail("%s File %s already exists", gFunction, name.get());
michael@0 91 return false;
michael@0 92 }
michael@0 93
michael@0 94 rv = file->Create(aType, aPerm);
michael@0 95 if (!VerifyResult(rv, "Create"))
michael@0 96 return false;
michael@0 97
michael@0 98 rv = file->Exists(&exists);
michael@0 99 if (!VerifyResult(rv, "Exists (after)"))
michael@0 100 return false;
michael@0 101 if (!exists) {
michael@0 102 fail("%s File %s was not created", gFunction, name.get());
michael@0 103 return false;
michael@0 104 }
michael@0 105
michael@0 106 return true;
michael@0 107 }
michael@0 108
michael@0 109 // Test nsIFile::CreateUnique, verifying that the new file exists and if it existed before,
michael@0 110 // the new file has a different name.
michael@0 111 // The new file is left in place.
michael@0 112 static bool TestCreateUnique(nsIFile* aBase, const char* aName, int32_t aType, int32_t aPerm)
michael@0 113 {
michael@0 114 gFunction = "TestCreateUnique";
michael@0 115 nsCOMPtr<nsIFile> file = NewFile(aBase);
michael@0 116 if (!file)
michael@0 117 return false;
michael@0 118
michael@0 119 nsCString name = FixName(aName);
michael@0 120 nsresult rv = file->AppendNative(name);
michael@0 121 if (!VerifyResult(rv, "AppendNative"))
michael@0 122 return false;
michael@0 123
michael@0 124 bool existsBefore;
michael@0 125 rv = file->Exists(&existsBefore);
michael@0 126 if (!VerifyResult(rv, "Exists (before)"))
michael@0 127 return false;
michael@0 128
michael@0 129 rv = file->CreateUnique(aType, aPerm);
michael@0 130 if (!VerifyResult(rv, "Create"))
michael@0 131 return false;
michael@0 132
michael@0 133 bool existsAfter;
michael@0 134 rv = file->Exists(&existsAfter);
michael@0 135 if (!VerifyResult(rv, "Exists (after)"))
michael@0 136 return false;
michael@0 137 if (!existsAfter) {
michael@0 138 fail("%s File %s was not created", gFunction, name.get());
michael@0 139 return false;
michael@0 140 }
michael@0 141
michael@0 142 if (existsBefore) {
michael@0 143 nsAutoCString leafName;
michael@0 144 rv = file->GetNativeLeafName(leafName);
michael@0 145 if (!VerifyResult(rv, "GetNativeLeafName"))
michael@0 146 return false;
michael@0 147 if (leafName.Equals(name)) {
michael@0 148 fail("%s File %s was not given a new name by CreateUnique", gFunction, name.get());
michael@0 149 return false;
michael@0 150 }
michael@0 151 }
michael@0 152
michael@0 153 return true;
michael@0 154 }
michael@0 155
michael@0 156 // Test nsIFile::OpenNSPRFileDesc with DELETE_ON_CLOSE, verifying that the file exists
michael@0 157 // and did not exist before, and leaving it there for future tests
michael@0 158 static bool TestDeleteOnClose(nsIFile* aBase, const char* aName, int32_t aFlags, int32_t aPerm)
michael@0 159 {
michael@0 160 gFunction = "TestDeleteOnClose";
michael@0 161 nsCOMPtr<nsIFile> file = NewFile(aBase);
michael@0 162 if (!file)
michael@0 163 return false;
michael@0 164
michael@0 165 nsCString name = FixName(aName);
michael@0 166 nsresult rv = file->AppendNative(name);
michael@0 167 if (!VerifyResult(rv, "AppendNative"))
michael@0 168 return false;
michael@0 169
michael@0 170 bool exists;
michael@0 171 rv = file->Exists(&exists);
michael@0 172 if (!VerifyResult(rv, "Exists (before)"))
michael@0 173 return false;
michael@0 174 if (exists) {
michael@0 175 fail("%s File %s already exists", gFunction, name.get());
michael@0 176 return false;
michael@0 177 }
michael@0 178
michael@0 179 PRFileDesc* fileDesc;
michael@0 180 rv = file->OpenNSPRFileDesc(aFlags | nsIFile::DELETE_ON_CLOSE, aPerm, &fileDesc);
michael@0 181 if (!VerifyResult(rv, "OpenNSPRFileDesc"))
michael@0 182 return false;
michael@0 183 PRStatus status = PR_Close(fileDesc);
michael@0 184 if (status != PR_SUCCESS) {
michael@0 185 fail("%s File %s could not be closed", gFunction, name.get());
michael@0 186 return false;
michael@0 187 }
michael@0 188
michael@0 189 rv = file->Exists(&exists);
michael@0 190 if (!VerifyResult(rv, "Exists (after)"))
michael@0 191 return false;
michael@0 192 if (exists) {
michael@0 193 fail("%s File %s was not removed on close!", gFunction, name.get());
michael@0 194 return false;
michael@0 195 }
michael@0 196
michael@0 197 return true;
michael@0 198 }
michael@0 199
michael@0 200 // Test nsIFile::Remove, verifying that the file does not exist and did before
michael@0 201 static bool TestRemove(nsIFile* aBase, const char* aName, bool aRecursive)
michael@0 202 {
michael@0 203 gFunction = "TestDelete";
michael@0 204 nsCOMPtr<nsIFile> file = NewFile(aBase);
michael@0 205 if (!file)
michael@0 206 return false;
michael@0 207
michael@0 208 nsCString name = FixName(aName);
michael@0 209 nsresult rv = file->AppendNative(name);
michael@0 210 if (!VerifyResult(rv, "AppendNative"))
michael@0 211 return false;
michael@0 212
michael@0 213 bool exists;
michael@0 214 rv = file->Exists(&exists);
michael@0 215 if (!VerifyResult(rv, "Exists (before)"))
michael@0 216 return false;
michael@0 217 if (!exists) {
michael@0 218 fail("%s File %s does not exist", gFunction, name.get());
michael@0 219 return false;
michael@0 220 }
michael@0 221
michael@0 222 rv = file->Remove(aRecursive);
michael@0 223 if (!VerifyResult(rv, "Remove"))
michael@0 224 return false;
michael@0 225
michael@0 226 rv = file->Exists(&exists);
michael@0 227 if (!VerifyResult(rv, "Exists (after)"))
michael@0 228 return false;
michael@0 229 if (exists) {
michael@0 230 fail("%s File %s was not removed", gFunction, name.get());
michael@0 231 return false;
michael@0 232 }
michael@0 233
michael@0 234 return true;
michael@0 235 }
michael@0 236
michael@0 237 // Test nsIFile::MoveToNative, verifying that the file did not exist at the new location
michael@0 238 // before and does afterward, and that it does not exist at the old location anymore
michael@0 239 static bool TestMove(nsIFile* aBase, nsIFile* aDestDir, const char* aName, const char* aNewName)
michael@0 240 {
michael@0 241 gFunction = "TestMove";
michael@0 242 nsCOMPtr<nsIFile> file = NewFile(aBase);
michael@0 243 if (!file)
michael@0 244 return false;
michael@0 245
michael@0 246 nsCString name = FixName(aName);
michael@0 247 nsresult rv = file->AppendNative(name);
michael@0 248 if (!VerifyResult(rv, "AppendNative"))
michael@0 249 return false;
michael@0 250
michael@0 251 bool exists;
michael@0 252 rv = file->Exists(&exists);
michael@0 253 if (!VerifyResult(rv, "Exists (before)"))
michael@0 254 return false;
michael@0 255 if (!exists) {
michael@0 256 fail("%s File %s does not exist", gFunction, name.get());
michael@0 257 return false;
michael@0 258 }
michael@0 259
michael@0 260 nsCOMPtr<nsIFile> newFile = NewFile(file);
michael@0 261 nsCString newName = FixName(aNewName);
michael@0 262 rv = newFile->MoveToNative(aDestDir, newName);
michael@0 263 if (!VerifyResult(rv, "MoveToNative"))
michael@0 264 return false;
michael@0 265
michael@0 266 rv = file->Exists(&exists);
michael@0 267 if (!VerifyResult(rv, "Exists (after)"))
michael@0 268 return false;
michael@0 269 if (exists) {
michael@0 270 fail("%s File %s was not moved", gFunction, name.get());
michael@0 271 return false;
michael@0 272 }
michael@0 273
michael@0 274 file = NewFile(aDestDir);
michael@0 275 if (!file)
michael@0 276 return false;
michael@0 277 rv = file->AppendNative(newName);
michael@0 278 if (!VerifyResult(rv, "AppendNative"))
michael@0 279 return false;
michael@0 280 bool equal;
michael@0 281 rv = file->Equals(newFile, &equal);
michael@0 282 if (!VerifyResult(rv, "Equals"))
michael@0 283 return false;
michael@0 284 if (!equal) {
michael@0 285 fail("%s file object was not updated to destination", gFunction);
michael@0 286 return false;
michael@0 287 }
michael@0 288
michael@0 289 rv = file->Exists(&exists);
michael@0 290 if (!VerifyResult(rv, "Exists (new after)"))
michael@0 291 return false;
michael@0 292 if (!exists) {
michael@0 293 fail("%s Destination file %s was not created", gFunction, newName.get());
michael@0 294 return false;
michael@0 295 }
michael@0 296
michael@0 297 return true;
michael@0 298 }
michael@0 299
michael@0 300 // Test nsIFile::CopyToNative, verifying that the file did not exist at the new location
michael@0 301 // before and does afterward, and that it does exist at the old location too
michael@0 302 static bool TestCopy(nsIFile* aBase, nsIFile* aDestDir, const char* aName, const char* aNewName)
michael@0 303 {
michael@0 304 gFunction = "TestCopy";
michael@0 305 nsCOMPtr<nsIFile> file = NewFile(aBase);
michael@0 306 if (!file)
michael@0 307 return false;
michael@0 308
michael@0 309 nsCString name = FixName(aName);
michael@0 310 nsresult rv = file->AppendNative(name);
michael@0 311 if (!VerifyResult(rv, "AppendNative"))
michael@0 312 return false;
michael@0 313
michael@0 314 bool exists;
michael@0 315 rv = file->Exists(&exists);
michael@0 316 if (!VerifyResult(rv, "Exists (before)"))
michael@0 317 return false;
michael@0 318 if (!exists) {
michael@0 319 fail("%s File %s does not exist", gFunction, name.get());
michael@0 320 return false;
michael@0 321 }
michael@0 322
michael@0 323 nsCOMPtr<nsIFile> newFile = NewFile(file);
michael@0 324 nsCString newName = FixName(aNewName);
michael@0 325 rv = newFile->CopyToNative(aDestDir, newName);
michael@0 326 if (!VerifyResult(rv, "MoveToNative"))
michael@0 327 return false;
michael@0 328 bool equal;
michael@0 329 rv = file->Equals(newFile, &equal);
michael@0 330 if (!VerifyResult(rv, "Equals"))
michael@0 331 return false;
michael@0 332 if (!equal) {
michael@0 333 fail("%s file object updated unexpectedly", gFunction);
michael@0 334 return false;
michael@0 335 }
michael@0 336
michael@0 337 rv = file->Exists(&exists);
michael@0 338 if (!VerifyResult(rv, "Exists (after)"))
michael@0 339 return false;
michael@0 340 if (!exists) {
michael@0 341 fail("%s File %s was removed", gFunction, name.get());
michael@0 342 return false;
michael@0 343 }
michael@0 344
michael@0 345 file = NewFile(aDestDir);
michael@0 346 if (!file)
michael@0 347 return false;
michael@0 348 rv = file->AppendNative(newName);
michael@0 349 if (!VerifyResult(rv, "AppendNative"))
michael@0 350 return false;
michael@0 351
michael@0 352 rv = file->Exists(&exists);
michael@0 353 if (!VerifyResult(rv, "Exists (new after)"))
michael@0 354 return false;
michael@0 355 if (!exists) {
michael@0 356 fail("%s Destination file %s was not created", gFunction, newName.get());
michael@0 357 return false;
michael@0 358 }
michael@0 359
michael@0 360 return true;
michael@0 361 }
michael@0 362
michael@0 363 // Test nsIFile::GetParent
michael@0 364 static bool TestParent(nsIFile* aBase, nsIFile* aStart)
michael@0 365 {
michael@0 366 gFunction = "TestParent";
michael@0 367 nsCOMPtr<nsIFile> file = NewFile(aStart);
michael@0 368 if (!file)
michael@0 369 return false;
michael@0 370
michael@0 371 nsCOMPtr<nsIFile> parent;
michael@0 372 nsresult rv = file->GetParent(getter_AddRefs(parent));
michael@0 373 VerifyResult(rv, "GetParent");
michael@0 374
michael@0 375 bool equal;
michael@0 376 rv = parent->Equals(aBase, &equal);
michael@0 377 VerifyResult(rv, "Equals");
michael@0 378 if (!equal) {
michael@0 379 fail("%s Incorrect parent", gFunction);
michael@0 380 return false;
michael@0 381 }
michael@0 382
michael@0 383 return true;
michael@0 384 }
michael@0 385
michael@0 386 // Test nsIFile::Normalize and native path setting/getting
michael@0 387 static bool TestNormalizeNativePath(nsIFile* aBase, nsIFile* aStart)
michael@0 388 {
michael@0 389 gFunction = "TestNormalizeNativePath";
michael@0 390 nsCOMPtr<nsIFile> file = NewFile(aStart);
michael@0 391 if (!file)
michael@0 392 return false;
michael@0 393
michael@0 394 nsAutoCString path;
michael@0 395 nsresult rv = file->GetNativePath(path);
michael@0 396 VerifyResult(rv, "GetNativePath");
michael@0 397 path.Append(FixName("/./.."));
michael@0 398 rv = file->InitWithNativePath(path);
michael@0 399 VerifyResult(rv, "InitWithNativePath");
michael@0 400 rv = file->Normalize();
michael@0 401 VerifyResult(rv, "Normalize");
michael@0 402 rv = file->GetNativePath(path);
michael@0 403 VerifyResult(rv, "GetNativePath (after normalization)");
michael@0 404
michael@0 405 nsAutoCString basePath;
michael@0 406 rv = aBase->GetNativePath(basePath);
michael@0 407 VerifyResult(rv, "GetNativePath (base)");
michael@0 408
michael@0 409 if (!path.Equals(basePath)) {
michael@0 410 fail("%s Incorrect normalization");
michael@0 411 return false;
michael@0 412 }
michael@0 413
michael@0 414 return true;
michael@0 415 }
michael@0 416
michael@0 417 int main(int argc, char** argv)
michael@0 418 {
michael@0 419 ScopedXPCOM xpcom("nsLocalFile");
michael@0 420 if (xpcom.failed())
michael@0 421 return 1;
michael@0 422
michael@0 423 nsCOMPtr<nsIFile> base;
michael@0 424 nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(base));
michael@0 425 if (!VerifyResult(rv, "Getting temp directory"))
michael@0 426 return 1;
michael@0 427 rv = base->AppendNative(nsDependentCString("mozfiletests"));
michael@0 428 if (!VerifyResult(rv, "Appending mozfiletests to temp directory name"))
michael@0 429 return 1;
michael@0 430 // Remove the directory in case tests failed and left it behind.
michael@0 431 // don't check result since it might not be there
michael@0 432 base->Remove(true);
michael@0 433
michael@0 434 // Now create the working directory we're going to use
michael@0 435 rv = base->Create(nsIFile::DIRECTORY_TYPE, 0700);
michael@0 436 if (!VerifyResult(rv, "Creating temp directory"))
michael@0 437 return 1;
michael@0 438 // Now we can safely normalize the path
michael@0 439 rv = base->Normalize();
michael@0 440 if (!VerifyResult(rv, "Normalizing temp directory name"))
michael@0 441 return 1;
michael@0 442
michael@0 443 // Initialize subdir object for later use
michael@0 444 nsCOMPtr<nsIFile> subdir = NewFile(base);
michael@0 445 if (!subdir)
michael@0 446 return 1;
michael@0 447 rv = subdir->AppendNative(nsDependentCString("subdir"));
michael@0 448 if (!VerifyResult(rv, "Appending 'subdir' to test dir name"))
michael@0 449 return 1;
michael@0 450
michael@0 451 passed("Setup");
michael@0 452
michael@0 453 // Test path parsing
michael@0 454 if (TestInvalidFileName(base, "a/b")) {
michael@0 455 passed("AppendNative with invalid file name");
michael@0 456 }
michael@0 457 if (TestParent(base, subdir)) {
michael@0 458 passed("GetParent");
michael@0 459 }
michael@0 460
michael@0 461 // Test file creation
michael@0 462 if (TestCreate(base, "file.txt", nsIFile::NORMAL_FILE_TYPE, 0600)) {
michael@0 463 passed("Create file");
michael@0 464 }
michael@0 465 if (TestRemove(base, "file.txt", false)) {
michael@0 466 passed("Remove file");
michael@0 467 }
michael@0 468
michael@0 469 // Test directory creation
michael@0 470 if (TestCreate(base, "subdir", nsIFile::DIRECTORY_TYPE, 0700)) {
michael@0 471 passed("Create directory");
michael@0 472 }
michael@0 473
michael@0 474 // Test move and copy in the base directory
michael@0 475 if (TestCreate(base, "file.txt", nsIFile::NORMAL_FILE_TYPE, 0600) &&
michael@0 476 TestMove(base, base, "file.txt", "file2.txt")) {
michael@0 477 passed("MoveTo rename file");
michael@0 478 }
michael@0 479 if (TestCopy(base, base, "file2.txt", "file3.txt")) {
michael@0 480 passed("CopyTo copy file");
michael@0 481 }
michael@0 482 // Test moving across directories
michael@0 483 if (TestMove(base, subdir, "file2.txt", "file2.txt")) {
michael@0 484 passed("MoveTo move file");
michael@0 485 }
michael@0 486 // Test moving across directories and renaming at the same time
michael@0 487 if (TestMove(subdir, base, "file2.txt", "file4.txt")) {
michael@0 488 passed("MoveTo move and rename file");
michael@0 489 }
michael@0 490 // Test copying across directoreis
michael@0 491 if (TestCopy(base, subdir, "file4.txt", "file5.txt")) {
michael@0 492 passed("CopyTo copy file across directories");
michael@0 493 }
michael@0 494
michael@0 495 // Run normalization tests while the directory exists
michael@0 496 if (TestNormalizeNativePath(base, subdir)) {
michael@0 497 passed("Normalize with native paths");
michael@0 498 }
michael@0 499
michael@0 500 // Test recursive directory removal
michael@0 501 if (TestRemove(base, "subdir", true)) {
michael@0 502 passed("Remove directory");
michael@0 503 }
michael@0 504
michael@0 505 if (TestCreateUnique(base, "foo", nsIFile::NORMAL_FILE_TYPE, 0600) &&
michael@0 506 TestCreateUnique(base, "foo", nsIFile::NORMAL_FILE_TYPE, 0600)) {
michael@0 507 passed("CreateUnique file");
michael@0 508 }
michael@0 509 if (TestCreateUnique(base, "bar.xx", nsIFile::DIRECTORY_TYPE, 0700) &&
michael@0 510 TestCreateUnique(base, "bar.xx", nsIFile::DIRECTORY_TYPE, 0700)) {
michael@0 511 passed("CreateUnique directory");
michael@0 512 }
michael@0 513
michael@0 514 if (TestDeleteOnClose(base, "file7.txt", PR_RDWR | PR_CREATE_FILE, 0600)) {
michael@0 515 passed("OpenNSPRFileDesc DELETE_ON_CLOSE");
michael@0 516 }
michael@0 517
michael@0 518 gFunction = "main";
michael@0 519 // Clean up temporary stuff
michael@0 520 rv = base->Remove(true);
michael@0 521 VerifyResult(rv, "Cleaning up temp directory");
michael@0 522
michael@0 523 return gFailCount > 0;
michael@0 524 }

mercurial