From f1396adce989b8c459736bdb5506c6e78d738c91 Mon Sep 17 00:00:00 2001 From: archshift Date: Wed, 10 Dec 2014 18:29:40 -0800 Subject: [PATCH 1/2] Added scope_exit, which is very helpful for handling situations where the test exits early. --- source/scope_exit.h | 37 +++++++++++++++++++++++++++++++++++++ source/tests/fs/fs_sdmc.cpp | 7 ++++--- 2 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 source/scope_exit.h diff --git a/source/scope_exit.h b/source/scope_exit.h new file mode 100644 index 0000000..1d3e593 --- /dev/null +++ b/source/scope_exit.h @@ -0,0 +1,37 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +namespace detail { + template + struct ScopeExitHelper { + explicit ScopeExitHelper(Func&& func) : func(std::move(func)) {} + ~ScopeExitHelper() { func(); } + + Func func; + }; + + template + ScopeExitHelper ScopeExit(Func&& func) { return ScopeExitHelper(std::move(func)); } +} + +/** + * This macro allows you to conveniently specify a block of code that will run on scope exit. Handy + * for doing ad-hoc clean-up tasks in a function with multiple returns. + * + * Example usage: + * \code + * const int saved_val = g_foo; + * g_foo = 55; + * SCOPE_EXIT({ g_foo = saved_val; }); + * + * if (Bar()) { + * return 0; + * } else { + * return 20; + * } + * \endcode + */ +#define SCOPE_EXIT(body) auto scope_exit_helper_##__LINE__ = detail::ScopeExit([&]() body) diff --git a/source/tests/fs/fs_sdmc.cpp b/source/tests/fs/fs_sdmc.cpp index 9de2159..dfcfccc 100644 --- a/source/tests/fs/fs_sdmc.cpp +++ b/source/tests/fs/fs_sdmc.cpp @@ -70,6 +70,10 @@ static bool TestFileWriteRead(FS_archive sdmcArchive) // Create file FSUSER_OpenFile(NULL, &fileHandle, sdmcArchive, filePath, FS_OPEN_CREATE | FS_OPEN_WRITE, 0); + SCOPE_EXIT({ // Close and delete file no matter what happens + FSFILE_Close(fileHandle); + FSUSER_DeleteFile(NULL, sdmcArchive, filePath); + }); // Write to file SoftAssert(FSFILE_Write(fileHandle, &bytesWritten, 0, stringWritten, strlen(stringWritten)+1, FS_WRITE_FLUSH) == 0); @@ -87,9 +91,6 @@ static bool TestFileWriteRead(FS_archive sdmcArchive) // Verify string contents SoftAssert(strcmp(stringRead.get(), stringWritten) == 0); - FSFILE_Close(fileHandle); - FSUSER_DeleteFile(NULL, sdmcArchive, filePath); - return true; } From dc4f0647690a214d943fe0d7191c2d2796829c38 Mon Sep 17 00:00:00 2001 From: archshift Date: Wed, 10 Dec 2014 18:30:28 -0800 Subject: [PATCH 2/2] Added tests for FSUSER_CreateFile, replaced FSUSER_OpenFile file creation where appropriate. --- source/tests/fs/fs_sdmc.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/source/tests/fs/fs_sdmc.cpp b/source/tests/fs/fs_sdmc.cpp index dfcfccc..fa00b86 100644 --- a/source/tests/fs/fs_sdmc.cpp +++ b/source/tests/fs/fs_sdmc.cpp @@ -2,6 +2,7 @@ #include #include <3ds.h> +#include "scope_exit.h" #include "tests/test.h" #include "tests/fs/fs_sdmc.h" @@ -10,10 +11,11 @@ namespace SDMC { static bool TestFileCreateDelete(FS_archive sdmcArchive) { - Handle fileHandle; + Handle fileHandle, fileHandle2; const static FS_path filePath = FS_makePath(PATH_CHAR, "/test_file_create_delete.txt"); + const static FS_path filePath2 = FS_makePath(PATH_CHAR, "/test_file_create_2.txt"); - // Create file (not interested in opening the handle) + // Create file with OpenFile (not interested in opening the handle) SoftAssert(FSUSER_OpenFile(NULL, &fileHandle, sdmcArchive, filePath, FS_OPEN_CREATE | FS_OPEN_WRITE, 0) == 0); FSFILE_Close(fileHandle); @@ -26,6 +28,19 @@ static bool TestFileCreateDelete(FS_archive sdmcArchive) // Should fail to make sure the file no longer exists SoftAssert(FSUSER_OpenFile(NULL, &fileHandle, sdmcArchive, filePath, FS_OPEN_READ, 0) != 0); FSFILE_Close(fileHandle); + + // Create file with CreateFile + SoftAssert(FSUSER_CreateFile(NULL, sdmcArchive, filePath2, 0) == 0); + SCOPE_EXIT({ + FSFILE_Close(fileHandle2); + FSUSER_DeleteFile(NULL, sdmcArchive, filePath2); + }); + + // Make sure the new file exists + SoftAssert(FSUSER_OpenFile(NULL, &fileHandle2, sdmcArchive, filePath2, FS_OPEN_READ, 0) == 0); + + // Try and create a file over an already-existing file (Should fail) + SoftAssert(FSUSER_CreateFile(NULL, sdmcArchive, filePath2, 0) != 0); return true; } @@ -36,9 +51,8 @@ static bool TestFileRename(FS_archive sdmcArchive) const static FS_path filePath = FS_makePath(PATH_CHAR, "/test_file_rename.txt"); const static FS_path newFilePath = FS_makePath(PATH_CHAR, "/test_file_rename_new.txt"); - // Create file (not interested in opening the handle) - FSUSER_OpenFile(NULL, &fileHandle, sdmcArchive, filePath, FS_OPEN_CREATE | FS_OPEN_WRITE, 0); - FSFILE_Close(fileHandle); + // Create file + FSUSER_CreateFile(NULL, sdmcArchive, filePath, 0); SoftAssert(FSUSER_RenameFile(NULL, sdmcArchive, filePath, sdmcArchive, newFilePath) == 0);