diff --git a/Code/Framework/AzFramework/Tests/Utils/Utils.cpp b/Code/Framework/AzFramework/Tests/Utils/Utils.cpp index cdc53a7e17..4f811a98ed 100644 --- a/Code/Framework/AzFramework/Tests/Utils/Utils.cpp +++ b/Code/Framework/AzFramework/Tests/Utils/Utils.cpp @@ -8,72 +8,100 @@ #include "Utils.h" #include +#include #include -UnitTest::ScopedTemporaryDirectory::ScopedTemporaryDirectory() +namespace UnitTest { - constexpr int MaxAttempts = 255; + void DeleteFolderRecursive(const AZ::IO::PathView& path) + { + auto callback = [&path](AZStd::string_view filename, bool isFile) -> bool + { + if (isFile) + { + auto filePath = AZ::IO::FixedMaxPath(path) / filename; + AZ::IO::SystemFile::Delete(filePath.c_str()); + } + else + { + if (filename != "." && filename != "..") + { + auto folderPath = AZ::IO::FixedMaxPath(path) / filename; + DeleteFolderRecursive(folderPath); + } + } + return true; + }; + auto searchPath = AZ::IO::FixedMaxPath(path) / "*"; + AZ::IO::SystemFile::FindFiles(searchPath.c_str(), callback); + AZ::IO::SystemFile::DeleteDir(AZ::IO::FixedMaxPathString(path.Native()).c_str()); + } + + + ScopedTemporaryDirectory::ScopedTemporaryDirectory() + { + constexpr int MaxAttempts = 255; #if !AZ_TRAIT_USE_POSIX_TEMP_FOLDER - const auto userTempFolder = std::filesystem::temp_directory_path(); + const auto userTempFolder = std::filesystem::temp_directory_path(); #else - AZ::IO::Path userTempFolder("/tmp"); + AZ::IO::Path userTempFolder("/tmp"); #endif - for (int i = 0; i < MaxAttempts; ++i) - { - auto randomFolder = AZ::Uuid::CreateRandom().ToString>(false, false); - AZ::IO::FixedMaxPath testPath; -#if !AZ_TRAIT_USE_POSIX_TEMP_FOLDER - auto path = userTempFolder / ("UnitTest-" + randomFolder).c_str(); - testPath = path.string().c_str(); -#else - userTempFolder /= ("UnitTest-" + randomFolder).c_str(); - testPath = userTempFolder.c_str(); -#endif - if (!AZ::IO::SystemFile::Exists(testPath.c_str())) + for (int i = 0; i < MaxAttempts; ++i) { -#if !AZ_TRAIT_USE_POSIX_TEMP_FOLDER - m_path = path; - m_tempDirectory = m_path.string().c_str(); + auto randomFolder = AZ::Uuid::CreateRandom().ToString>(false, false); + AZ::IO::FixedMaxPath testPath; +#if !AZ_TRAIT_USE_POSIX_TEMP_FOLDER + auto path = userTempFolder / ("UnitTest-" + randomFolder).c_str(); + testPath = path.string().c_str(); #else - m_tempDirectory = testPath; + userTempFolder /= ("UnitTest-" + randomFolder).c_str(); + testPath = userTempFolder.c_str(); #endif - m_directoryExists = AZ::IO::SystemFile::CreateDir(m_tempDirectory.c_str()); - break; + if (!AZ::IO::SystemFile::Exists(testPath.c_str())) + { +#if !AZ_TRAIT_USE_POSIX_TEMP_FOLDER + m_path = path; + m_tempDirectory = m_path.string().c_str(); +#else + m_tempDirectory = testPath; +#endif + m_directoryExists = AZ::IO::SystemFile::CreateDir(m_tempDirectory.c_str()); + break; + } + } + + AZ_Error("ScopedTemporaryDirectory", !m_tempDirectory.empty(), "Failed to create unique temporary directory after attempting %d random folder names", MaxAttempts); + } + + ScopedTemporaryDirectory::~ScopedTemporaryDirectory() + { + if (m_directoryExists) + { + DeleteFolderRecursive(m_tempDirectory); } } - AZ_Error("ScopedTemporaryDirectory", !m_tempDirectory.empty(), "Failed to create unique temporary directory after attempting %d random folder names", MaxAttempts); -} - -UnitTest::ScopedTemporaryDirectory::~ScopedTemporaryDirectory() -{ - if (m_directoryExists) + bool ScopedTemporaryDirectory::IsValid() const { - AZ::IO::SystemFile::DeleteDir(m_tempDirectory.c_str()); + return m_directoryExists; } -} -bool UnitTest::ScopedTemporaryDirectory::IsValid() const -{ - return m_directoryExists; -} - -const char* UnitTest::ScopedTemporaryDirectory::GetDirectory() const -{ - return m_tempDirectory.c_str(); -} + const char* ScopedTemporaryDirectory::GetDirectory() const + { + return m_tempDirectory.c_str(); + } #if !AZ_TRAIT_USE_POSIX_TEMP_FOLDER -const std::filesystem::path& UnitTest::ScopedTemporaryDirectory::GetPath() const -{ - return m_path; -} - -std::filesystem::path UnitTest::ScopedTemporaryDirectory::operator/(const std::filesystem::path& rhs) const -{ - return m_path / rhs; -} + const std::filesystem::path& ScopedTemporaryDirectory::GetPath() const + { + return m_path; + } + std::filesystem::path ScopedTemporaryDirectory::operator/(const std::filesystem::path& rhs) const + { + return m_path / rhs; + } #endif // !AZ_TRAIT_USE_POSIX_TEMP_FOLDER +} diff --git a/Code/Framework/AzFramework/Tests/Utils/Utils.h b/Code/Framework/AzFramework/Tests/Utils/Utils.h index 83a3a9dd42..b5fb5e8387 100644 --- a/Code/Framework/AzFramework/Tests/Utils/Utils.h +++ b/Code/Framework/AzFramework/Tests/Utils/Utils.h @@ -18,6 +18,9 @@ namespace UnitTest { + //! Deletes a folder hierarchy from the supplied path + void DeleteFolderRecursive(const AZ::IO::PathView& path); + // Creates a randomly named folder inside the user's temporary directory. // The folder and all contents will be destroyed when the object goes out of scope struct ScopedTemporaryDirectory diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.cpp index 3f2cb24d69..5ffbe1b4f3 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.cpp @@ -352,8 +352,20 @@ namespace UnitTest AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult( entityId, &AzToolsFramework::EditorEntityContextRequestBus::Events::CreateNewEditorEntity, name); + if (!entityId.IsValid()) + { + AZ_Error("CreateDefaultEditorEntity", false, "Failed to create editor entity '%s'", name); + return AZ::EntityId(); + } + AZ::Entity* entity = GetEntityById(entityId); + if (!entity) + { + AZ_Error("CreateDefaultEditorEntity", false, "Invalid entity obtained from Id %s", entityId.ToString().c_str()); + return AZ::EntityId(); + } + entity->Deactivate(); // add required components for the Editor entity diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/ToolsTestApplication.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/ToolsTestApplication.cpp index be9b332982..3ef1210233 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/ToolsTestApplication.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/ToolsTestApplication.cpp @@ -11,7 +11,12 @@ namespace UnitTest { ToolsTestApplication::ToolsTestApplication(AZStd::string applicationName) - : ToolsApplication() + :ToolsTestApplication(AZStd::move(applicationName), 0, nullptr) + { + } + + ToolsTestApplication::ToolsTestApplication(AZStd::string applicationName, int argc, char** argv) + : AzToolsFramework::ToolsApplication(&argc, &argv) , m_applicationName(AZStd::move(applicationName)) { } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/ToolsTestApplication.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/ToolsTestApplication.h index 22de71b2d8..2bf920cc4a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/ToolsTestApplication.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UnitTest/ToolsTestApplication.h @@ -18,6 +18,7 @@ namespace UnitTest { public: explicit ToolsTestApplication(AZStd::string applicationName); + ToolsTestApplication(AZStd::string applicationName, int argc, char** argv); void SetSettingsRegistrySpecializations(AZ::SettingsRegistryInterface::Specializations& specializations) override; protected: diff --git a/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp b/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp index 4aa9dbe2bb..5ad68a2c1c 100644 --- a/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp +++ b/Code/Framework/AzToolsFramework/Tests/AssetFileInfoListComparison.cpp @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -49,19 +50,22 @@ namespace UnitTest void SetUp() override { using namespace AZ::Data; - m_application = new ToolsTestApplication("AssetFileInfoListComparisonTest"); + constexpr size_t MaxCommandArgsCount = 128; + using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString; + using ArgumentContainer = AZStd::fixed_vector; + // The first command line argument is assumed to be the executable name so add a blank entry for it + ArgumentContainer argContainer{ {} }; + + // Append Command Line override for the Project Cache Path + auto projectCachePathOverride = FixedValueString::format(R"(--project-cache-path="%s")", m_tempDir.GetDirectory()); + auto projectPathOverride = FixedValueString{ R"(--project-path=AutomatedTesting)" }; + argContainer.push_back(projectCachePathOverride.data()); + argContainer.push_back(projectPathOverride.data()); + m_application = new ToolsTestApplication("AssetFileInfoListComparisonTest", aznumeric_caster(argContainer.size()), argContainer.data()); AzToolsFramework::AssetSeedManager assetSeedManager; AzFramework::AssetRegistry assetRegistry; - m_localFileIO = aznew AZ::IO::LocalFileIO(); - - m_priorFileIO = AZ::IO::FileIOBase::GetInstance(); - AZ::IO::FileIOBase::SetInstance(nullptr); - AZ::IO::FileIOBase::SetInstance(m_localFileIO); - - AZ::IO::FileIOBase::GetInstance()->SetAlias("@assets@", m_tempDir.GetDirectory()); - - AZStd::string assetRoot = AzToolsFramework::PlatformAddressedAssetCatalog::GetAssetRootForPlatform(AzFramework::PlatformId::PC); + const AZStd::string assetRoot = AzToolsFramework::PlatformAddressedAssetCatalog::GetAssetRootForPlatform(AzFramework::PlatformId::PC); for (int idx = 0; idx < TotalAssets; idx++) { @@ -75,7 +79,8 @@ namespace UnitTest AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[idx].Open(m_assetsPath[idx].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { - m_fileStreams[idx].Write(info.m_relativePath.size(), info.m_relativePath.data()); + AZ::IO::SizeType bytesWritten = m_fileStreams[idx].Write(info.m_relativePath.size(), info.m_relativePath.data()); + EXPECT_EQ(bytesWritten, info.m_relativePath.size()); AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } else @@ -92,6 +97,7 @@ namespace UnitTest assetRegistry.RegisterAssetDependency(m_assets[3], AZ::Data::ProductDependency(m_assets[4], 0)); m_application->Start(AzFramework::Application::Descriptor()); + // Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is // shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash // in the unit tests. @@ -109,14 +115,16 @@ namespace UnitTest AZStd::string pcCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::PC); - ASSERT_TRUE(AzFramework::AssetCatalog::SaveCatalog(pcCatalogFile.c_str(), &assetRegistry)) << "Unable to save the asset catalog file.\n"; + bool catalogSaved = AzFramework::AssetCatalog::SaveCatalog(pcCatalogFile.c_str(), &assetRegistry); + EXPECT_TRUE(catalogSaved) << "Unable to save the asset catalog file.\n"; m_pcCatalog = new AzToolsFramework::PlatformAddressedAssetCatalog(AzFramework::PlatformId::PC); assetSeedManager.AddSeedAsset(m_assets[0], AzFramework::PlatformFlags::Platform_PC); assetSeedManager.AddSeedAsset(m_assets[1], AzFramework::PlatformFlags::Platform_PC); - assetSeedManager.SaveAssetFileInfo(TempFiles[FileIndex::FirstAssetFileInfoList], AzFramework::PlatformFlags::Platform_PC, {}); + bool firstAssetFileInfoListSaved = assetSeedManager.SaveAssetFileInfo(TempFiles[FileIndex::FirstAssetFileInfoList], AzFramework::PlatformFlags::Platform_PC, {}); + EXPECT_TRUE(firstAssetFileInfoListSaved); // Modify contents of asset2 int fileIndex = 2; @@ -124,7 +132,8 @@ namespace UnitTest if (m_fileStreams[fileIndex].Open(m_assetsPath[fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { AZStd::string fileContent = AZStd::string::format("new Asset%d.txt", fileIndex);// changing file content - m_fileStreams[fileIndex].Write(fileContent.size(), fileContent.c_str()); + AZ::IO::SizeType bytesWritten = m_fileStreams[fileIndex].Write(fileContent.size(), fileContent.c_str()); + EXPECT_EQ(bytesWritten, fileContent.size()); AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } else @@ -138,7 +147,8 @@ namespace UnitTest if (m_fileStreams[fileIndex].Open(m_assetsPath[fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { AZStd::string fileContent = AZStd::string::format("new Asset%d.txt", fileIndex);// changing file content - m_fileStreams[fileIndex].Write(fileContent.size(), fileContent.c_str()); + AZ::IO::SizeType bytesWritten = m_fileStreams[fileIndex].Write(fileContent.size(), fileContent.c_str()); + EXPECT_EQ(bytesWritten, fileContent.size()); AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } else @@ -149,7 +159,8 @@ namespace UnitTest assetSeedManager.RemoveSeedAsset(m_assets[0], AzFramework::PlatformFlags::Platform_PC); assetSeedManager.AddSeedAsset(m_assets[5], AzFramework::PlatformFlags::Platform_PC); - assetSeedManager.SaveAssetFileInfo(TempFiles[FileIndex::SecondAssetFileInfoList], AzFramework::PlatformFlags::Platform_PC, {}); + bool secondAssetFileInfoListSaved = assetSeedManager.SaveAssetFileInfo(TempFiles[FileIndex::SecondAssetFileInfoList], AzFramework::PlatformFlags::Platform_PC, {}); + EXPECT_TRUE(secondAssetFileInfoListSaved); } void TearDown() override @@ -162,7 +173,8 @@ namespace UnitTest if (fileIO->Exists(TempFiles[idx])) { AZ_TEST_START_TRACE_SUPPRESSION; - fileIO->Remove(TempFiles[idx]); + AZ::IO::Result result = fileIO->Remove(TempFiles[idx]); + EXPECT_EQ(result.GetResultCode(), AZ::IO::ResultCode::Success); AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder } } @@ -175,7 +187,8 @@ namespace UnitTest if (fileIO->Exists(m_assetsPath[idx].c_str())) { AZ_TEST_START_TRACE_SUPPRESSION; - fileIO->Remove(m_assetsPath[idx].c_str()); + AZ::IO::Result result = fileIO->Remove(m_assetsPath[idx].c_str()); + EXPECT_EQ(result.GetResultCode(), AZ::IO::ResultCode::Success); AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder } } @@ -184,15 +197,12 @@ namespace UnitTest if (fileIO->Exists(pcCatalogFile.c_str())) { AZ_TEST_START_TRACE_SUPPRESSION; - fileIO->Remove(pcCatalogFile.c_str()); + AZ::IO::Result result = fileIO->Remove(pcCatalogFile.c_str()); + EXPECT_EQ(result.GetResultCode(), AZ::IO::ResultCode::Success); AZ_TEST_STOP_TRACE_SUPPRESSION(1); // deleting from asset cache folder } delete m_pcCatalog; - delete m_localFileIO; - m_localFileIO = nullptr; - AZ::IO::FileIOBase::SetInstance(nullptr); - AZ::IO::FileIOBase::SetInstance(m_priorFileIO); m_application->Stop(); delete m_application; @@ -742,11 +752,9 @@ namespace UnitTest } - ToolsTestApplication* m_application; + ToolsTestApplication* m_application = nullptr; UnitTest::ScopedTemporaryDirectory m_tempDir; - AzToolsFramework::PlatformAddressedAssetCatalog* m_pcCatalog; - AZ::IO::FileIOBase* m_priorFileIO = nullptr; - AZ::IO::FileIOBase* m_localFileIO = nullptr; + AzToolsFramework::PlatformAddressedAssetCatalog* m_pcCatalog = nullptr; AZ::IO::FileIOStream m_fileStreams[TotalAssets]; AZ::Data::AssetId m_assets[TotalAssets]; AZStd::string m_assetsPath[TotalAssets]; diff --git a/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp b/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp index 0b5c37ccc2..4083608370 100644 --- a/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp +++ b/Code/Framework/AzToolsFramework/Tests/AssetSeedManager.cpp @@ -23,11 +23,12 @@ #include #include #include +#include + namespace // anonymous { static const int s_totalAssets = 12; static const int s_totalTestPlatforms = 2; - const char* s_catalogFile = "AssetCatalog.xml"; AZ::Data::AssetId assets[s_totalAssets]; const char TestSliceAssetPath[] = "test.slice"; @@ -55,18 +56,30 @@ namespace UnitTest void SetUp() override { using namespace AZ::Data; - m_application = new ToolsTestApplication("AssetSeedManagerTest"); + constexpr size_t MaxCommandArgsCount = 128; + using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString; + using ArgumentContainer = AZStd::fixed_vector; + // The first command line argument is assumed to be the executable name so add a blank entry for it + ArgumentContainer argContainer{ {} }; + + // Append Command Line override for the Project Cache Path + AZ::IO::Path cacheProjectRootFolder{ m_tempDir.GetDirectory() }; + auto projectCachePathOverride = FixedValueString::format(R"(--project-cache-path="%s")", cacheProjectRootFolder.c_str()); + auto projectPathOverride = FixedValueString{ R"(--project-path=AutomatedTesting)" }; + argContainer.push_back(projectCachePathOverride.data()); + argContainer.push_back(projectPathOverride.data()); + m_application = new ToolsTestApplication("AssetSeedManagerTest", aznumeric_caster(argContainer.size()), argContainer.data()); m_assetSeedManager = new AzToolsFramework::AssetSeedManager(); m_assetRegistry = new AzFramework::AssetRegistry(); - AZ::SettingsRegistryInterface* registry = AZ::SettingsRegistry::Get(); - auto projectPathKey = - AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path"; - registry->Set(projectPathKey, "AutomatedTesting"); - AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry); - m_application->Start(AzFramework::Application::Descriptor()); + // By default @assets@ is setup to include the platform at the end. But this test is going to + // loop over platforms and it will be included as part of the relative path of the file. + // So the asset folder for these tests have to point to the cache project root folder, which + // doesn't include the platform. + AZ::IO::FileIOBase::GetInstance()->SetAlias("@assets@", cacheProjectRootFolder.c_str()); + for (int idx = 0; idx < s_totalAssets; idx++) { assets[idx] = AssetId(AZ::Uuid::CreateRandom(), 0); @@ -83,17 +96,18 @@ namespace UnitTest int platformCount = 0; for(auto thisPlatform : m_testPlatforms) { - AZStd::string assetRoot = AzToolsFramework::PlatformAddressedAssetCatalog::GetAssetRootForPlatform(thisPlatform); + AZ::IO::Path assetRoot = AzToolsFramework::PlatformAddressedAssetCatalog::GetAssetRootForPlatform(thisPlatform); for (int idx = 0; idx < s_totalAssets; idx++) { - AzFramework::StringFunc::Path::Join(assetRoot.c_str(), m_assetsPath[idx].c_str(), m_assetsPathFull[platformCount][idx]); + m_assetsPathFull[platformCount][idx] = (assetRoot / m_assetsPath[idx]).Native(); AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[platformCount][idx].Open(m_assetsPathFull[platformCount][idx].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { - m_fileStreams[platformCount][idx].Write(m_assetsPath[idx].size(), m_assetsPath[idx].data()); + AZ::IO::SizeType bytesWritten = m_fileStreams[platformCount][idx].Write(m_assetsPath[idx].size(), m_assetsPath[idx].data()); + EXPECT_EQ(bytesWritten, m_assetsPath[idx].size()); m_fileStreams[platformCount][idx].Close(); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, only invalid for PC, not invalid in Jenkins + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } else { @@ -117,7 +131,7 @@ namespace UnitTest AZ_TEST_START_TRACE_SUPPRESSION; AZ::IO::FileIOStream dynamicSliceFileIOStream(TestDynamicSliceAssetPath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder AZ::Data::AssetInfo sliceAssetInfo; sliceAssetInfo.m_relativePath = TestSliceAssetPath; @@ -131,7 +145,7 @@ namespace UnitTest AZ_TEST_START_TRACE_SUPPRESSION; AZ::IO::FileIOStream sliceFileIOStream(TestSliceAssetPath, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder // asset0 -> asset1 -> asset2 -> asset4 // --> asset3 @@ -197,58 +211,6 @@ namespace UnitTest void TearDown() override { - AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); - - if (fileIO->Exists(s_catalogFile)) - { - AZ_TEST_START_TRACE_SUPPRESSION; - fileIO->Remove(s_catalogFile); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins - } - - for (size_t platformCount = 0; platformCount < s_totalTestPlatforms; ++platformCount) - { - // Deleting all the temporary files - for (int idx = 0; idx < s_totalAssets; idx++) - { - // we need to close the handle before we try to remove the file - if (fileIO->Exists(m_assetsPathFull[platformCount][idx].c_str())) - { - AZ_TEST_START_TRACE_SUPPRESSION; - fileIO->Remove(m_assetsPathFull[platformCount][idx].c_str()); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins - } - } - } - - if (fileIO->Exists(TestSliceAssetPath)) - { - AZ_TEST_START_TRACE_SUPPRESSION; - fileIO->Remove(TestSliceAssetPath); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins - } - - if (fileIO->Exists(TestDynamicSliceAssetPath)) - { - AZ_TEST_START_TRACE_SUPPRESSION; - fileIO->Remove(TestDynamicSliceAssetPath); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins - } - - auto pcCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::PC); - auto androidCatalogFile = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::ANDROID_ID); - if (fileIO->Exists(pcCatalogFile.c_str())) - { - AZ_TEST_START_TRACE_SUPPRESSION; - fileIO->Remove(pcCatalogFile.c_str()); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // deleting from asset cache folder, not invalid in Jenkins - } - - if (fileIO->Exists(androidCatalogFile.c_str())) - { - fileIO->Remove(androidCatalogFile.c_str()); - } - delete m_assetSeedManager; delete m_assetRegistry; delete m_pcCatalog; @@ -284,7 +246,7 @@ namespace UnitTest // Attempt to save to the same file. Should not be allowed. AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(m_assetSeedManager->Save(filePath)); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // One error expected // Clean up the test environment AZ::IO::SystemFile::SetWritable(filePath.c_str(), true); @@ -310,7 +272,7 @@ namespace UnitTest // Attempt to save to the same file. Should not be allowed. AZ_TEST_START_TRACE_SUPPRESSION; EXPECT_FALSE(m_assetSeedManager->SaveAssetFileInfo(filePath, AzFramework::PlatformFlags::Platform_PC, {})); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // One error expected // Clean up the test environment AZ::IO::SystemFile::SetWritable(filePath.c_str(), true); @@ -379,7 +341,7 @@ namespace UnitTest // Step we are testing AZ_TEST_START_TRACE_SUPPRESSION; m_assetSeedManager->AddPlatformToAllSeeds(AzFramework::PlatformId::ANDROID_ID); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // One error expected // Verification AzFramework::PlatformFlags expectedPlatformFlags = AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_ANDROID; @@ -649,9 +611,10 @@ namespace UnitTest if (m_fileStreams[0][fileIndex].Open(m_assetsPathFull[0][fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex); - m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str()); + AZ::IO::SizeType bytesWritten = m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str()); + EXPECT_EQ(bytesWritten, fileContent.size()); m_fileStreams[0][fileIndex].Close(); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } AzToolsFramework::AssetFileInfoList assetList2 = m_assetSeedManager->GetDependencyList(AzFramework::PlatformId::PC); @@ -682,9 +645,10 @@ namespace UnitTest if (m_fileStreams[0][fileIndex].Open(m_assetsPathFull[0][fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex + 1);// changing file content - m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str()); + AZ::IO::SizeType bytesWritten = m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str()); + EXPECT_EQ(bytesWritten, fileContent.size()); m_fileStreams[0][fileIndex].Close(); - AZ_TEST_STOP_TRACE_SUPPRESSION_NO_COUNT; // writing to asset cache folder, not invalid in Jenkins + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } AzToolsFramework::AssetFileInfoList assetList2 = m_assetSeedManager->GetDependencyList(AzFramework::PlatformId::PC); @@ -790,16 +754,17 @@ namespace UnitTest } - AzToolsFramework::AssetSeedManager* m_assetSeedManager; - AzFramework::AssetRegistry* m_assetRegistry; - ToolsTestApplication* m_application; - AzToolsFramework::PlatformAddressedAssetCatalog* m_pcCatalog; - AzToolsFramework::PlatformAddressedAssetCatalog* m_androidCatalog; + AzToolsFramework::AssetSeedManager* m_assetSeedManager = nullptr; + AzFramework::AssetRegistry* m_assetRegistry = nullptr; + ToolsTestApplication* m_application = nullptr; + AzToolsFramework::PlatformAddressedAssetCatalog* m_pcCatalog = nullptr; + AzToolsFramework::PlatformAddressedAssetCatalog* m_androidCatalog = nullptr; AZ::IO::FileIOStream m_fileStreams[s_totalTestPlatforms][s_totalAssets]; AzFramework::PlatformId m_testPlatforms[s_totalTestPlatforms]; AZStd::string m_assetsPath[s_totalAssets]; AZStd::string m_assetsPathFull[s_totalTestPlatforms][s_totalAssets]; AZ::Data::AssetId m_testDynamicSliceAssetId; + UnitTest::ScopedTemporaryDirectory m_tempDir; }; TEST_F(AssetSeedManagerTest, AssetSeedManager_SaveSeedListFile_FileIsReadOnly) diff --git a/Code/Framework/AzToolsFramework/Tests/InstanceDataHierarchy.cpp b/Code/Framework/AzToolsFramework/Tests/InstanceDataHierarchy.cpp index 1b11479bff..806a3bbab2 100644 --- a/Code/Framework/AzToolsFramework/Tests/InstanceDataHierarchy.cpp +++ b/Code/Framework/AzToolsFramework/Tests/InstanceDataHierarchy.cpp @@ -1285,7 +1285,7 @@ namespace UnitTest Crc32 uiHandler = 0; EXPECT_EQ(it->ReadAttribute(AZ::Edit::UIHandlers::Handler, uiHandler), true); EXPECT_EQ(uiHandler, AZ_CRC("TestHandler")); - EXPECT_EQ(it->GetElementMetadata()->m_name, "UIElement"); + EXPECT_STREQ(it->GetElementMetadata()->m_name, "UIElement"); EXPECT_EQ(it->GetElementMetadata()->m_nameCrc, AZ_CRC("UIElement")); uiHandler = 0; @@ -1293,7 +1293,7 @@ namespace UnitTest ++it; EXPECT_EQ(it->ReadAttribute(AZ::Edit::UIHandlers::Handler, uiHandler), true); EXPECT_EQ(uiHandler, AZ_CRC("TestHandler2")); - EXPECT_EQ(it->GetElementMetadata()->m_name, "UIElement2"); + EXPECT_STREQ(it->GetElementMetadata()->m_name, "UIElement2"); EXPECT_EQ(it->GetElementMetadata()->m_nameCrc, AZ_CRC("UIElement2")); } }; @@ -1356,21 +1356,21 @@ namespace UnitTest auto it = children.begin(); - EXPECT_EQ(it->GetElementMetadata()->m_name, "aggregatedDataElement"); + EXPECT_STREQ(it->GetElementMetadata()->m_name, "aggregatedDataElement"); ++it; if (i == 0) { - EXPECT_EQ(it->GetElementMetadata()->m_name, "notAggregatedDataElement"); + EXPECT_STREQ(it->GetElementMetadata()->m_name, "notAggregatedDataElement"); ++it; } - EXPECT_EQ(it->GetElementMetadata()->m_name, "aggregatedUIElement"); + EXPECT_STREQ(it->GetElementMetadata()->m_name, "aggregatedUIElement"); ++it; if (i == 0) { - EXPECT_EQ(it->GetElementMetadata()->m_name, "notAggregatedUIElement"); + EXPECT_STREQ(it->GetElementMetadata()->m_name, "notAggregatedUIElement"); ++it; } } @@ -1505,11 +1505,11 @@ namespace UnitTest AZStd::string childName(child.GetElementMetadata()->m_name); if (childName.compare("GroupFloat") == 0) { - EXPECT_EQ(child.GetGroupElementMetadata()->m_description, "Normal Group"); + EXPECT_STREQ(child.GetGroupElementMetadata()->m_description, "Normal Group"); } if (childName.compare("ToggleGroupInt") == 0) { - EXPECT_EQ(child.GetGroupElementMetadata()->m_description, "Group Toggle"); + EXPECT_STREQ(child.GetGroupElementMetadata()->m_description, "Group Toggle"); } if ((childName.compare("SubDataNormal") == 0) || (childName.compare("SubDataToggle") == 0)) { @@ -1518,11 +1518,11 @@ namespace UnitTest childName = subChild.GetElementMetadata()->m_name; if (childName.compare("SubInt") == 0) { - EXPECT_EQ(subChild.GetGroupElementMetadata()->m_description, "Normal SubGroup"); + EXPECT_STREQ(subChild.GetGroupElementMetadata()->m_description, "Normal SubGroup"); } if (childName.compare("SubFloat") == 0) { - EXPECT_EQ(subChild.GetGroupElementMetadata()->m_description, "SubGroup Toggle"); + EXPECT_STREQ(subChild.GetGroupElementMetadata()->m_description, "SubGroup Toggle"); } } } @@ -1552,7 +1552,7 @@ namespace UnitTest AZStd::string childName(child.GetElementMetadata()->m_name); if (childName.compare(paramName) == 0) { - EXPECT_EQ(child.GetParent()->GetClassMetadata()->m_name, "GroupTestComponent"); + EXPECT_STREQ(child.GetParent()->GetClassMetadata()->m_name, "GroupTestComponent"); } if ((childName.compare("SubDataNormal") == 0) || (childName.compare("SubDataToggle") == 0)) { @@ -1561,7 +1561,7 @@ namespace UnitTest childName = subChild.GetElementMetadata()->m_name; if (childName.compare(paramName) == 0) { - EXPECT_EQ(subChild.GetParent()->GetClassMetadata()->m_name, "SubData"); + EXPECT_STREQ(subChild.GetParent()->GetClassMetadata()->m_name, "SubData"); } } } diff --git a/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp b/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp index 00a7b1973c..67d40be376 100644 --- a/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/PlatformAddressedAssetCatalogTests.cpp @@ -19,9 +19,8 @@ #include #include #include -#include -#include #include +#include namespace { @@ -35,25 +34,22 @@ namespace UnitTest { public: - AZStd::string GetTempFolder() - { - QTemporaryDir dir; - QDir tempPath(dir.path()); - return tempPath.absolutePath().toUtf8().data(); - } - void SetUp() override { using namespace AZ::Data; - m_application = new ToolsTestApplication("AddressedAssetCatalogManager"); // Shorter name because Setting Registry - // specialization are 32 characters max. + constexpr size_t MaxCommandArgsCount = 128; + using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString; + using ArgumentContainer = AZStd::fixed_vector; + // The first command line argument is assumed to be the executable name so add a blank entry for it + ArgumentContainer argContainer{ {} }; - AZ::SettingsRegistryInterface* registry = AZ::SettingsRegistry::Get(); - - auto projectPathKey = - AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path"; - registry->Set(projectPathKey, "AutomatedTesting"); - AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry); + // Append Command Line override for the Project Cache Path + AZ::IO::Path cacheProjectRootFolder{ m_tempDir.GetDirectory() }; + auto projectCachePathOverride = FixedValueString::format(R"(--project-cache-path="%s")", cacheProjectRootFolder.c_str()); + auto projectPathOverride = FixedValueString{ R"(--project-path=AutomatedTesting)" }; + argContainer.push_back(projectCachePathOverride.data()); + argContainer.push_back(projectPathOverride.data()); + m_application = new ToolsTestApplication("AddressedAssetCatalogManager", aznumeric_caster(argContainer.size()), argContainer.data()); m_application->Start(AzFramework::Application::Descriptor()); // Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is @@ -61,33 +57,36 @@ namespace UnitTest // in the unit tests. AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize); - AZStd::string cacheFolder; - AzFramework::StringFunc::Path::Join(GetTempFolder().c_str(), "testplatform", cacheFolder); - AzFramework::StringFunc::Path::Join(cacheFolder.c_str(), "testproject", cacheFolder); - - AZ::IO::FileIOBase::GetInstance()->SetAlias("@assets@", cacheFolder.c_str()); + // By default @assets@ is setup to include the platform at the end. But this test is going to + // loop over all platforms and it will be included as part of the relative path of the file. + // So the asset folder for these tests have to point to the cache project root folder, which + // doesn't include the platform. + AZ::IO::FileIOBase::GetInstance()->SetAlias("@assets@", cacheProjectRootFolder.c_str()); for (int platformNum = AzFramework::PlatformId::PC; platformNum < AzFramework::PlatformId::NumPlatformIds; ++platformNum) { - AZStd::string platformName{ AzFramework::PlatformHelper::GetPlatformName(static_cast(platformNum)) }; + const AZStd::string platformName{ AzFramework::PlatformHelper::GetPlatformName(static_cast(platformNum)) }; if (!platformName.length()) { // Do not test disabled platforms continue; } + AZStd::unique_ptr assetRegistry = AZStd::make_unique(); for (int idx = 0; idx < s_totalAssets; idx++) { m_assets[platformNum][idx] = AssetId(AZ::Uuid::CreateRandom(), 0); AZ::Data::AssetInfo info; - info.m_relativePath = AZStd::string::format("%s%sAsset%d_%s.txt", cacheFolder.c_str(), AZ_CORRECT_FILESYSTEM_SEPARATOR_STRING, idx, platformName.c_str()); + info.m_relativePath = AZStd::move((AZ::IO::Path(platformName) / AZStd::string::format("Asset%d.txt", idx)).Native()); info.m_assetId = m_assets[platformNum][idx]; assetRegistry->RegisterAsset(m_assets[platformNum][idx], info); - m_assetsPath[platformNum][idx] = info.m_relativePath; + m_assetsPath[platformNum][idx] = AZStd::move((cacheProjectRootFolder / info.m_relativePath).Native()); AZ_TEST_START_TRACE_SUPPRESSION; if (m_fileStreams[platformNum][idx].Open(m_assetsPath[platformNum][idx].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath)) { - m_fileStreams[platformNum][idx].Write(info.m_relativePath.size(), info.m_relativePath.data()); + AZ::IO::SizeType bytesWritten = m_fileStreams[platformNum][idx].Write(info.m_relativePath.size(), info.m_relativePath.data()); + EXPECT_EQ(bytesWritten, info.m_relativePath.size()); + m_fileStreams[platformNum][idx].Close(); AZ_TEST_STOP_TRACE_SUPPRESSION(1); // writing to asset cache folder } else @@ -112,48 +111,15 @@ namespace UnitTest void TearDown() override { - AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); - for (int platformNum = AzFramework::PlatformId::PC; platformNum < AzFramework::PlatformId::NumPlatformIds; ++platformNum) - { - AZStd::string platformName{ AzFramework::PlatformHelper::GetPlatformName(static_cast(platformNum)) }; - if (!platformName.length()) - { - // Do not test disabled platforms - continue; - } - AZStd::string catalogPath = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(static_cast(platformNum)); - - if (fileIO->Exists(catalogPath.c_str())) - { - fileIO->Remove(catalogPath.c_str()); - } - // Deleting all the temporary files - for (int idx = 0; idx < s_totalAssets; idx++) - { - // we need to close the handle before we try to remove the file - m_fileStreams[platformNum][idx].Close(); - if (fileIO->Exists(m_assetsPath[platformNum][idx].c_str())) - { - AZ_TEST_START_TRACE_SUPPRESSION; - fileIO->Remove(m_assetsPath[platformNum][idx].c_str()); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); // removing from asset cache folder - } - } - } - - delete m_localFileIO; - m_localFileIO = nullptr; - AZ::IO::FileIOBase::SetInstance(m_priorFileIO); delete m_PlatformAddressedAssetCatalogManager; m_application->Stop(); delete m_application; } - AzToolsFramework::PlatformAddressedAssetCatalogManager* m_PlatformAddressedAssetCatalogManager; - ToolsTestApplication* m_application; - AZ::IO::FileIOBase* m_priorFileIO = nullptr; - AZ::IO::FileIOBase* m_localFileIO = nullptr; + AzToolsFramework::PlatformAddressedAssetCatalogManager* m_PlatformAddressedAssetCatalogManager = nullptr; + ToolsTestApplication* m_application = nullptr; + UnitTest::ScopedTemporaryDirectory m_tempDir; AZ::IO::FileIOStream m_fileStreams[AzFramework::PlatformId::NumPlatformIds][s_totalAssets]; AZ::Data::AssetId m_assets[AzFramework::PlatformId::NumPlatformIds][s_totalAssets]; @@ -183,12 +149,14 @@ namespace UnitTest TEST_F(PlatformAddressedAssetCatalogManagerTest, PlatformAddressedAssetCatalogManager_CatalogExistsChecks_Success) { - EXPECT_EQ(AzToolsFramework::PlatformAddressedAssetCatalog::CatalogExists(AzFramework::PlatformId::ANDROID_ID), true); AZStd::string androidCatalogPath = AzToolsFramework::PlatformAddressedAssetCatalog::GetCatalogRegistryPathForPlatform(AzFramework::PlatformId::ANDROID_ID); if (AZ::IO::FileIOBase::GetInstance()->Exists(androidCatalogPath.c_str())) { - AZ::IO::FileIOBase::GetInstance()->Remove(androidCatalogPath.c_str()); + AZ_TEST_START_TRACE_SUPPRESSION; + AZ::IO::Result result = AZ::IO::FileIOBase::GetInstance()->Remove(androidCatalogPath.c_str()); + EXPECT_EQ(result.GetResultCode(), AZ::IO::ResultCode::Success); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // removing from asset cache folder } EXPECT_EQ(AzToolsFramework::PlatformAddressedAssetCatalog::CatalogExists(AzFramework::PlatformId::ANDROID_ID), false); } @@ -218,31 +186,32 @@ namespace UnitTest : public AllocatorsFixture { public: - AZStd::string GetTempFolder() - { - QTemporaryDir dir; - QDir tempPath(dir.path()); - return tempPath.absolutePath().toUtf8().data(); - } - void SetUp() override { - AZ::IO::FileIOBase::SetInstance(nullptr); // The API requires the old instance to be destroyed first - AZ::IO::FileIOBase::SetInstance(new AZ::IO::LocalFileIO()); + constexpr size_t MaxCommandArgsCount = 128; + using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString; + using ArgumentContainer = AZStd::fixed_vector; + // The first command line argument is assumed to be the executable name so add a blank entry for it + ArgumentContainer argContainer{ {} }; - AZStd::string cacheFolder; - AzFramework::StringFunc::Path::Join(GetTempFolder().c_str(), "testplatform", cacheFolder); - AzFramework::StringFunc::Path::Join(cacheFolder.c_str(), "testproject", cacheFolder); - - AZ::IO::FileIOBase::GetInstance()->SetAlias("@assets@", cacheFolder.c_str()); + // Append Command Line override for the Project Cache Path + AZ::IO::Path cacheProjectRootFolder{ m_tempDir.GetDirectory() }; + auto projectCachePathOverride = FixedValueString::format(R"(--project-cache-path="%s")", cacheProjectRootFolder.c_str()); + auto projectPathOverride = FixedValueString{ R"(--project-path=AutomatedTesting)" }; + argContainer.push_back(projectCachePathOverride.data()); + argContainer.push_back(projectPathOverride.data()); + m_application = new ToolsTestApplication("MessageTest", aznumeric_caster(argContainer.size()), argContainer.data()); m_platformAddressedAssetCatalogManager = AZStd::make_unique(AzFramework::PlatformId::Invalid); } void TearDown() override { m_platformAddressedAssetCatalogManager.reset(); + delete m_application; } + ToolsTestApplication* m_application = nullptr; AZStd::unique_ptr m_platformAddressedAssetCatalogManager; + UnitTest::ScopedTemporaryDirectory m_tempDir; }; TEST_F(MessageTest, PlatformAddressedAssetCatalogManagerMessageTest_MessagesForwarded_CountsMatch) @@ -253,7 +222,7 @@ namespace UnitTest AZ_TEST_START_TRACE_SUPPRESSION; auto* mockCatalog = new ::testing::NiceMock(AzFramework::PlatformId::ANDROID_ID); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); // Expected error not finding catalog AZStd::unique_ptr< ::testing::NiceMock> catalogHolder; catalogHolder.reset(mockCatalog);