Merge branch 'development' of https://github.com/o3de/o3de into jckand/DynVegTestSaveFix
Signed-off-by: jckand-amzn <82226555+jckand-amzn@users.noreply.github.com>
This commit is contained in:
@@ -4,10 +4,18 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
import pytest
|
||||
|
||||
import ly_test_tools.environment.file_system as file_system
|
||||
import editor_python_test_tools.hydra_test_utils as hydra
|
||||
|
||||
from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@@ -114,3 +122,73 @@ class TestAutomation(EditorTestSuite):
|
||||
|
||||
class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest):
|
||||
from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module
|
||||
|
||||
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_generic'])
|
||||
class TestMaterialEditorBasicTests(object):
|
||||
@pytest.fixture(autouse=True)
|
||||
def setup_teardown(self, request, workspace, project):
|
||||
def delete_files():
|
||||
file_system.delete(
|
||||
[
|
||||
os.path.join(workspace.paths.project(), "Materials", "test_material.material"),
|
||||
os.path.join(workspace.paths.project(), "Materials", "test_material_1.material"),
|
||||
os.path.join(workspace.paths.project(), "Materials", "test_material_2.material"),
|
||||
],
|
||||
True,
|
||||
True,
|
||||
)
|
||||
# Cleanup our newly created materials
|
||||
delete_files()
|
||||
|
||||
def teardown():
|
||||
# Cleanup our newly created materials
|
||||
delete_files()
|
||||
|
||||
request.addfinalizer(teardown)
|
||||
|
||||
@pytest.mark.parametrize("exe_file_name", ["MaterialEditor"])
|
||||
@pytest.mark.test_case_id("C34448113") # Creating a New Asset.
|
||||
@pytest.mark.test_case_id("C34448114") # Opening an Existing Asset.
|
||||
@pytest.mark.test_case_id("C34448115") # Closing Selected Material.
|
||||
@pytest.mark.test_case_id("C34448116") # Closing All Materials.
|
||||
@pytest.mark.test_case_id("C34448117") # Closing all but Selected Material.
|
||||
@pytest.mark.test_case_id("C34448118") # Saving Material.
|
||||
@pytest.mark.test_case_id("C34448119") # Saving as a New Material.
|
||||
@pytest.mark.test_case_id("C34448120") # Saving as a Child Material.
|
||||
@pytest.mark.test_case_id("C34448121") # Saving all Open Materials.
|
||||
def test_MaterialEditorBasicTests(
|
||||
self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name):
|
||||
|
||||
expected_lines = [
|
||||
"Material opened: True",
|
||||
"Test asset doesn't exist initially: True",
|
||||
"New asset created: True",
|
||||
"New Material opened: True",
|
||||
"Material closed: True",
|
||||
"All documents closed: True",
|
||||
"Close All Except Selected worked as expected: True",
|
||||
"Actual Document saved with changes: True",
|
||||
"Document saved as copy is saved with changes: True",
|
||||
"Document saved as child is saved with changes: True",
|
||||
"Save All worked as expected: True",
|
||||
]
|
||||
unexpected_lines = [
|
||||
"Traceback (most recent call last):"
|
||||
]
|
||||
|
||||
hydra.launch_and_validate_results(
|
||||
request,
|
||||
TEST_DIRECTORY,
|
||||
generic_launcher,
|
||||
"hydra_AtomMaterialEditor_BasicTests.py",
|
||||
run_python="--runpython",
|
||||
timeout=43,
|
||||
expected_lines=expected_lines,
|
||||
unexpected_lines=unexpected_lines,
|
||||
halt_on_unexpected=True,
|
||||
null_renderer=True,
|
||||
log_file_name="MaterialEditor.log",
|
||||
enable_prefab_system=False,
|
||||
)
|
||||
|
||||
@@ -83,77 +83,6 @@ class TestAtomEditorComponentsMain(object):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_generic'])
|
||||
@pytest.mark.system
|
||||
class TestMaterialEditorBasicTests(object):
|
||||
@pytest.fixture(autouse=True)
|
||||
def setup_teardown(self, request, workspace, project):
|
||||
def delete_files():
|
||||
file_system.delete(
|
||||
[
|
||||
os.path.join(workspace.paths.project(), "Materials", "test_material.material"),
|
||||
os.path.join(workspace.paths.project(), "Materials", "test_material_1.material"),
|
||||
os.path.join(workspace.paths.project(), "Materials", "test_material_2.material"),
|
||||
],
|
||||
True,
|
||||
True,
|
||||
)
|
||||
# Cleanup our newly created materials
|
||||
delete_files()
|
||||
|
||||
def teardown():
|
||||
# Cleanup our newly created materials
|
||||
delete_files()
|
||||
|
||||
request.addfinalizer(teardown)
|
||||
|
||||
@pytest.mark.parametrize("exe_file_name", ["MaterialEditor"])
|
||||
@pytest.mark.test_case_id("C34448113") # Creating a New Asset.
|
||||
@pytest.mark.test_case_id("C34448114") # Opening an Existing Asset.
|
||||
@pytest.mark.test_case_id("C34448115") # Closing Selected Material.
|
||||
@pytest.mark.test_case_id("C34448116") # Closing All Materials.
|
||||
@pytest.mark.test_case_id("C34448117") # Closing all but Selected Material.
|
||||
@pytest.mark.test_case_id("C34448118") # Saving Material.
|
||||
@pytest.mark.test_case_id("C34448119") # Saving as a New Material.
|
||||
@pytest.mark.test_case_id("C34448120") # Saving as a Child Material.
|
||||
@pytest.mark.test_case_id("C34448121") # Saving all Open Materials.
|
||||
def test_MaterialEditorBasicTests(
|
||||
self, request, workspace, project, launcher_platform, generic_launcher, exe_file_name):
|
||||
|
||||
expected_lines = [
|
||||
"Material opened: True",
|
||||
"Test asset doesn't exist initially: True",
|
||||
"New asset created: True",
|
||||
"New Material opened: True",
|
||||
"Material closed: True",
|
||||
"All documents closed: True",
|
||||
"Close All Except Selected worked as expected: True",
|
||||
"Actual Document saved with changes: True",
|
||||
"Document saved as copy is saved with changes: True",
|
||||
"Document saved as child is saved with changes: True",
|
||||
"Save All worked as expected: True",
|
||||
]
|
||||
unexpected_lines = [
|
||||
"Traceback (most recent call last):"
|
||||
]
|
||||
|
||||
hydra.launch_and_validate_results(
|
||||
request,
|
||||
TEST_DIRECTORY,
|
||||
generic_launcher,
|
||||
"hydra_AtomMaterialEditor_BasicTests.py",
|
||||
run_python="--runpython",
|
||||
timeout=120,
|
||||
expected_lines=expected_lines,
|
||||
unexpected_lines=unexpected_lines,
|
||||
halt_on_unexpected=True,
|
||||
null_renderer=True,
|
||||
log_file_name="MaterialEditor.log",
|
||||
enable_prefab_system=False,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
class TestAutomation(EditorTestSuite):
|
||||
|
||||
@@ -162,6 +162,13 @@ def select_model_config(configname):
|
||||
azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SelectModelPresetByName", configname)
|
||||
|
||||
|
||||
def destroy_main_window():
|
||||
"""
|
||||
Closes the Material Editor window
|
||||
"""
|
||||
azlmbr.atomtools.AtomToolsMainWindowFactoryRequestBus(azlmbr.bus.Broadcast, "DestroyMainWindow")
|
||||
|
||||
|
||||
def wait_for_condition(function, timeout_in_seconds=1.0):
|
||||
# type: (function, float) -> bool
|
||||
"""
|
||||
|
||||
@@ -186,6 +186,11 @@ def run():
|
||||
material_editor.set_property(document2_id, property2_name, initial_color)
|
||||
material_editor.save_all()
|
||||
material_editor.close_all_documents()
|
||||
material_editor.wait_for_condition(lambda:
|
||||
(not material_editor.is_open(document1_id)) and
|
||||
(not material_editor.is_open(document2_id)) and
|
||||
(not material_editor.is_open(document3_id)), 2.0)
|
||||
material_editor.destroy_main_window()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -115,7 +115,6 @@ CNewLevelDialog::~CNewLevelDialog()
|
||||
void CNewLevelDialog::OnStartup()
|
||||
{
|
||||
UpdateData(false);
|
||||
setFocus();
|
||||
}
|
||||
|
||||
void CNewLevelDialog::UpdateData(bool fromUi)
|
||||
|
||||
@@ -133,6 +133,9 @@
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>LEVEL</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
|
||||
@@ -8,57 +8,41 @@
|
||||
|
||||
#include <AzCore/PlatformIncl.h>
|
||||
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzTest/Platform.h>
|
||||
#include <AzTest/Utils.h>
|
||||
|
||||
namespace AZ
|
||||
namespace AZ::Test
|
||||
{
|
||||
namespace Test
|
||||
ScopedAutoTempDirectory::ScopedAutoTempDirectory()
|
||||
{
|
||||
ScopedAutoTempDirectory::ScopedAutoTempDirectory()
|
||||
using UuidString = AZStd::fixed_string<AZ::Uuid::MaxStringBuffer>;
|
||||
constexpr DWORD bufferSize = static_cast<DWORD>(AZ::IO::MaxPathLength);
|
||||
|
||||
wchar_t tempDirW[AZ::IO::MaxPathLength]{};
|
||||
GetTempPathW(bufferSize, tempDirW);
|
||||
|
||||
AZ::IO::FixedMaxPath tempDirectoryRoot;
|
||||
AZStd::to_string(tempDirectoryRoot.Native(), tempDirW);
|
||||
|
||||
constexpr int MaxAttempts = 255;
|
||||
for (int i = 0; i < MaxAttempts; ++i)
|
||||
{
|
||||
constexpr const DWORD bufferSize = static_cast<DWORD>(AZ::IO::MaxPathLength);
|
||||
|
||||
char tempDir[bufferSize] = {0};
|
||||
GetTempPathA(bufferSize, tempDir);
|
||||
|
||||
char workingTempPathBuffer[bufferSize] = {'\0'};
|
||||
|
||||
int maxAttempts = 2000; // Prevent an infinite loop by setting an arbitrary maximum attempts at finding an available temp folder name
|
||||
while (maxAttempts > 0)
|
||||
AZ::IO::FixedMaxPath testPath = tempDirectoryRoot /
|
||||
AZ::IO::FixedMaxPathString::format("UnitTest-%s",
|
||||
AZ::Uuid::CreateRandom().ToString<UuidString>().c_str());
|
||||
// Try to create the temp directory if it doesn't exist
|
||||
if (!AZ::IO::SystemFile::Exists(testPath.c_str()) && AZ::IO::SystemFile::CreateDir(testPath.c_str()))
|
||||
{
|
||||
// Use the system's tick count to base the folder name
|
||||
ULONGLONG currentTick = GetTickCount64();
|
||||
azsnprintf(workingTempPathBuffer, bufferSize, "%sUnitTest-%X", tempDir, aznumeric_cast<unsigned int>(currentTick));
|
||||
|
||||
// Check if the requested directory name is available and re-generate if it already exists
|
||||
bool exists = AZ::IO::SystemFile::Exists(workingTempPathBuffer);
|
||||
if (exists)
|
||||
{
|
||||
Sleep(1);
|
||||
maxAttempts--;
|
||||
continue;
|
||||
}
|
||||
azstrncpy(AZStd::data(m_tempDirectory), AZStd::size(m_tempDirectory),
|
||||
testPath.c_str(), testPath.Native().size());
|
||||
break;
|
||||
}
|
||||
|
||||
AZ_Error("AzTest", maxAttempts > 0, "Unable to determine a temp directory");
|
||||
|
||||
if (maxAttempts > 0)
|
||||
{
|
||||
// Create the temp directory and track it for deletion
|
||||
bool tempDirectoryCreated = AZ::IO::SystemFile::CreateDir(workingTempPathBuffer);
|
||||
if (tempDirectoryCreated)
|
||||
{
|
||||
azstrncpy(m_tempDirectory, AZ::IO::MaxPathLength, workingTempPathBuffer, AZ::IO::MaxPathLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("AzTest", false, "Unable to create temp directory %s", workingTempPathBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // Test
|
||||
} // AZ
|
||||
|
||||
AZ_Error("AzTest", m_tempDirectory[0] != '\0', "Unable to create temp path within directory %s after %d attempts",
|
||||
tempDirectoryRoot.c_str(), MaxAttempts);
|
||||
}
|
||||
} // AZ::Test
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
#include <AzFramework/Physics/Material.h>
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
|
||||
|
||||
namespace Terrain
|
||||
@@ -43,11 +44,25 @@ namespace Terrain
|
||||
AZ::Edit::UIHandlers::ComboBox, &TerrainPhysicsSurfaceMaterialMapping::m_surfaceTag, "Surface Tag",
|
||||
"Surface type to map to a physics material.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &TerrainPhysicsSurfaceMaterialMapping::m_materialId, "Material ID", "")
|
||||
->ElementAttribute(Physics::Attributes::MaterialLibraryAssetId, &TerrainPhysicsSurfaceMaterialMapping::GetMaterialLibraryId)
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(AZ::Edit::Attributes::ShowProductAssetFileName, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Data::AssetId TerrainPhysicsSurfaceMaterialMapping::GetMaterialLibraryId()
|
||||
{
|
||||
if (const auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get())
|
||||
{
|
||||
if (const auto* physicsConfiguration = physicsSystem->GetConfiguration())
|
||||
{
|
||||
return physicsConfiguration->m_materialLibraryAsset.GetId();
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void TerrainPhysicsColliderConfig::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
TerrainPhysicsSurfaceMaterialMapping::Reflect(context);
|
||||
|
||||
@@ -36,6 +36,9 @@ namespace Terrain
|
||||
|
||||
SurfaceData::SurfaceTag m_surfaceTag;
|
||||
Physics::MaterialId m_materialId;
|
||||
|
||||
private:
|
||||
static AZ::Data::AssetId GetMaterialLibraryId();
|
||||
};
|
||||
|
||||
class TerrainPhysicsColliderConfig
|
||||
|
||||
Reference in New Issue
Block a user