Automated test for scene files with and without python scripts running python incorrectly (#2373)

* Cleared m_scriptFilename between scene files.
This fixes a bug where a Python script file would be run on a scene file
that didn't have a script file set.
Added a general case version to SceneBuilderWorker.cpp, to make it easy
to mark all scene files as dirty.
Automated tests for this will come in a separate pull request.

Signed-off-by: stankowi <4838196+AMZN-stankowi@users.noreply.github.com>

* Work in progress automated tests

Signed-off-by: stankowi <4838196+AMZN-stankowi@users.noreply.github.com>

* Python test done

Signed-off-by: stankowi <4838196+AMZN-stankowi@users.noreply.github.com>

* Sorted jobs work now. This may sort too aggressively, I'll remove the additional sorting after some testing.

Signed-off-by: stankowi <4838196+AMZN-stankowi@users.noreply.github.com>

* Cleaned up test

Signed-off-by: stankowi <4838196+AMZN-stankowi@users.noreply.github.com>

* Fixed stray '

Signed-off-by: stankowi <4838196+AMZN-stankowi@users.noreply.github.com>

* Removed temp code from test

Signed-off-by: stankowi <4838196+AMZN-stankowi@users.noreply.github.com>

* Command line help options for AP
Removed job sorting that wasn't actually sorting jobs

Signed-off-by: stankowi <4838196+AMZN-stankowi@users.noreply.github.com>

* Changed constant variable names to match coding standards

Signed-off-by: stankowi <4838196+AMZN-stankowi@users.noreply.github.com>
This commit is contained in:
AMZN-stankowi
2021-08-02 10:57:57 -07:00
committed by GitHub
parent e22820e08b
commit 9ee9730294
17 changed files with 329 additions and 30 deletions
@@ -7,6 +7,7 @@
#
add_subdirectory(asset_processor_tests)
add_subdirectory(fbx_tests)
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
## AP Python Tests ##
@@ -0,0 +1,21 @@
#
# Copyright (c) Contributors to the Open 3D Engine Project.
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_pytest(
NAME SceneProcessingTests.PythonAssetBuilderTests
TEST_SUITE main
PATH ${CMAKE_CURRENT_LIST_DIR}/pythonassetbuildertests.py
PYTEST_MARKS "not SUITE_sandbox" # don't run sandbox tests in this file
EXCLUDE_TEST_RUN_TARGET_FROM_IDE
RUNTIME_DEPENDENCIES
AZ::AssetProcessorBatch
AZ::AssetProcessor
)
endif()
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f82aecb36faf5cf9f2730e5ad264db38a3a469f8f48aff9b74682d1a32b098f0
size 11644
@@ -0,0 +1,9 @@
{
"values":
[
{
"$type": "ScriptProcessorRule",
"scriptFilename": "TwoSceneFiles_OneWithPythonOneWithout_PythonOnlyRunsOnFirstScene/python_builder.py"
}
]
}
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f82aecb36faf5cf9f2730e5ad264db38a3a469f8f48aff9b74682d1a32b098f0
size 11644
@@ -0,0 +1,15 @@
{
"values": [
{
"$type": "{07B356B7-3635-40B5-878A-FAC4EFD5AD86} MeshGroup",
"name": "b_simple_box_no_script",
"nodeSelectionList": {
"selectedNodes": [
{},
"RootNode",
"RootNode.Cube"
]
}
}
]
}
@@ -0,0 +1,45 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
import datetime, uuid, os
import azlmbr.scene as sceneApi
import azlmbr.scene.graph
def output_test_data(scene):
source_filename = os.path.basename(scene.sourceFilename)
source_filename = source_filename.replace('.','_')
log_output_file_name = f"{source_filename}.log"
log_output_folder = os.path.dirname(scene.sourceFilename)
log_output_location = os.path.join(log_output_folder, log_output_file_name)
# Saving a file to the temp folder is the easiest way to have this test communicate
# with the outer python test.
with open(log_output_location, "w") as f:
# Just write something to the file, but the filename is the main information
# used for the test.
f.write(f"scene.sourceFilename: {scene.sourceFilename}\n")
return True
mySceneJobHandler = None
def on_update_manifest(args):
scene = args[0]
result = output_test_data(scene)
global mySceneJobHandler
mySceneJobHandler.disconnect()
mySceneJobHandler = None
return result
def main():
global mySceneJobHandler
mySceneJobHandler = sceneApi.ScriptBuildingNotificationBusHandler()
mySceneJobHandler.connect()
mySceneJobHandler.add_callback('OnUpdateManifest', on_update_manifest)
if __name__ == "__main__":
main()
@@ -0,0 +1,94 @@
"""
Copyright (c) Contributors to the Open 3D Engine Project.
For complete copyright and license terms please see the LICENSE at the root of this distribution.
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
# Import builtin libraries
import pytest
import logging
import os
import stat
# Import LyTestTools
from ly_test_tools.o3de.asset_processor import AssetProcessor
from ly_test_tools.o3de import asset_processor as asset_processor_utils
import ly_test_tools.environment.file_system as fs
# Import fixtures
from ..ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
from ..ap_fixtures.ap_setup_fixture import ap_setup_fixture as ap_setup_fixture
# Import LyShared
from ly_test_tools.o3de.ap_log_parser import APLogParser, APOutputParser
import ly_test_tools.o3de.pipeline_utils as utils
# Use the following logging pattern to hook all test logging together:
logger = logging.getLogger(__name__)
# Configuring the logging is done in ly_test_tools at the following location:
# ~/dev/Tools/LyTestTools/ly_test_tools/log/py_logging_util.py
# Helper: variables we will use for parameter values in the test:
targetProjects = ["AutomatedTesting"]
@pytest.fixture
def local_resources(request, workspace, ap_setup_fixture):
ap_setup_fixture["tests_dir"] = os.path.dirname(os.path.realpath(__file__))
@pytest.mark.usefixtures("asset_processor")
@pytest.mark.usefixtures("ap_setup_fixture")
@pytest.mark.usefixtures("local_resources")
@pytest.mark.parametrize("project", targetProjects)
@pytest.mark.assetpipeline
@pytest.mark.SUITE_main
class TestsPythonAssetProcessing_APBatch(object):
@pytest.mark.BAT
@pytest.mark.assetpipeline
def test_ProcessAssetWithoutScriptAfterAssetWithScript_ScriptOnlyRunsOnExpectedAsset(self, workspace, ap_setup_fixture, asset_processor):
# This is a regression test. The situation it's testing is, the Python script to run
# defined in scene manifest files was persisting in a single builder. So if
# that builder processed file a.fbx, then b.fbx, and a.fbx has a Python script to run,
# it was also running that Python script on b.fbx.
asset_processor.prepare_test_environment(ap_setup_fixture["tests_dir"], "TwoSceneFiles_OneWithPythonOneWithout_PythonOnlyRunsOnFirstScene")
asset_processor_extra_params = [
# Disabling Atom assets disables most products, using the debugOutput flag ensures one product is output.
"--debugOutput",
# By default, if job priorities are equal, jobs run in an arbitrary order. This makes sure
# jobs are run by sorting on the database source name, so they run in the same order each time
# when this test is run.
"--sortJobsByDBSourceName",
# Disabling Atom products means this asset won't need a lot of source dependencies to be processed,
# keeping the scope of this test down.
"--regset=\"/O3DE/SceneAPI/AssetImporter/SkipAtomOutput=true\"",
# The bug this regression test happened when the same builder processed FBX files with and without Python.
# This flag ensures that only one builder is launched, so that situation can be replicated.
"--regset=\"/Amazon/AssetProcessor/Settings/Jobs/maxJobs=1\""]
result, _ = asset_processor.batch_process(extra_params=asset_processor_extra_params)
assert result, "AP Batch failed"
expected_product_list = [
"a_simple_box_with_script.dbgsg",
"b_simple_box_no_script.dbgsg"
]
missing_assets, _ = utils.compare_assets_with_cache(expected_product_list,
asset_processor.project_test_cache_folder())
assert not missing_assets, f'The following assets were expected to be in, but not found in cache: {str(missing_assets)}'
# The Python script loaded in the scene manifest will write a log file with the source file's name
# to the temp folder. This is the easiest way to have the internal Python there communicate with this test.
expected_path = os.path.join(asset_processor.project_test_source_folder(), "a_simple_box_with_script_fbx.log")
unexpected_path = os.path.join(asset_processor.project_test_source_folder(), "b_simple_box_no_script_fbx.log")
# Simple check to make sure the Python script in the scene manifest ran on the file it should have ran on.
assert os.path.exists(expected_path), f"Did not find expected output test asset {expected_path}"
# If this test fails here, it means the Python script from the first processed FBX file is being run
# on the second FBX file, when it should not be.
assert not os.path.exists(unexpected_path), f"Found unexpected output test asset {unexpected_path}"