Merge branch 'development' into ExposeLodControls
This commit is contained in:
@@ -25,3 +25,4 @@ TestResults/**
|
||||
*.swatches
|
||||
/imgui.ini
|
||||
/scripts/project_manager/logs/
|
||||
/AutomatedTesting/Gem/PythonTests/scripting/TestResults
|
||||
|
||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
@@ -212,10 +212,10 @@
|
||||
"Configuration": {
|
||||
"ModelAsset": {
|
||||
"assetId": {
|
||||
"guid": "{935F694A-8639-515B-8133-81CDC7948E5B}",
|
||||
"subId": 277333723
|
||||
"guid": "{0CD745C0-6AA8-569A-A68A-73A3270986C4}",
|
||||
"subId": 277889906
|
||||
},
|
||||
"assetHint": "objects/groudplane/groundplane_521x521m.azmodel"
|
||||
"assetHint": "objects/groudplane/groundplane_512x512m.azmodel"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2771,6 +2771,80 @@
|
||||
<source>VECTOR2_CREATEONE_OUTPUT0_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_NAME">
|
||||
<source>VECTOR2_DIRECTIONTO_NAME</source>
|
||||
<comment>Class/Bus: Vector2 Event/Method: DirectionTo</comment>
|
||||
<translation type="unfinished">Get Direction Vector</translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_TOOLTIP">
|
||||
<source>VECTOR2_DIRECTIONTO_TOOLTIP</source>
|
||||
<translation>Returns a direction vector between two points and the distance between them, by default the direction will be normalized, it may be optionally scaled using the Scale parameter if different from 1.0</translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_CATEGORY">
|
||||
<source>VECTOR2_DIRECTIONTO_CATEGORY</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_OUT_NAME">
|
||||
<source>VECTOR2_DIRECTIONTO_OUT_NAME</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_OUT_TOOLTIP">
|
||||
<source>VECTOR2_DIRECTIONTO_OUT_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTOL_IN_NAME">
|
||||
<source>VECTOR2_DIRECTIONTOL_IN_NAME</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_IN_TOOLTIP">
|
||||
<source>VECTOR2_DIRECTIONTO_IN_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_OUTPUT0_NAME">
|
||||
<source>VECTOR2_DIRECTIONTO_OUTPUT0_NAME</source>
|
||||
<comment>C++ Type: const Vector2</comment>
|
||||
<translation type="unfinished">Direction</translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_OUTPUT0_TOOLTIP">
|
||||
<source>VECTOR2_DIRECTIONTO_OUTPUT0_TOOLTIP</source>
|
||||
<translation>The direction between To and From normalized and optionally scaled</translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_OUTPUT1_NAME">
|
||||
<source>VECTOR2_DIRECTIONTO_OUTPUT1_NAME</source>
|
||||
<comment>C++ Type: float</comment>
|
||||
<translation type="unfinished">Distance</translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_OUTPUT1_TOOLTIP">
|
||||
<source>VECTOR2_DIRECTIONTO_OUTPUT1_TOOLTIP</source>
|
||||
<translation>The distance between To and From</translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_PARAM0_NAME">
|
||||
<source>VECTOR2_DIRECTIONTO_PARAM0_NAME</source>
|
||||
<comment>Simple Type: Vector2 C++ Type: Vector2*</comment>
|
||||
<translation type="unfinished">From</translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_PARAM0_TOOLTIP">
|
||||
<source>VECTOR2_DIRECTIONTO_PARAM0_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_PARAM1_NAME">
|
||||
<source>VECTOR2_DIRECTIONTO_PARAM1_NAME</source>
|
||||
<comment>Simple Type: Vector2 C++ Type: Vector2*</comment>
|
||||
<translation type="unfinished">To</translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_PARAM1_TOOLTIP">
|
||||
<source>VECTOR2_DIRECTIONTO_PARAM1_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_PARAM2_NAME">
|
||||
<source>VECTOR2_DIRECTIONTO_PARAM2_NAME</source>
|
||||
<comment>Simple Type: Vector2 C++ Type: Vector2*</comment>
|
||||
<translation type="unfinished">Scale</translation>
|
||||
</message>
|
||||
<message id="VECTOR2_DIRECTIONTO_PARAM2_TOOLTIP">
|
||||
<source>VECTOR2_DIRECTIONTO_PARAM2_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR2_GETPROJECTED_NAME">
|
||||
<source>VECTOR2_GETPROJECTED_NAME</source>
|
||||
<comment>Class/Bus: Vector2 Event/Method: GetProjected</comment>
|
||||
@@ -32262,6 +32336,80 @@ An Entity can be selected by using the pick button, or by dragging an Entity fro
|
||||
<source>VECTOR4_GETRECIPROCAL_PARAM0_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_NAME">
|
||||
<source>VECTOR4_DIRECTIONTO_NAME</source>
|
||||
<comment>Class/Bus: Vector4 Event/Method: DirectionTo</comment>
|
||||
<translation type="unfinished">Get Direction Vector</translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_TOOLTIP">
|
||||
<source>VECTOR4_DIRECTIONTO_TOOLTIP</source>
|
||||
<translation>Returns a direction vector between two points and the distance between them, by default the direction will be normalized, it may be optionally scaled using the Scale parameter if different from 1.0</translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_CATEGORY">
|
||||
<source>VECTOR4_DIRECTIONTO_CATEGORY</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_OUT_NAME">
|
||||
<source>VECTOR4_DIRECTIONTO_OUT_NAME</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_OUT_TOOLTIP">
|
||||
<source>VECTOR4_DIRECTIONTO_OUT_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTOL_IN_NAME">
|
||||
<source>VECTOR4_DIRECTIONTOL_IN_NAME</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_IN_TOOLTIP">
|
||||
<source>VECTOR4_DIRECTIONTO_IN_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_OUTPUT0_NAME">
|
||||
<source>VECTOR4_DIRECTIONTO_OUTPUT0_NAME</source>
|
||||
<comment>C++ Type: const Vector4</comment>
|
||||
<translation type="unfinished">Direction</translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_OUTPUT0_TOOLTIP">
|
||||
<source>VECTOR4_DIRECTIONTO_OUTPUT0_TOOLTIP</source>
|
||||
<translation>The direction between To and From normalized and optionally scaled</translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_OUTPUT1_NAME">
|
||||
<source>VECTOR4_DIRECTIONTO_OUTPUT1_NAME</source>
|
||||
<comment>C++ Type: float</comment>
|
||||
<translation type="unfinished">Distance</translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_OUTPUT1_TOOLTIP">
|
||||
<source>VECTOR4_DIRECTIONTO_OUTPUT1_TOOLTIP</source>
|
||||
<translation>The distance between To and From</translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_PARAM0_NAME">
|
||||
<source>VECTOR4_DIRECTIONTO_PARAM0_NAME</source>
|
||||
<comment>Simple Type: Vector4 C++ Type: Vector4*</comment>
|
||||
<translation type="unfinished">From</translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_PARAM0_TOOLTIP">
|
||||
<source>VECTOR4_DIRECTIONTO_PARAM0_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_PARAM1_NAME">
|
||||
<source>VECTOR4_DIRECTIONTO_PARAM1_NAME</source>
|
||||
<comment>Simple Type: Vector4 C++ Type: Vector4*</comment>
|
||||
<translation type="unfinished">To</translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_PARAM1_TOOLTIP">
|
||||
<source>VECTOR4_DIRECTIONTO_PARAM1_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_PARAM2_NAME">
|
||||
<source>VECTOR4_DIRECTIONTO_PARAM2_NAME</source>
|
||||
<comment>Simple Type: Vector4 C++ Type: Vector4*</comment>
|
||||
<translation type="unfinished">Scale</translation>
|
||||
</message>
|
||||
<message id="VECTOR4_DIRECTIONTO_PARAM2_TOOLTIP">
|
||||
<source>VECTOR4_DIRECTIONTO_PARAM2_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR4_AXISX_NAME">
|
||||
<source>VECTOR4_AXISX_NAME</source>
|
||||
<comment>Class/Bus: Vector4 Event/Method: CreateAxisX</comment>
|
||||
@@ -37469,6 +37617,80 @@ An Entity can be selected by using the pick button, or by dragging an Entity fro
|
||||
<source>VECTOR3_GETRECIPROCAL_PARAM0_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_NAME">
|
||||
<source>VECTOR3_DIRECTIONTO_NAME</source>
|
||||
<comment>Class/Bus: Vector3 Event/Method: DirectionTo</comment>
|
||||
<translation type="unfinished">Get Direction Vector</translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_TOOLTIP">
|
||||
<source>VECTOR3_DIRECTIONTO_TOOLTIP</source>
|
||||
<translation>Returns a direction vector between two points and the distance between them, by default the direction will be normalized, it may be optionally scaled using the Scale parameter if different from 1.0</translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_CATEGORY">
|
||||
<source>VECTOR3_DIRECTIONTO_CATEGORY</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_OUT_NAME">
|
||||
<source>VECTOR3_DIRECTIONTO_OUT_NAME</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_OUT_TOOLTIP">
|
||||
<source>VECTOR3_DIRECTIONTO_OUT_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTOL_IN_NAME">
|
||||
<source>VECTOR3_DIRECTIONTOL_IN_NAME</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_IN_TOOLTIP">
|
||||
<source>VECTOR3_DIRECTIONTO_IN_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_OUTPUT0_NAME">
|
||||
<source>VECTOR3_DIRECTIONTO_OUTPUT0_NAME</source>
|
||||
<comment>C++ Type: const Vector3</comment>
|
||||
<translation type="unfinished">Direction</translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_OUTPUT0_TOOLTIP">
|
||||
<source>VECTOR3_DIRECTIONTO_OUTPUT0_TOOLTIP</source>
|
||||
<translation>The direction between To and From normalized and optionally scaled</translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_OUTPUT1_NAME">
|
||||
<source>VECTOR3_DIRECTIONTO_OUTPUT1_NAME</source>
|
||||
<comment>C++ Type: float</comment>
|
||||
<translation type="unfinished">Distance</translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_OUTPUT1_TOOLTIP">
|
||||
<source>VECTOR3_DIRECTIONTO_OUTPUT1_TOOLTIP</source>
|
||||
<translation>The distance between To and From</translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_PARAM0_NAME">
|
||||
<source>VECTOR3_DIRECTIONTO_PARAM0_NAME</source>
|
||||
<comment>Simple Type: Vector3 C++ Type: Vector3*</comment>
|
||||
<translation type="unfinished">From</translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_PARAM0_TOOLTIP">
|
||||
<source>VECTOR3_DIRECTIONTO_PARAM0_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_PARAM1_NAME">
|
||||
<source>VECTOR3_DIRECTIONTO_PARAM1_NAME</source>
|
||||
<comment>Simple Type: Vector3 C++ Type: Vector3*</comment>
|
||||
<translation type="unfinished">To</translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_PARAM1_TOOLTIP">
|
||||
<source>VECTOR3_DIRECTIONTO_PARAM1_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_PARAM2_NAME">
|
||||
<source>VECTOR3_DIRECTIONTO_PARAM2_NAME</source>
|
||||
<comment>Simple Type: Vector3 C++ Type: Vector3*</comment>
|
||||
<translation type="unfinished">Scale</translation>
|
||||
</message>
|
||||
<message id="VECTOR3_DIRECTIONTO_PARAM2_TOOLTIP">
|
||||
<source>VECTOR3_DIRECTIONTO_PARAM2_TOOLTIP</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message id="VECTOR3_PROJECT_NAME">
|
||||
<source>VECTOR3_PROJECT_NAME</source>
|
||||
<comment>Class/Bus: Vector3 Event/Method: Project</comment>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"Amazon": {
|
||||
"AssetProcessor": {
|
||||
"Settings": {
|
||||
"RC cgf": {
|
||||
"ignore": true
|
||||
},
|
||||
"RC fbx": {
|
||||
"ignore": true
|
||||
},
|
||||
"ScanFolder AtomTestData": {
|
||||
"watch": "@ENGINEROOT@/Gems/Atom/TestData",
|
||||
"recursive": 1,
|
||||
"order": 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,12 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TARGETS Editor
|
||||
VARIANTS Tools)
|
||||
|
||||
# The Material Editor needs the Lyshine "Tools" gem variant for the custom LyShine pass
|
||||
ly_enable_gems(
|
||||
PROJECT_NAME AutomatedTesting GEMS LyShine
|
||||
TARGETS MaterialEditor
|
||||
VARIANTS Tools)
|
||||
|
||||
# The pipeline tools use "Builders" gem variants:
|
||||
ly_enable_gems(
|
||||
PROJECT_NAME AutomatedTesting GEM_FILE enabled_gems.cmake
|
||||
|
||||
@@ -12,6 +12,11 @@
|
||||
################################################################################
|
||||
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
# Only enable AWS automated tests on Windows
|
||||
if(NOT "${PAL_PLATFORM_NAME}" STREQUAL "Windows")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Enable after installing NodeJS and CDK on jenkins Windows AMI.
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::AWSTests
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# AWS Gem Automation Tests
|
||||
|
||||
## Prerequisites
|
||||
1. Build the O3DE Editor and AutomatedTesting.GameLauncher in Profile.
|
||||
2. AWS CLI is installed and configured following [Configuration and Credential File Settings](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html).
|
||||
3. [AWS Cloud Development Kit (CDK)](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_install) is installed.
|
||||
|
||||
## Deploy CDK Applications
|
||||
1. Go to the AWS IAM console and create an IAM role called o3de-automation-tests which adds your own account as as a trusted entity and uses the "AdministratorAccess" permissions policy.
|
||||
2. Copy {engine_root}\scripts\build\Platform\Windows\deploy_cdk_applications.cmd to your engine root folder.
|
||||
3. Open a Command Prompt window at the engine root and set the following environment variables:
|
||||
Set O3DE_AWS_PROJECT_NAME=AWSAUTO
|
||||
Set O3DE_AWS_DEPLOY_REGION=us-east-1
|
||||
Set ASSUME_ROLE_ARN="arn:aws:iam::{your_aws_account_id}:role/o3de-automation-tests"
|
||||
Set COMMIT_ID=HEAD
|
||||
4. Deploy the CDK applications for AWS gems by running deploy_cdk_applications.cmd in the same Command Prompt window.
|
||||
5. Edit AWS\common\constants.py to replace the assume role ARN with your own:
|
||||
arn:aws:iam::{your_aws_account_id}:role/o3de-automation-tests
|
||||
|
||||
## Run Automation Tests
|
||||
### CLI
|
||||
Open a Command Prompt window at the engine root and run the following CLI command:
|
||||
python\python.cmd -m pytest {path_to_the_test_file} --build-directory {directory_to_the_profile_build}
|
||||
|
||||
### Pycharm
|
||||
You can also run any specific automation test directly from Pycharm by providing the "--build-directory" argument in the Run Configuration.
|
||||
+61
-45
@@ -9,18 +9,18 @@ import logging
|
||||
import os
|
||||
import pytest
|
||||
import typing
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
import ly_test_tools.log.log_monitor
|
||||
|
||||
from AWS.common import constants
|
||||
from .aws_metrics_custom_thread import AWSMetricsThread
|
||||
|
||||
# fixture imports
|
||||
from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor
|
||||
from .aws_metrics_utils import aws_metrics_utils
|
||||
from .aws_metrics_custom_thread import AWSMetricsThread
|
||||
|
||||
AWS_METRICS_FEATURE_NAME = 'AWSMetrics'
|
||||
GAME_LOG_NAME = 'Game.log'
|
||||
CONTEXT_VARIABLE = ['-c', 'batch_processing=true']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -36,7 +36,7 @@ def setup(launcher: pytest.fixture,
|
||||
asset_processor.start()
|
||||
asset_processor.wait_for_idle()
|
||||
|
||||
file_to_monitor = os.path.join(launcher.workspace.paths.project_log(), GAME_LOG_NAME)
|
||||
file_to_monitor = os.path.join(launcher.workspace.paths.project_log(), constants.GAME_LOG_NAME)
|
||||
|
||||
# Initialize the log monitor.
|
||||
log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=launcher, log_file_path=file_to_monitor)
|
||||
@@ -73,23 +73,26 @@ def monitor_metrics_submission(log_monitor: pytest.fixture) -> None:
|
||||
f'unexpected_lines values: {unexpected_lines}')
|
||||
|
||||
|
||||
def query_metrics_from_s3(aws_metrics_utils: pytest.fixture, stack_name: str) -> None:
|
||||
def query_metrics_from_s3(aws_metrics_utils: pytest.fixture, resource_mappings: pytest.fixture, stack_name: str) -> None:
|
||||
"""
|
||||
Verify that the metrics events are delivered to the S3 bucket and can be queried.
|
||||
aws_metrics_utils: aws_metrics_utils fixture.
|
||||
stack_name: name of the CloudFormation stack.
|
||||
:param aws_metrics_utils: aws_metrics_utils fixture.
|
||||
:param resource_mappings: resource_mappings fixture.
|
||||
:param stack_name: name of the CloudFormation stack.
|
||||
"""
|
||||
analytics_bucket_name = aws_metrics_utils.get_analytics_bucket_name(stack_name)
|
||||
aws_metrics_utils.verify_s3_delivery(analytics_bucket_name)
|
||||
aws_metrics_utils.verify_s3_delivery(
|
||||
resource_mappings.get_resource_name_id('AWSMetrics.AnalyticsBucketName')
|
||||
)
|
||||
logger.info('Metrics are sent to S3.')
|
||||
|
||||
aws_metrics_utils.run_glue_crawler(f'{stack_name}-EventsCrawler')
|
||||
aws_metrics_utils.run_glue_crawler(
|
||||
resource_mappings.get_resource_name_id('AWSMetrics.EventsCrawlerName'))
|
||||
|
||||
# Remove the events_json table if exists so that the sample query can create a table with the same name.
|
||||
aws_metrics_utils.delete_table(f'{stack_name}-eventsdatabase', 'events_json')
|
||||
aws_metrics_utils.run_named_queries(f'{stack_name}-AthenaWorkGroup')
|
||||
logger.info('Query metrics from S3 successfully.')
|
||||
|
||||
# Empty the S3 bucket. S3 buckets can only be deleted successfully when it doesn't contain any object.
|
||||
aws_metrics_utils.empty_batch_analytics_bucket(analytics_bucket_name)
|
||||
|
||||
|
||||
def verify_operational_metrics(aws_metrics_utils: pytest.fixture, stack_name: str, start_time: datetime) -> None:
|
||||
"""
|
||||
@@ -102,7 +105,7 @@ def verify_operational_metrics(aws_metrics_utils: pytest.fixture, stack_name: st
|
||||
'AWS/Lambda',
|
||||
'Invocations',
|
||||
[{'Name': 'FunctionName',
|
||||
'Value': f'{stack_name}-AnalyticsProcessingLambdaName'}],
|
||||
'Value': f'{stack_name}-AnalyticsProcessingLambda'}],
|
||||
start_time)
|
||||
logger.info('AnalyticsProcessingLambda metrics are sent to CloudWatch.')
|
||||
|
||||
@@ -115,50 +118,59 @@ def verify_operational_metrics(aws_metrics_utils: pytest.fixture, stack_name: st
|
||||
logger.info('EventsProcessingLambda metrics are sent to CloudWatch.')
|
||||
|
||||
|
||||
def start_kinesis_analytics_application(aws_metrics_utils: pytest.fixture, stack_name: str) -> None:
|
||||
def update_kinesis_analytics_application_status(aws_metrics_utils: pytest.fixture,
|
||||
resource_mappings: pytest.fixture, start_application: bool) -> None:
|
||||
"""
|
||||
Start the Kinesis analytics application for real-time analytics.
|
||||
aws_metrics_utils: aws_metrics_utils fixture.
|
||||
stack_name: name of the CloudFormation stack.
|
||||
Update the Kinesis analytics application to start or stop it.
|
||||
:param aws_metrics_utils: aws_metrics_utils fixture.
|
||||
:param resource_mappings: resource_mappings fixture.
|
||||
:param start_application: whether to start or stop the application.
|
||||
"""
|
||||
analytics_application_name = f'{stack_name}-AnalyticsApplication'
|
||||
aws_metrics_utils.start_kinesis_data_analytics_application(analytics_application_name)
|
||||
if start_application:
|
||||
aws_metrics_utils.start_kinesis_data_analytics_application(
|
||||
resource_mappings.get_resource_name_id('AWSMetrics.AnalyticsApplicationName'))
|
||||
else:
|
||||
aws_metrics_utils.stop_kinesis_data_analytics_application(
|
||||
resource_mappings.get_resource_name_id('AWSMetrics.AnalyticsApplicationName'))
|
||||
|
||||
@pytest.mark.SUITE_periodic
|
||||
@pytest.mark.usefixtures('automatic_process_killer')
|
||||
@pytest.mark.parametrize('project', ['AutomatedTesting'])
|
||||
@pytest.mark.parametrize('level', ['AWS/Metrics'])
|
||||
@pytest.mark.parametrize('feature_name', [AWS_METRICS_FEATURE_NAME])
|
||||
@pytest.mark.usefixtures('resource_mappings')
|
||||
@pytest.mark.parametrize('resource_mappings_filename', ['default_aws_resource_mappings.json'])
|
||||
@pytest.mark.usefixtures('aws_credentials')
|
||||
@pytest.mark.usefixtures('resource_mappings')
|
||||
@pytest.mark.parametrize('assume_role_arn', [constants.ASSUME_ROLE_ARN])
|
||||
@pytest.mark.parametrize('feature_name', [AWS_METRICS_FEATURE_NAME])
|
||||
@pytest.mark.parametrize('level', ['AWS/Metrics'])
|
||||
@pytest.mark.parametrize('profile_name', ['AWSAutomationTest'])
|
||||
@pytest.mark.parametrize('region_name', ['us-west-2'])
|
||||
@pytest.mark.parametrize('assume_role_arn', ['arn:aws:iam::645075835648:role/o3de-automation-tests'])
|
||||
@pytest.mark.usefixtures('cdk')
|
||||
@pytest.mark.parametrize('session_name', ['o3de-Automation-session'])
|
||||
@pytest.mark.parametrize('deployment_params', [CONTEXT_VARIABLE])
|
||||
@pytest.mark.parametrize('project', ['AutomatedTesting'])
|
||||
@pytest.mark.parametrize('region_name', [constants.AWS_REGION])
|
||||
@pytest.mark.parametrize('resource_mappings_filename', [constants.AWS_RESOURCE_MAPPING_FILE_NAME])
|
||||
@pytest.mark.parametrize('session_name', [constants.SESSION_NAME])
|
||||
@pytest.mark.parametrize('stacks', [[f'{constants.AWS_PROJECT_NAME}-{AWS_METRICS_FEATURE_NAME}-{constants.AWS_REGION}']])
|
||||
class TestAWSMetricsWindows(object):
|
||||
"""
|
||||
Test class to verify the real-time and batch analytics for metrics.
|
||||
"""
|
||||
|
||||
@pytest.mark.parametrize('destroy_stacks_on_teardown', [False])
|
||||
def test_realtime_and_batch_analytics(self,
|
||||
level: str,
|
||||
launcher: pytest.fixture,
|
||||
asset_processor: pytest.fixture,
|
||||
workspace: pytest.fixture,
|
||||
aws_utils: pytest.fixture,
|
||||
cdk: pytest.fixture,
|
||||
resource_mappings: pytest.fixture,
|
||||
stacks: typing.List,
|
||||
aws_metrics_utils: pytest.fixture):
|
||||
"""
|
||||
Verify that the metrics events are sent to CloudWatch and S3 for analytics.
|
||||
"""
|
||||
# Start Kinesis analytics application on a separate thread to avoid blocking the test.
|
||||
kinesis_analytics_application_thread = AWSMetricsThread(target=start_kinesis_analytics_application,
|
||||
args=(aws_metrics_utils, cdk.stacks[0]))
|
||||
kinesis_analytics_application_thread = AWSMetricsThread(target=update_kinesis_analytics_application_status,
|
||||
args=(aws_metrics_utils, resource_mappings, True))
|
||||
kinesis_analytics_application_thread.start()
|
||||
|
||||
# Clear the analytics bucket objects before sending new metrics.
|
||||
aws_metrics_utils.empty_bucket(
|
||||
resource_mappings.get_resource_name_id('AWSMetrics.AnalyticsBucketName'))
|
||||
|
||||
log_monitor = setup(launcher, asset_processor)
|
||||
|
||||
# Kinesis analytics application needs to be in the running state before we start the game launcher.
|
||||
@@ -177,18 +189,22 @@ class TestAWSMetricsWindows(object):
|
||||
start_time)
|
||||
logger.info('Real-time metrics are sent to CloudWatch.')
|
||||
|
||||
# Run time-consuming verifications on separate threads to avoid blocking the test.
|
||||
verification_threads = list()
|
||||
verification_threads.append(
|
||||
AWSMetricsThread(target=query_metrics_from_s3, args=(aws_metrics_utils, cdk.stacks[0])))
|
||||
verification_threads.append(
|
||||
AWSMetricsThread(target=verify_operational_metrics, args=(aws_metrics_utils, cdk.stacks[0], start_time)))
|
||||
for thread in verification_threads:
|
||||
# Run time-consuming operations on separate threads to avoid blocking the test.
|
||||
operational_threads = list()
|
||||
operational_threads.append(
|
||||
AWSMetricsThread(target=query_metrics_from_s3,
|
||||
args=(aws_metrics_utils, resource_mappings, stacks[0])))
|
||||
operational_threads.append(
|
||||
AWSMetricsThread(target=verify_operational_metrics,
|
||||
args=(aws_metrics_utils, stacks[0], start_time)))
|
||||
operational_threads.append(
|
||||
AWSMetricsThread(target=update_kinesis_analytics_application_status,
|
||||
args=(aws_metrics_utils, resource_mappings, False)))
|
||||
for thread in operational_threads:
|
||||
thread.start()
|
||||
for thread in verification_threads:
|
||||
for thread in operational_threads:
|
||||
thread.join()
|
||||
|
||||
@pytest.mark.parametrize('destroy_stacks_on_teardown', [True])
|
||||
def test_unauthorized_user_request_rejected(self,
|
||||
level: str,
|
||||
launcher: pytest.fixture,
|
||||
|
||||
@@ -198,7 +198,7 @@ class AWSMetricsUtils:
|
||||
|
||||
assert state == 'SUCCEEDED', f'Failed to run the named query {named_query.get("Name", {})}'
|
||||
|
||||
def empty_batch_analytics_bucket(self, bucket_name: str) -> None:
|
||||
def empty_bucket(self, bucket_name: str) -> None:
|
||||
"""
|
||||
Empty the S3 bucket following:
|
||||
https://boto3.amazonaws.com/v1/documentation/api/latest/guide/migrations3.html
|
||||
@@ -211,25 +211,18 @@ class AWSMetricsUtils:
|
||||
for key in bucket.objects.all():
|
||||
key.delete()
|
||||
|
||||
def get_analytics_bucket_name(self, stack_name: str) -> str:
|
||||
def delete_table(self, database_name: str, table_name: str) -> None:
|
||||
"""
|
||||
Get the name of the deployed S3 bucket.
|
||||
:param stack_name: Name of the CloudFormation stack.
|
||||
:return: Name of the deployed S3 bucket.
|
||||
Delete an existing Glue table.
|
||||
|
||||
:param database_name: Name of the Glue database.
|
||||
:param table_name: Name of the table to delete.
|
||||
"""
|
||||
|
||||
client = self._aws_util.client('cloudformation')
|
||||
|
||||
response = client.describe_stack_resources(
|
||||
StackName=stack_name
|
||||
client = self._aws_util.client('glue')
|
||||
client.delete_table(
|
||||
DatabaseName=database_name,
|
||||
Name=table_name
|
||||
)
|
||||
resources = response.get('StackResources', [])
|
||||
|
||||
for resource in resources:
|
||||
if resource.get('ResourceType') == 'AWS::S3::Bucket':
|
||||
return resource.get('PhysicalResourceId', '')
|
||||
|
||||
return ''
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
|
||||
@@ -45,7 +45,8 @@ class KinesisAnalyticsApplicationUpdatedWaiter(CustomWaiter):
|
||||
class GlueCrawlerReadyWaiter(CustomWaiter):
|
||||
"""
|
||||
Subclass of the base custom waiter class.
|
||||
Wait for the Glue crawler to finish its processing.
|
||||
Wait for the Glue crawler to finish its processing. Return when the crawler is in the "Stopping" status
|
||||
to avoid wasting too much time in the automation tests on its shutdown process.
|
||||
"""
|
||||
def __init__(self, client: botocore.client):
|
||||
"""
|
||||
@@ -57,7 +58,7 @@ class GlueCrawlerReadyWaiter(CustomWaiter):
|
||||
'GlueCrawlerReady',
|
||||
'GetCrawler',
|
||||
'Crawler.State',
|
||||
{'READY': WaitState.SUCCESS},
|
||||
{'STOPPING': WaitState.SUCCESS},
|
||||
client)
|
||||
|
||||
def wait(self, crawler_name):
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
@@ -1,248 +0,0 @@
|
||||
"""
|
||||
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 os
|
||||
import pytest
|
||||
import boto3
|
||||
import uuid
|
||||
import logging
|
||||
import subprocess
|
||||
import botocore
|
||||
|
||||
import ly_test_tools.environment.process_utils as process_utils
|
||||
from typing import List
|
||||
|
||||
BOOTSTRAP_STACK_NAME = 'CDKToolkit'
|
||||
BOOTSTRAP_STAGING_BUCKET_LOGIC_ID = 'StagingBucket'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Cdk:
|
||||
"""
|
||||
Cdk class that provides methods to run cdk application commands.
|
||||
Expects system to have NodeJS, AWS CLI and CDK installed globally and have their paths setup as env variables.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._cdk_env = ''
|
||||
self._stacks = []
|
||||
self._cdk_path = os.path.dirname(os.path.realpath(__file__))
|
||||
self._session = ''
|
||||
|
||||
cdk_npm_latest_version_cmd = ['npm', 'view', 'aws-cdk', 'version']
|
||||
|
||||
output = process_utils.check_output(
|
||||
cdk_npm_latest_version_cmd,
|
||||
cwd=self._cdk_path,
|
||||
shell=True)
|
||||
cdk_npm_latest_version = output.split()[0]
|
||||
|
||||
cdk_version_cmd = ['cdk', 'version']
|
||||
output = process_utils.check_output(
|
||||
cdk_version_cmd,
|
||||
cwd=self._cdk_path,
|
||||
shell=True)
|
||||
cdk_version = output.split()[0]
|
||||
logger.info(f'Current CDK version {cdk_version}')
|
||||
|
||||
if cdk_version != cdk_npm_latest_version:
|
||||
try:
|
||||
logger.info(f'Updating CDK to latest')
|
||||
# uninstall and reinstall cdk in case npm has been updated.
|
||||
output = process_utils.check_output(
|
||||
'npm uninstall -g aws-cdk',
|
||||
cwd=self._cdk_path,
|
||||
shell=True)
|
||||
|
||||
logger.info(f'Uninstall CDK output: {output}')
|
||||
|
||||
output = process_utils.check_output(
|
||||
'npm install -g aws-cdk@latest',
|
||||
cwd=self._cdk_path,
|
||||
shell=True)
|
||||
|
||||
logger.info(f'Install CDK output: {output}')
|
||||
except subprocess.CalledProcessError as error:
|
||||
logger.warning(f'Failed reinstalling latest CDK on npm'
|
||||
f'\nError:{error.stderr}')
|
||||
|
||||
def setup(self, cdk_path: str, project: str, account_id: str,
|
||||
workspace: pytest.fixture, session: boto3.session.Session):
|
||||
"""
|
||||
:param cdk_path: Path where cdk app.py is stored.
|
||||
:param project: Project name used for cdk project name env variable.
|
||||
:param account_id: AWS account id to use with cdk application.
|
||||
:param workspace: ly_test_tools workspace fixture.
|
||||
:param session: Current boto3 session, provides credentials and region.
|
||||
"""
|
||||
self._cdk_env = os.environ.copy()
|
||||
unique_id = uuid.uuid4().hex[-4:]
|
||||
self._cdk_env['O3DE_AWS_PROJECT_NAME'] = project[:4] + unique_id if len(project) > 4 else project + unique_id
|
||||
self._cdk_env['O3DE_AWS_DEPLOY_REGION'] = session.region_name
|
||||
self._cdk_env['O3DE_AWS_DEPLOY_ACCOUNT'] = account_id
|
||||
self._cdk_env['PATH'] = f'{workspace.paths.engine_root()}\\python;' + self._cdk_env['PATH']
|
||||
|
||||
credentials = session.get_credentials().get_frozen_credentials()
|
||||
self._cdk_env['AWS_ACCESS_KEY_ID'] = credentials.access_key
|
||||
self._cdk_env['AWS_SECRET_ACCESS_KEY'] = credentials.secret_key
|
||||
self._cdk_env['AWS_SESSION_TOKEN'] = credentials.token
|
||||
self._cdk_path = cdk_path
|
||||
|
||||
self._session = session
|
||||
|
||||
output = process_utils.check_output(
|
||||
'python -m pip install -r requirements.txt',
|
||||
cwd=self._cdk_path,
|
||||
env=self._cdk_env,
|
||||
shell=True)
|
||||
|
||||
logger.info(f'Installing cdk python dependencies: {output}')
|
||||
|
||||
self.bootstrap()
|
||||
|
||||
def bootstrap(self) -> None:
|
||||
"""
|
||||
Deploy the bootstrap stack.
|
||||
"""
|
||||
try:
|
||||
bootstrap_cmd = ['cdk', 'bootstrap',
|
||||
f'aws://{self._cdk_env["O3DE_AWS_DEPLOY_ACCOUNT"]}/{self._cdk_env["O3DE_AWS_DEPLOY_REGION"]}']
|
||||
|
||||
process_utils.check_call(
|
||||
bootstrap_cmd,
|
||||
cwd=self._cdk_path,
|
||||
env=self._cdk_env,
|
||||
shell=True)
|
||||
except botocore.exceptions.ClientError as clientError:
|
||||
logger.warning(f'Failed creating Bootstrap stack {BOOTSTRAP_STACK_NAME} not found. '
|
||||
f'\nError:{clientError["Error"]["Message"]}')
|
||||
|
||||
def list(self, deployment_params: List[str] = None) -> List[str]:
|
||||
"""
|
||||
lists cdk stack names.
|
||||
:param deployment_params: Deployment parameters like --all can be passed in this way.
|
||||
:return List of cdk stack names.
|
||||
"""
|
||||
if not self._cdk_path:
|
||||
return []
|
||||
|
||||
list_cdk_application_cmd = ['cdk', 'list']
|
||||
if deployment_params:
|
||||
list_cdk_application_cmd.extend(deployment_params)
|
||||
|
||||
output = process_utils.check_output(
|
||||
list_cdk_application_cmd,
|
||||
cwd=self._cdk_path,
|
||||
env=self._cdk_env,
|
||||
shell=True)
|
||||
|
||||
return output.splitlines()
|
||||
|
||||
def synthesize(self, deployment_params: List[str] = None) -> None:
|
||||
"""
|
||||
Synthesizes all cdk stacks.
|
||||
:param deployment_params: Deployment parameters like --all can be passed in this way.
|
||||
"""
|
||||
if not self._cdk_path:
|
||||
return
|
||||
|
||||
synth_cdk_application_cmd = ['cdk', 'synth']
|
||||
if deployment_params:
|
||||
synth_cdk_application_cmd.extend(deployment_params)
|
||||
|
||||
process_utils.check_output(
|
||||
synth_cdk_application_cmd,
|
||||
cwd=self._cdk_path,
|
||||
env=self._cdk_env,
|
||||
shell=True)
|
||||
|
||||
def deploy(self, deployment_params: List[str] = None) -> List[str]:
|
||||
"""
|
||||
Deploys all the CDK stacks.
|
||||
:param deployment_params: Deployment parameters like --all can be passed in this way.
|
||||
:return List of deployed stack arns.
|
||||
"""
|
||||
if not self._cdk_path:
|
||||
return []
|
||||
|
||||
deploy_cdk_application_cmd = ['cdk', 'deploy', '--require-approval', 'never']
|
||||
if deployment_params:
|
||||
deploy_cdk_application_cmd.extend(deployment_params)
|
||||
|
||||
output = process_utils.check_output(
|
||||
deploy_cdk_application_cmd,
|
||||
cwd=self._cdk_path,
|
||||
env=self._cdk_env,
|
||||
shell=True)
|
||||
|
||||
for line in output.splitlines():
|
||||
line_sections = line.split('/')
|
||||
assert len(line_sections), 3
|
||||
self._stacks.append(line.split('/')[-2])
|
||||
|
||||
return self._stacks
|
||||
|
||||
def destroy(self, deployment_params: List[str] = None) -> None:
|
||||
"""
|
||||
Destroys the cdk application.
|
||||
:param deployment_params: Deployment parameters like --all can be passed in this way.
|
||||
"""
|
||||
|
||||
logger.info(f'CDK Path {self._cdk_path}')
|
||||
destroy_cdk_application_cmd = ['cdk', 'destroy', '-f']
|
||||
if deployment_params:
|
||||
destroy_cdk_application_cmd.extend(deployment_params)
|
||||
|
||||
try:
|
||||
process_utils.check_output(
|
||||
destroy_cdk_application_cmd,
|
||||
cwd=self._cdk_path,
|
||||
env=self._cdk_env,
|
||||
shell=True)
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
logger.error(e.output)
|
||||
raise e
|
||||
|
||||
self._stacks = []
|
||||
|
||||
def remove_bootstrap_stack(self) -> None:
|
||||
"""
|
||||
Remove the CDK bootstrap stack.
|
||||
:param aws_utils: aws_utils fixture.
|
||||
"""
|
||||
# Check if the bootstrap stack exists.
|
||||
response = self._session.client('cloudformation').describe_stacks(
|
||||
StackName=BOOTSTRAP_STACK_NAME
|
||||
)
|
||||
stacks = response.get('Stacks', [])
|
||||
if not stacks or len(stacks) is 0:
|
||||
return
|
||||
|
||||
# Clear the bootstrap staging bucket before deleting the bootstrap stack.
|
||||
response = self._session.client('cloudformation').describe_stack_resource(
|
||||
StackName=BOOTSTRAP_STACK_NAME,
|
||||
LogicalResourceId=BOOTSTRAP_STAGING_BUCKET_LOGIC_ID
|
||||
)
|
||||
|
||||
staging_bucket_name = response.get('StackResourceDetail', {}).get('PhysicalResourceId', '')
|
||||
if staging_bucket_name:
|
||||
s3 = self._session.resource('s3')
|
||||
bucket = s3.Bucket(staging_bucket_name)
|
||||
for key in bucket.objects.all():
|
||||
key.delete()
|
||||
|
||||
# Delete the bootstrap stack.
|
||||
# Should not need to delete the stack if S3 bucket can be cleaned.
|
||||
# self._session.client('cloudformation').delete_stack(
|
||||
# StackName=BOOTSTRAP_STACK_NAME
|
||||
# )
|
||||
|
||||
@property
|
||||
def stacks(self):
|
||||
return self._stacks
|
||||
+33
-28
@@ -4,45 +4,42 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
import pytest
|
||||
import os
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pytest
|
||||
|
||||
import ly_test_tools.log.log_monitor
|
||||
|
||||
from AWS.common import constants
|
||||
|
||||
# fixture imports
|
||||
from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor
|
||||
|
||||
AWS_PROJECT_NAME = 'AWS-AutomationTest'
|
||||
AWS_CLIENT_AUTH_FEATURE_NAME = 'AWSClientAuth'
|
||||
AWS_CLIENT_AUTH_DEFAULT_PROFILE_NAME = 'default'
|
||||
|
||||
GAME_LOG_NAME = 'Game.log'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@pytest.mark.SUITE_periodic
|
||||
@pytest.mark.usefixtures('automatic_process_killer')
|
||||
@pytest.mark.usefixtures('asset_processor')
|
||||
@pytest.mark.usefixtures('workspace')
|
||||
@pytest.mark.parametrize('project', ['AutomatedTesting'])
|
||||
@pytest.mark.usefixtures('cdk')
|
||||
@pytest.mark.parametrize('feature_name', [AWS_CLIENT_AUTH_FEATURE_NAME])
|
||||
@pytest.mark.usefixtures('resource_mappings')
|
||||
@pytest.mark.parametrize('resource_mappings_filename', ['default_aws_resource_mappings.json'])
|
||||
@pytest.mark.usefixtures('automatic_process_killer')
|
||||
@pytest.mark.usefixtures('aws_utils')
|
||||
@pytest.mark.parametrize('region_name', ['us-west-2'])
|
||||
@pytest.mark.parametrize('assume_role_arn', ['arn:aws:iam::645075835648:role/o3de-automation-tests'])
|
||||
@pytest.mark.parametrize('session_name', ['o3de-Automation-session'])
|
||||
@pytest.mark.usefixtures('cdk')
|
||||
@pytest.mark.parametrize('deployment_params', [[]])
|
||||
@pytest.mark.usefixtures('workspace')
|
||||
@pytest.mark.parametrize('assume_role_arn', [constants.ASSUME_ROLE_ARN])
|
||||
@pytest.mark.parametrize('feature_name', [AWS_CLIENT_AUTH_FEATURE_NAME])
|
||||
@pytest.mark.parametrize('project', ['AutomatedTesting'])
|
||||
@pytest.mark.usefixtures('resource_mappings')
|
||||
@pytest.mark.parametrize('resource_mappings_filename', [constants.AWS_RESOURCE_MAPPING_FILE_NAME])
|
||||
@pytest.mark.parametrize('region_name', [constants.AWS_REGION])
|
||||
@pytest.mark.parametrize('session_name', [constants.SESSION_NAME])
|
||||
@pytest.mark.parametrize('stacks', [[f'{constants.AWS_PROJECT_NAME}-{AWS_CLIENT_AUTH_FEATURE_NAME}-Stack-{constants.AWS_REGION}']])
|
||||
class TestAWSClientAuthWindows(object):
|
||||
"""
|
||||
Test class to verify AWS Client Auth gem features on Windows.
|
||||
"""
|
||||
|
||||
@pytest.mark.parametrize('level', ['AWS/ClientAuth'])
|
||||
@pytest.mark.parametrize('destroy_stacks_on_teardown', [False])
|
||||
def test_anonymous_credentials(self,
|
||||
level: str,
|
||||
launcher: pytest.fixture,
|
||||
@@ -53,14 +50,14 @@ class TestAWSClientAuthWindows(object):
|
||||
"""
|
||||
Test to verify AWS Cognito Identity pool anonymous authorization.
|
||||
|
||||
Setup: Deploys cdk and updates resource mapping file.
|
||||
Setup: Updates resource mapping file using existing CloudFormation stacks.
|
||||
Tests: Getting credentials when no credentials are configured
|
||||
Verification: Log monitor looks for success credentials log.
|
||||
"""
|
||||
asset_processor.start()
|
||||
asset_processor.wait_for_idle()
|
||||
|
||||
file_to_monitor = os.path.join(launcher.workspace.paths.project_log(), GAME_LOG_NAME)
|
||||
file_to_monitor = os.path.join(launcher.workspace.paths.project_log(), constants.GAME_LOG_NAME)
|
||||
log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=launcher, log_file_path=file_to_monitor)
|
||||
|
||||
launcher.args = ['+LoadLevel', level]
|
||||
@@ -74,10 +71,8 @@ class TestAWSClientAuthWindows(object):
|
||||
)
|
||||
assert result, 'Anonymous credentials fetched successfully.'
|
||||
|
||||
@pytest.mark.parametrize('destroy_stacks_on_teardown', [True])
|
||||
def test_password_signin_credentials(self,
|
||||
launcher: pytest.fixture,
|
||||
cdk: pytest.fixture,
|
||||
resource_mappings: pytest.fixture,
|
||||
workspace: pytest.fixture,
|
||||
asset_processor: pytest.fixture,
|
||||
@@ -86,16 +81,29 @@ class TestAWSClientAuthWindows(object):
|
||||
"""
|
||||
Test to verify AWS Cognito IDP Password sign in and Cognito Identity pool authenticated authorization.
|
||||
|
||||
Setup: Deploys cdk and updates resource mapping file.
|
||||
Setup: Updates resource mapping file using existing CloudFormation stacks.
|
||||
Tests: Sign up new test user, admin confirm the user, sign in and get aws credentials.
|
||||
Verification: Log monitor looks for success credentials log.
|
||||
"""
|
||||
asset_processor.start()
|
||||
asset_processor.wait_for_idle()
|
||||
|
||||
file_to_monitor = os.path.join(launcher.workspace.paths.project_log(), GAME_LOG_NAME)
|
||||
file_to_monitor = os.path.join(launcher.workspace.paths.project_log(), constants.GAME_LOG_NAME)
|
||||
log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=launcher, log_file_path=file_to_monitor)
|
||||
|
||||
cognito_idp = aws_utils.client('cognito-idp')
|
||||
user_pool_id = resource_mappings.get_resource_name_id(f'{AWS_CLIENT_AUTH_FEATURE_NAME}.CognitoUserPoolId')
|
||||
logger.info(f'UserPoolId:{user_pool_id}')
|
||||
|
||||
# Remove the user if already exists
|
||||
try:
|
||||
cognito_idp.admin_delete_user(
|
||||
UserPoolId=user_pool_id,
|
||||
Username='test1'
|
||||
)
|
||||
except cognito_idp.exceptions.UserNotFoundException:
|
||||
pass
|
||||
|
||||
launcher.args = ['+LoadLevel', 'AWS/ClientAuthPasswordSignUp']
|
||||
launcher.args.extend(['-rhi=null'])
|
||||
|
||||
@@ -109,9 +117,6 @@ class TestAWSClientAuthWindows(object):
|
||||
|
||||
launcher.stop()
|
||||
|
||||
cognito_idp = aws_utils.client('cognito-idp')
|
||||
user_pool_id = resource_mappings.get_resource_name_id(f'{AWS_CLIENT_AUTH_FEATURE_NAME}.CognitoUserPoolId')
|
||||
print(f'UserPoolId:{user_pool_id}')
|
||||
cognito_idp.admin_confirm_sign_up(
|
||||
UserPoolId=user_pool_id,
|
||||
Username='test1'
|
||||
|
||||
+15
-17
@@ -5,10 +5,11 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import logging
|
||||
import typing
|
||||
import os
|
||||
import shutil
|
||||
import typing
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
import pytest
|
||||
import ly_test_tools
|
||||
@@ -16,16 +17,15 @@ import ly_test_tools.log.log_monitor
|
||||
import ly_test_tools.environment.process_utils as process_utils
|
||||
import ly_test_tools.o3de.asset_processor_utils as asset_processor_utils
|
||||
|
||||
from botocore.exceptions import ClientError
|
||||
from AWS.common import constants
|
||||
|
||||
# fixture imports
|
||||
from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor
|
||||
|
||||
AWS_CORE_FEATURE_NAME = 'AWSCore'
|
||||
AWS_RESOURCE_MAPPING_FILE_NAME = 'default_aws_resource_mappings.json'
|
||||
|
||||
process_utils.kill_processes_named("o3de", ignore_extensions=True) # Kill ProjectManager windows
|
||||
|
||||
GAME_LOG_NAME = 'Game.log'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ def setup(launcher: pytest.fixture, asset_processor: pytest.fixture) -> typing.T
|
||||
asset_processor.start()
|
||||
asset_processor.wait_for_idle()
|
||||
|
||||
file_to_monitor = os.path.join(launcher.workspace.paths.project_log(), GAME_LOG_NAME)
|
||||
file_to_monitor = os.path.join(launcher.workspace.paths.project_log(), constants.GAME_LOG_NAME)
|
||||
log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=launcher, log_file_path=file_to_monitor)
|
||||
|
||||
return log_monitor, s3_download_dir
|
||||
@@ -58,7 +58,7 @@ def write_test_data_to_dynamodb_table(resource_mappings: pytest.fixture, aws_uti
|
||||
:param resource_mappings: resource_mappings fixture.
|
||||
:param aws_utils: aws_utils fixture.
|
||||
"""
|
||||
table_name = resource_mappings.get_resource_name_id("AWSCore.ExampleDynamoTableOutput")
|
||||
table_name = resource_mappings.get_resource_name_id(f'{AWS_CORE_FEATURE_NAME}.ExampleDynamoTableOutput')
|
||||
try:
|
||||
aws_utils.client('dynamodb').put_item(
|
||||
TableName=table_name,
|
||||
@@ -77,21 +77,19 @@ def write_test_data_to_dynamodb_table(resource_mappings: pytest.fixture, aws_uti
|
||||
@pytest.mark.SUITE_periodic
|
||||
@pytest.mark.usefixtures('automatic_process_killer')
|
||||
@pytest.mark.usefixtures('asset_processor')
|
||||
@pytest.mark.usefixtures('cdk')
|
||||
@pytest.mark.parametrize('feature_name', [AWS_CORE_FEATURE_NAME])
|
||||
@pytest.mark.parametrize('region_name', ['us-west-2'])
|
||||
@pytest.mark.parametrize('assume_role_arn', ['arn:aws:iam::645075835648:role/o3de-automation-tests'])
|
||||
@pytest.mark.parametrize('session_name', ['o3de-Automation-session'])
|
||||
@pytest.mark.parametrize('region_name', [constants.AWS_REGION])
|
||||
@pytest.mark.parametrize('assume_role_arn', [constants.ASSUME_ROLE_ARN])
|
||||
@pytest.mark.parametrize('session_name', [constants.SESSION_NAME])
|
||||
@pytest.mark.usefixtures('workspace')
|
||||
@pytest.mark.parametrize('project', ['AutomatedTesting'])
|
||||
@pytest.mark.parametrize('level', ['AWS/Core'])
|
||||
@pytest.mark.usefixtures('resource_mappings')
|
||||
@pytest.mark.parametrize('resource_mappings_filename', [AWS_RESOURCE_MAPPING_FILE_NAME])
|
||||
@pytest.mark.parametrize('resource_mappings_filename', [constants.AWS_RESOURCE_MAPPING_FILE_NAME])
|
||||
@pytest.mark.parametrize('stacks', [[f'{constants.AWS_PROJECT_NAME}-{AWS_CORE_FEATURE_NAME}',
|
||||
f'{constants.AWS_PROJECT_NAME}-{AWS_CORE_FEATURE_NAME}-Example-{constants.AWS_REGION}']])
|
||||
@pytest.mark.usefixtures('aws_credentials')
|
||||
@pytest.mark.parametrize('profile_name', ['AWSAutomationTest'])
|
||||
@pytest.mark.usefixtures('cdk')
|
||||
@pytest.mark.parametrize('deployment_params', [['--all']])
|
||||
@pytest.mark.parametrize('destroy_stacks_on_teardown', [True])
|
||||
class TestAWSCoreAWSResourceInteraction(object):
|
||||
"""
|
||||
Test class to verify the scripting behavior for the AWSCore gem.
|
||||
@@ -119,7 +117,7 @@ class TestAWSCoreAWSResourceInteraction(object):
|
||||
expected_lines: typing.List[str],
|
||||
unexpected_lines: typing.List[str]):
|
||||
"""
|
||||
Setup: Deploys cdk and updates resource mapping file.
|
||||
Setup: Updates resource mapping file using existing CloudFormation stacks.
|
||||
Tests: Interact with AWS S3, DynamoDB and Lambda services.
|
||||
Verification: Script canvas nodes can communicate with AWS services successfully.
|
||||
"""
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
@@ -0,0 +1,19 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
# ARN of the IAM role to assume for retrieving temporary AWS credentials
|
||||
ASSUME_ROLE_ARN = 'arn:aws:iam::645075835648:role/o3de-automation-tests'
|
||||
# Name of the AWS project deployed by the CDK applications
|
||||
AWS_PROJECT_NAME = 'AWSAUTO'
|
||||
# Region for the existing CloudFormation stacks used by the automation tests
|
||||
AWS_REGION = 'us-east-1'
|
||||
# Name of the default resource mapping config file used by the automation tests
|
||||
AWS_RESOURCE_MAPPING_FILE_NAME = 'default_aws_resource_mappings.json'
|
||||
# Name of the game launcher log
|
||||
GAME_LOG_NAME = 'Game.log'
|
||||
# Name of the IAM role session for retrieving temporary AWS credentials
|
||||
SESSION_NAME = 'o3de-Automation-session'
|
||||
+5
-9
@@ -6,9 +6,9 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import pytest
|
||||
import json
|
||||
import logging
|
||||
from AWS.common import constants
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -22,18 +22,14 @@ class ResourceMappings:
|
||||
ResourceMappings class that handles writing Cloud formation outputs to resource mappings json file in a project.
|
||||
"""
|
||||
|
||||
def __init__(self, file_path: str, region: str, feature_name: str, account_id: str, workspace: pytest.fixture,
|
||||
cloud_formation_client):
|
||||
def __init__(self, file_path: str, region: str, feature_name: str, account_id: str, cloud_formation_client):
|
||||
"""
|
||||
:param file_path: Path for the resource mapping file.
|
||||
:param region: Region value for the resource mapping file.
|
||||
:param feature_name: Feature gem name to use to append name to mappings key.
|
||||
:param account_id: AWS account id value for the resource mapping file.
|
||||
:param workspace: ly_test_tools workspace fixture.
|
||||
:param cloud_formation_client: AWS cloud formation client.
|
||||
"""
|
||||
self._cdk_env = os.environ.copy()
|
||||
self._cdk_env['PATH'] = f'{workspace.paths.engine_root()}\\python;' + self._cdk_env['PATH']
|
||||
self._resource_mapping_file_path = file_path
|
||||
self._region = region
|
||||
self._feature_name = feature_name
|
||||
@@ -44,7 +40,7 @@ class ResourceMappings:
|
||||
f'Invalid resource mapping file path {self._resource_mapping_file_path}'
|
||||
self._client = cloud_formation_client
|
||||
|
||||
def populate_output_keys(self, stacks=[]) -> None:
|
||||
def populate_output_keys(self, stacks=None) -> None:
|
||||
"""
|
||||
Calls describe stacks on cloud formation service and persists outputs to resource mappings file.
|
||||
:param stacks List of stack arns to describe and populate resource mappings with.
|
||||
@@ -58,7 +54,7 @@ class ResourceMappings:
|
||||
|
||||
self._write_resource_mappings(stacks[0].get('Outputs', []))
|
||||
|
||||
def _write_resource_mappings(self, outputs, append_feature_name = True) -> None:
|
||||
def _write_resource_mappings(self, outputs, append_feature_name=True) -> None:
|
||||
with open(self._resource_mapping_file_path) as file_content:
|
||||
resource_mappings = json.load(file_content)
|
||||
|
||||
@@ -91,7 +87,7 @@ class ResourceMappings:
|
||||
resource_mappings = json.load(file_content)
|
||||
|
||||
resource_mappings[AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY] = ''
|
||||
resource_mappings[AWS_RESOURCE_MAPPINGS_REGION_KEY] = 'us-west-2'
|
||||
resource_mappings[AWS_RESOURCE_MAPPINGS_REGION_KEY] = constants.AWS_REGION
|
||||
|
||||
# Append new mappings.
|
||||
resource_mappings[AWS_RESOURCE_MAPPINGS_KEY] = resource_mappings.get(AWS_RESOURCE_MAPPINGS_KEY, {})
|
||||
@@ -11,8 +11,7 @@ import typing
|
||||
|
||||
from AWS.common.aws_utils import AwsUtils
|
||||
from AWS.common.aws_credentials import AwsCredentials
|
||||
from AWS.Windows.cdk.cdk_utils import Cdk
|
||||
from AWS.Windows.resource_mappings.resource_mappings import ResourceMappings
|
||||
from AWS.common.resource_mappings import ResourceMappings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -52,6 +51,7 @@ def resource_mappings(
|
||||
project: str,
|
||||
feature_name: str,
|
||||
resource_mappings_filename: str,
|
||||
stacks: typing.List,
|
||||
workspace: pytest.fixture,
|
||||
aws_utils: pytest.fixture) -> ResourceMappings:
|
||||
"""
|
||||
@@ -61,6 +61,7 @@ def resource_mappings(
|
||||
:param project: Project to find resource mapping file.
|
||||
:param feature_name: AWS Gem name that is prepended to resource mapping keys.
|
||||
:param resource_mappings_filename: Name of resource mapping file.
|
||||
:param stacks: List of stack names to describe and populate resource mappings with.
|
||||
:param workspace: ly_test_tools workspace fixture.
|
||||
:param aws_utils: AWS utils fixture.
|
||||
:return: ResourceMappings class object.
|
||||
@@ -70,8 +71,8 @@ def resource_mappings(
|
||||
logger.info(f'Resource mapping path : {path}')
|
||||
logger.info(f'Resource mapping resolved path : {abspath(path)}')
|
||||
resource_mappings_obj = ResourceMappings(abspath(path), aws_utils.assume_session().region_name, feature_name,
|
||||
aws_utils.assume_account_id(), workspace,
|
||||
aws_utils.client('cloudformation'))
|
||||
aws_utils.assume_account_id(), aws_utils.client('cloudformation'))
|
||||
resource_mappings_obj.populate_output_keys(stacks)
|
||||
|
||||
def teardown():
|
||||
resource_mappings_obj.clear_output_keys()
|
||||
@@ -81,56 +82,6 @@ def resource_mappings(
|
||||
return resource_mappings_obj
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def cdk(
|
||||
request: pytest.fixture,
|
||||
project: str,
|
||||
feature_name: str,
|
||||
workspace: pytest.fixture,
|
||||
aws_utils: pytest.fixture,
|
||||
resource_mappings: pytest.fixture,
|
||||
deployment_params: typing.List[str],
|
||||
destroy_stacks_on_teardown: bool) -> Cdk:
|
||||
"""
|
||||
Fixture for setting up a Cdk
|
||||
:param request: _pytest.fixtures.SubRequest class that handles getting
|
||||
a pytest fixture from a pytest function/fixture.
|
||||
:param project: Project name used for cdk project name env variable.
|
||||
:param feature_name: Feature gem name to expect cdk folder in.
|
||||
:param workspace: ly_test_tools workspace fixture.
|
||||
:param aws_utils: aws_utils fixture.
|
||||
:param resource_mappings: resource_mappings fixture.
|
||||
:param deployment_params: Parameters for the CDK application deployment.
|
||||
:param destroy_stacks_on_teardown: option to control calling destroy ot the end of test.
|
||||
:return Cdk class object.
|
||||
"""
|
||||
|
||||
cdk_path = f'{workspace.paths.engine_root()}/Gems/{feature_name}/cdk'
|
||||
logger.info(f'CDK Path {cdk_path}')
|
||||
|
||||
if pytest.cdk_obj is None:
|
||||
pytest.cdk_obj = Cdk()
|
||||
pytest.cdk_obj.setup(cdk_path, project, aws_utils.assume_account_id(), workspace, aws_utils.assume_session())
|
||||
|
||||
stacks = pytest.cdk_obj.deploy(deployment_params=deployment_params)
|
||||
|
||||
logger.info(f'Cdk stack names:\n{stacks}')
|
||||
resource_mappings.populate_output_keys(stacks)
|
||||
|
||||
def teardown():
|
||||
if destroy_stacks_on_teardown:
|
||||
pytest.cdk_obj.destroy(deployment_params=deployment_params)
|
||||
# Enable after https://github.com/aws/aws-cdk/issues/986 is fixed.
|
||||
# Until then clean the bootstrap bucket manually.
|
||||
# pytest.cdk_obj.remove_bootstrap_stack()
|
||||
|
||||
pytest.cdk_obj = None
|
||||
|
||||
request.addfinalizer(teardown)
|
||||
|
||||
return pytest.cdk_obj
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def aws_credentials(request: pytest.fixture, aws_utils: pytest.fixture, profile_name: str):
|
||||
"""
|
||||
|
||||
@@ -12,7 +12,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL TRUE
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Active.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
|
||||
@@ -8,7 +8,7 @@ INTRODUCTION
|
||||
------------
|
||||
|
||||
EditorPythonBindings is a Python project that contains a collection of editor testing tools
|
||||
developed by the Lumberyard feature teams. The project contains tools for system level
|
||||
developed by the O3DE feature teams. The project contains tools for system level
|
||||
editor tests.
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ installed on your system.
|
||||
|
||||
INSTALL
|
||||
-----------
|
||||
It is recommended to set up these these tools with Lumberyard's CMake build commands.
|
||||
It is recommended to set up these these tools with O3DE's CMake build commands.
|
||||
Assuming CMake is already setup on your operating system, below are some sample build commands:
|
||||
cd /path/to/od3e/
|
||||
mkdir windows_vs2019
|
||||
|
||||
+30
@@ -8,6 +8,7 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.object
|
||||
|
||||
from typing import List
|
||||
@@ -428,3 +429,32 @@ def get_component_type_id_map(component_name_list):
|
||||
type_ids_by_component[component_names[i]] = typeId
|
||||
|
||||
return type_ids_by_component
|
||||
|
||||
|
||||
def attach_component_to_entity(entity_id, component_name):
|
||||
# type: (azlmbr.entity.EntityId, str) -> azlmbr.entity.EntityComponentIdPair
|
||||
"""
|
||||
Adds the component if not added already.
|
||||
:param entity_id: EntityId of the entity to attach the component to
|
||||
:param component_name: name of the component
|
||||
:return: If successful, returns the EntityComponentIdPair, otherwise returns None.
|
||||
"""
|
||||
type_ids_list = editor.EditorComponentAPIBus(
|
||||
bus.Broadcast, 'FindComponentTypeIdsByEntityType', [component_name], 0)
|
||||
general.log(f"Components found = {len(type_ids_list)}")
|
||||
if len(type_ids_list) < 1:
|
||||
general.log(f"ERROR: A component class with name {component_name} doesn't exist")
|
||||
return None
|
||||
elif len(type_ids_list) > 1:
|
||||
general.log(f"ERROR: Found more than one component classes with same name: {component_name}")
|
||||
return None
|
||||
# Before adding the component let's check if it is already attached to the entity.
|
||||
component_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', entity_id, type_ids_list[0])
|
||||
if component_outcome.IsSuccess():
|
||||
return component_outcome.GetValue() # In this case the value is not a list.
|
||||
component_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entity_id, type_ids_list)
|
||||
if component_outcome.IsSuccess():
|
||||
general.log(f"{component_name} Component added to entity.")
|
||||
return component_outcome.GetValue()[0]
|
||||
general.log(f"ERROR: Failed to add component [{component_name}] to entity")
|
||||
return None
|
||||
|
||||
+13
-2
@@ -29,7 +29,7 @@ def teardown_editor(editor):
|
||||
|
||||
def launch_and_validate_results(request, test_directory, editor, editor_script, expected_lines, unexpected_lines=[],
|
||||
halt_on_unexpected=False, run_python="--runpythontest", auto_test_mode=True, null_renderer=True, cfg_args=[],
|
||||
timeout=300):
|
||||
timeout=300, log_file_name="Editor.log"):
|
||||
"""
|
||||
Runs the Editor with the specified script, and monitors for expected log lines.
|
||||
:param request: Special fixture providing information of the requesting test function.
|
||||
@@ -44,6 +44,7 @@ def launch_and_validate_results(request, test_directory, editor, editor_script,
|
||||
:param null_renderer: Specifies the test does not require the renderer. Defaults to True.
|
||||
:param cfg_args: Additional arguments for CFG, such as LevelName.
|
||||
:param timeout: Length of time for test to run. Default is 60.
|
||||
:param log_file_name: Name of the log file created by the editor. Defaults to 'Editor.log'
|
||||
"""
|
||||
test_case = os.path.join(test_directory, editor_script)
|
||||
request.addfinalizer(lambda: teardown_editor(editor))
|
||||
@@ -58,7 +59,17 @@ def launch_and_validate_results(request, test_directory, editor, editor_script,
|
||||
|
||||
with editor.start():
|
||||
|
||||
editorlog_file = os.path.join(editor.workspace.paths.project_log(), 'Editor.log')
|
||||
editorlog_file = os.path.join(editor.workspace.paths.project_log(), log_file_name)
|
||||
|
||||
# Log monitor requires the file to exist.
|
||||
logger.debug(f"Waiting until log file <{editorlog_file}> exists...")
|
||||
waiter.wait_for(
|
||||
lambda: os.path.exists(editorlog_file),
|
||||
timeout=60,
|
||||
exc=f"Log file '{editorlog_file}' was never created by another process.",
|
||||
interval=1,
|
||||
)
|
||||
logger.debug(f"Done! log file <{editorlog_file}> exists.")
|
||||
|
||||
# Initialize the log monitor and set time to wait for log creation
|
||||
log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=editor, log_file_path=editorlog_file)
|
||||
|
||||
@@ -13,7 +13,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_REQUIRES gpu
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Active.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
|
||||
@@ -27,19 +27,19 @@ class TestPythonAssetProcessing(object):
|
||||
unexpected_lines = []
|
||||
expected_lines = [
|
||||
'Mock asset exists',
|
||||
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive.azmodel) found',
|
||||
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative.azmodel) found',
|
||||
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive.azmodel) found',
|
||||
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative.azmodel) found',
|
||||
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive.azmodel) found',
|
||||
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative.azmodel) found',
|
||||
'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found'
|
||||
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel) found',
|
||||
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel) found',
|
||||
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel) found',
|
||||
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel) found',
|
||||
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel) found',
|
||||
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel) found',
|
||||
'AssetId found for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel) found'
|
||||
]
|
||||
timeout = 180
|
||||
halt_on_unexpected = False
|
||||
test_directory = os.path.join(os.path.dirname(__file__))
|
||||
testFile = os.path.join(test_directory, 'AssetBuilder_test_case.py')
|
||||
editor.args.extend(['-NullRenderer', "--skipWelcomeScreenDialog", "--autotest_mode", "--runpythontest", testFile])
|
||||
editor.args.extend(['-NullRenderer', '-rhi=Null', "--skipWelcomeScreenDialog", "--autotest_mode", "--runpythontest", testFile])
|
||||
|
||||
with editor.start():
|
||||
editorlog_file = os.path.join(editor.workspace.paths.project_log(), 'Editor.log')
|
||||
|
||||
@@ -29,21 +29,21 @@ if (assetIdString.endswith(':528cca58') is False):
|
||||
print ('Mock asset exists')
|
||||
|
||||
# These tests detect if the geom_group.fbx file turns into a number of azmodel product assets
|
||||
def test_azmodel_product(generatedModelAssetPath, expectedSubId):
|
||||
def test_azmodel_product(generatedModelAssetPath):
|
||||
azModelAssetType = azlmbr.math.Uuid_CreateString('{2C7477B6-69C5-45BE-8163-BCD6A275B6D8}', 0)
|
||||
assetId = azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, 'GetAssetIdByPath', generatedModelAssetPath, azModelAssetType, False)
|
||||
assetIdString = assetId.to_string()
|
||||
if (assetIdString.endswith(':' + expectedSubId) is False):
|
||||
raise_and_stop(f'Asset at path {generatedModelAssetPath} has unexpected asset ID ({assetIdString}) for ({generatedModelAssetPath}), expected {expectedSubId}!')
|
||||
if (assetId.is_valid()):
|
||||
print(f'AssetId found for asset ({generatedModelAssetPath}) found')
|
||||
else:
|
||||
print(f'Expected subId for asset ({generatedModelAssetPath}) found')
|
||||
raise_and_stop(f'Asset at path {generatedModelAssetPath} has unexpected asset ID ({assetIdString})!')
|
||||
|
||||
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive.azmodel', '1024be55')
|
||||
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative.azmodel', '1052c94e')
|
||||
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive.azmodel', '10130556')
|
||||
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative.azmodel', '1065724d')
|
||||
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive.azmodel', '10d16e68')
|
||||
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative.azmodel', '10a71973')
|
||||
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel', '10412075')
|
||||
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel')
|
||||
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel')
|
||||
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel')
|
||||
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel')
|
||||
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel')
|
||||
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel')
|
||||
test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel')
|
||||
|
||||
azlmbr.editor.EditorToolsApplicationRequestBus(azlmbr.bus.Broadcast, 'ExitNoPrompt')
|
||||
|
||||
@@ -12,7 +12,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
|
||||
@@ -12,7 +12,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Active.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
|
||||
+11
-13
@@ -92,17 +92,17 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
AZ::AssetProcessor
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AssetPipelineTests.AssetBundler
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py
|
||||
EXCLUDE_TEST_RUN_TARGET_FROM_IDE
|
||||
TEST_SERIAL
|
||||
TIMEOUT 2400
|
||||
TEST_SUITE periodic
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
AZ::AssetBundlerBatch
|
||||
)
|
||||
# Issue #3017
|
||||
#ly_add_pytest(
|
||||
# NAME AssetPipelineTests.AssetBundler
|
||||
# PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py
|
||||
# EXCLUDE_TEST_RUN_TARGET_FROM_IDE
|
||||
# TEST_SERIAL
|
||||
# TEST_SUITE periodic
|
||||
# RUNTIME_DEPENDENCIES
|
||||
# AZ::AssetProcessor
|
||||
# AZ::AssetBundlerBatch
|
||||
#)
|
||||
|
||||
ly_add_pytest(
|
||||
NAME AssetPipelineTests.AssetBundler_SandBox
|
||||
@@ -111,7 +111,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
PYTEST_MARKS "SUITE_sandbox" # run only sandbox tests in this file
|
||||
EXCLUDE_TEST_RUN_TARGET_FROM_IDE
|
||||
TEST_SERIAL
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
AZ::AssetBundlerBatch
|
||||
@@ -133,7 +132,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/missing_dependency_tests.py
|
||||
EXCLUDE_TEST_RUN_TARGET_FROM_IDE
|
||||
TEST_SERIAL
|
||||
TIMEOUT 1500
|
||||
TEST_SUITE periodic
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessorBatch
|
||||
|
||||
@@ -39,7 +39,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedT
|
||||
TEST_SUITE main
|
||||
TEST_REQUIRES gpu
|
||||
TEST_SERIAL
|
||||
TIMEOUT 800
|
||||
TIMEOUT 1200
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/test_Atom_GPUTests.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
AssetProcessor
|
||||
|
||||
+2
-2
@@ -206,8 +206,8 @@ def run():
|
||||
# PostFX Layer Component
|
||||
ComponentTests("PostFX Layer")
|
||||
|
||||
# Radius Weight Modifier Component
|
||||
ComponentTests("Radius Weight Modifier")
|
||||
# PostFX Radius Weight Modifier Component
|
||||
ComponentTests("PostFX Radius Weight Modifier")
|
||||
|
||||
# Light Component
|
||||
ComponentTests("Light")
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ import azlmbr.legacy.general as general
|
||||
sys.path.append(os.path.join(azlmbr.paths.devassets, "Gem", "PythonTests"))
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from atom_renderer.atom_utils.atom_component_helper import LIGHT_TYPES
|
||||
from atom_renderer.atom_utils.atom_constants import LIGHT_TYPES
|
||||
|
||||
LIGHT_TYPE_PROPERTY = 'Controller|Configuration|Light type'
|
||||
SPHERE_AND_SPOT_DISK_LIGHT_PROPERTIES = [
|
||||
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
"""
|
||||
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 azlmbr.materialeditor will fail with a ModuleNotFound error when using this script with Editor.exe
|
||||
This is because azlmbr.materialeditor only binds to MaterialEditor.exe and not Editor.exe
|
||||
You need to launch this script with MaterialEditor.exe in order for azlmbr.materialeditor to appear.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devassets, "Gem", "PythonTests"))
|
||||
|
||||
import atom_renderer.atom_utils.material_editor_utils as material_editor
|
||||
|
||||
NEW_MATERIAL = "test_material.material"
|
||||
NEW_MATERIAL_1 = "test_material_1.material"
|
||||
NEW_MATERIAL_2 = "test_material_2.material"
|
||||
TEST_MATERIAL_1 = "001_DefaultWhite.material"
|
||||
TEST_MATERIAL_2 = "002_BaseColorLerp.material"
|
||||
TEST_MATERIAL_3 = "003_MetalMatte.material"
|
||||
TEST_DATA_PATH = os.path.join(
|
||||
azlmbr.paths.devroot, "Gems", "Atom", "TestData", "TestData", "Materials", "StandardPbrTestCases"
|
||||
)
|
||||
MATERIAL_TYPE_PATH = os.path.join(
|
||||
azlmbr.paths.devroot, "Gems", "Atom", "Feature", "Common", "Assets",
|
||||
"Materials", "Types", "StandardPBR.materialtype",
|
||||
)
|
||||
|
||||
|
||||
def run():
|
||||
"""
|
||||
Summary:
|
||||
Material Editor basic tests including the below
|
||||
1. Opening an Existing Asset
|
||||
2. Creating a New Asset
|
||||
3. Closing Selected Material
|
||||
4. Closing All Materials
|
||||
5. Closing all but Selected Material
|
||||
6. Saving Material
|
||||
7. Saving as a New Material
|
||||
8. Saving as a Child Material
|
||||
9. Saving all Open Materials
|
||||
|
||||
Expected Result:
|
||||
All the above functions work as expected in Material Editor.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
# 1) Test Case: Opening an Existing Asset
|
||||
document_id = material_editor.open_material(MATERIAL_TYPE_PATH)
|
||||
print(f"Material opened: {material_editor.is_open(document_id)}")
|
||||
|
||||
# Verify if the test material exists initially
|
||||
target_path = os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Materials", NEW_MATERIAL)
|
||||
print(f"Test asset doesn't exist initially: {not os.path.exists(target_path)}")
|
||||
|
||||
# 2) Test Case: Creating a New Material Using Existing One
|
||||
material_editor.save_document_as_child(document_id, target_path)
|
||||
material_editor.wait_for_condition(lambda: os.path.exists(target_path), 2.0)
|
||||
print(f"New asset created: {os.path.exists(target_path)}")
|
||||
|
||||
# Verify if the newly created document is open
|
||||
new_document_id = material_editor.open_material(target_path)
|
||||
material_editor.wait_for_condition(lambda: material_editor.is_open(new_document_id))
|
||||
print(f"New Material opened: {material_editor.is_open(new_document_id)}")
|
||||
|
||||
# 3) Test Case: Closing Selected Material
|
||||
print(f"Material closed: {material_editor.close_document(new_document_id)}")
|
||||
|
||||
# Open materials initially
|
||||
document1_id, document2_id, document3_id = (
|
||||
material_editor.open_material(os.path.join(TEST_DATA_PATH, material))
|
||||
for material in [TEST_MATERIAL_1, TEST_MATERIAL_2, TEST_MATERIAL_3]
|
||||
)
|
||||
|
||||
# 4) Test Case: Closing All Materials
|
||||
print(f"All documents closed: {material_editor.close_all_documents()}")
|
||||
|
||||
# 5) Test Case: Closing all but Selected Material
|
||||
document1_id, document2_id, document3_id = (
|
||||
material_editor.open_material(os.path.join(TEST_DATA_PATH, material))
|
||||
for material in [TEST_MATERIAL_1, TEST_MATERIAL_2, TEST_MATERIAL_3]
|
||||
)
|
||||
result = material_editor.close_all_except_selected(document1_id)
|
||||
print(f"Close All Except Selected worked as expected: {result and material_editor.is_open(document1_id)}")
|
||||
|
||||
# 6) Test Case: Saving Material
|
||||
document_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_1))
|
||||
property_name = azlmbr.name.Name("baseColor.color")
|
||||
initial_color = material_editor.get_property(document_id, property_name)
|
||||
# Assign new color to the material file and save the actual material
|
||||
expected_color = math.Color(0.25, 0.25, 0.25, 1.0)
|
||||
material_editor.set_property(document_id, property_name, expected_color)
|
||||
material_editor.save_document(document_id)
|
||||
|
||||
# 7) Test Case: Saving as a New Material
|
||||
# Assign new color to the material file and save the document as copy
|
||||
expected_color_1 = math.Color(0.5, 0.5, 0.5, 1.0)
|
||||
material_editor.set_property(document_id, property_name, expected_color_1)
|
||||
target_path_1 = os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Materials", NEW_MATERIAL_1)
|
||||
material_editor.save_document_as_copy(document_id, target_path_1)
|
||||
time.sleep(2.0)
|
||||
|
||||
# 8) Test Case: Saving as a Child Material
|
||||
# Assign new color to the material file save the document as child
|
||||
expected_color_2 = math.Color(0.75, 0.75, 0.75, 1.0)
|
||||
material_editor.set_property(document_id, property_name, expected_color_2)
|
||||
target_path_2 = os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Materials", NEW_MATERIAL_2)
|
||||
material_editor.save_document_as_child(document_id, target_path_2)
|
||||
time.sleep(2.0)
|
||||
|
||||
# Close/Reopen documents
|
||||
material_editor.close_all_documents()
|
||||
document_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_1))
|
||||
document1_id = material_editor.open_material(target_path_1)
|
||||
document2_id = material_editor.open_material(target_path_2)
|
||||
|
||||
# Verify if the changes are saved in the actual document
|
||||
actual_color = material_editor.get_property(document_id, property_name)
|
||||
print(f"Actual Document saved with changes: {material_editor.compare_colors(actual_color, expected_color)}")
|
||||
|
||||
# Verify if the changes are saved in the document saved as copy
|
||||
actual_color = material_editor.get_property(document1_id, property_name)
|
||||
result_copy = material_editor.compare_colors(actual_color, expected_color_1)
|
||||
print(f"Document saved as copy is saved with changes: {result_copy}")
|
||||
|
||||
# Verify if the changes are saved in the document saved as child
|
||||
actual_color = material_editor.get_property(document2_id, property_name)
|
||||
result_child = material_editor.compare_colors(actual_color, expected_color_2)
|
||||
print(f"Document saved as child is saved with changes: {result_child}")
|
||||
|
||||
# Revert back the changes in the actual document
|
||||
material_editor.set_property(document_id, property_name, initial_color)
|
||||
material_editor.save_document(document_id)
|
||||
material_editor.close_all_documents()
|
||||
|
||||
# 9) Test Case: Saving all Open Materials
|
||||
# Open first material and make change to the values
|
||||
document1_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_1))
|
||||
property1_name = azlmbr.name.Name("metallic.factor")
|
||||
initial_metallic_factor = material_editor.get_property(document1_id, property1_name)
|
||||
expected_metallic_factor = 0.444
|
||||
material_editor.set_property(document1_id, property1_name, expected_metallic_factor)
|
||||
|
||||
# Open second material and make change to the values
|
||||
document2_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_2))
|
||||
property2_name = azlmbr.name.Name("baseColor.color")
|
||||
initial_color = material_editor.get_property(document2_id, property2_name)
|
||||
expected_color = math.Color(0.4156, 0.0196, 0.6862, 1.0)
|
||||
material_editor.set_property(document2_id, property2_name, expected_color)
|
||||
|
||||
# Save all and close all documents
|
||||
material_editor.save_all()
|
||||
material_editor.close_all_documents()
|
||||
|
||||
# Reopen materials and verify values
|
||||
document1_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_1))
|
||||
result = material_editor.is_close(
|
||||
material_editor.get_property(document1_id, property1_name), expected_metallic_factor, 0.00001
|
||||
)
|
||||
document2_id = material_editor.open_material(os.path.join(TEST_DATA_PATH, TEST_MATERIAL_2))
|
||||
result = result and material_editor.compare_colors(
|
||||
expected_color, material_editor.get_property(document2_id, property2_name))
|
||||
print(f"Save All worked as expected: {result}")
|
||||
|
||||
# Revert the changes made
|
||||
material_editor.set_property(document1_id, property1_name, initial_metallic_factor)
|
||||
material_editor.set_property(document2_id, property2_name, initial_color)
|
||||
material_editor.save_all()
|
||||
material_editor.close_all_documents()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
+1
@@ -93,6 +93,7 @@ def run():
|
||||
general.idle_wait_frames(100)
|
||||
for i in range(1, 101):
|
||||
benchmarker.capture_pass_timestamp(i)
|
||||
benchmarker.capture_cpu_frame_time(i)
|
||||
general.exit_game_mode()
|
||||
helper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=2.0)
|
||||
general.log("Capturing complete.")
|
||||
|
||||
+267
@@ -0,0 +1,267 @@
|
||||
"""
|
||||
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
|
||||
|
||||
Hydra script that is used to create an entity with a Light component attached.
|
||||
It then updates the property values of the Light component and takes a screenshot.
|
||||
The screenshot is compared against an expected golden image for test verification.
|
||||
|
||||
See the run() function for more in-depth test info.
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from atom_renderer.atom_utils import atom_component_helper, atom_constants, screenshot_utils
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper")
|
||||
|
||||
LEVEL_NAME = "auto_test"
|
||||
LIGHT_COMPONENT = "Light"
|
||||
LIGHT_TYPE_PROPERTY = 'Controller|Configuration|Light type'
|
||||
DEGREE_RADIAN_FACTOR = 0.0174533
|
||||
|
||||
|
||||
def run():
|
||||
"""
|
||||
Sets up the tests by making sure the required level is created & setup correctly.
|
||||
It then executes 2 test cases - see each associated test function's docstring for more info.
|
||||
|
||||
Finally prints the string "Light component tests completed" after completion
|
||||
|
||||
Tests will fail immediately if any of these log lines are found:
|
||||
1. Trace::Assert
|
||||
2. Trace::Error
|
||||
3. Traceback (most recent call last):
|
||||
|
||||
:return: None
|
||||
"""
|
||||
atom_component_helper.create_basic_atom_level(level_name=LEVEL_NAME)
|
||||
|
||||
# Run tests.
|
||||
area_light_test()
|
||||
spot_light_test()
|
||||
general.log("Light component tests completed.")
|
||||
|
||||
|
||||
def area_light_test():
|
||||
"""
|
||||
Basic test for the "Light" component attached to an "area_light" entity.
|
||||
|
||||
Test Case - Light Component: Capsule, Spot (disk), and Point (sphere):
|
||||
1. Creates "area_light" entity w/ a Light component that has a Capsule Light type w/ the color set to 255, 0, 0
|
||||
2. Enters game mode to take a screenshot for comparison, then exits game mode.
|
||||
3. Sets the Light component Intensity Mode to Lumens (default).
|
||||
4. Ensures the Light component Mode is Automatic (default).
|
||||
5. Sets the Intensity value of the Light component to 0.0
|
||||
6. Enters game mode again, takes another screenshot for comparison, then exits game mode.
|
||||
7. Updates the Intensity value of the Light component to 1000.0
|
||||
8. Enters game mode again, takes another screenshot for comparison, then exits game mode.
|
||||
9. Swaps the Capsule light type option to Spot (disk) light type on the Light component
|
||||
10. Updates "area_light" entity Transform rotate value to x: 90.0, y:0.0, z:0.0
|
||||
11. Enters game mode again, takes another screenshot for comparison, then exits game mode.
|
||||
12. Swaps the Spot (disk) light type for the Point (sphere) light type in the Light component.
|
||||
13. Enters game mode again, takes another screenshot for comparison, then exits game mode.
|
||||
14. Deletes the Light component from the "area_light" entity and verifies its successful.
|
||||
"""
|
||||
# Create an "area_light" entity with "Light" component using Light type of "Capsule"
|
||||
area_light_entity_name = "area_light"
|
||||
area_light = hydra.Entity(area_light_entity_name)
|
||||
area_light.create_entity(math.Vector3(-1.0, -2.0, 3.0), [LIGHT_COMPONENT])
|
||||
general.log(
|
||||
f"{area_light_entity_name}_test: Component added to the entity: "
|
||||
f"{hydra.has_components(area_light.id, [LIGHT_COMPONENT])}")
|
||||
light_component_id_pair = hydra.attach_component_to_entity(area_light.id, LIGHT_COMPONENT)
|
||||
|
||||
# Select the "Capsule" light type option.
|
||||
azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast,
|
||||
'SetComponentProperty',
|
||||
light_component_id_pair,
|
||||
LIGHT_TYPE_PROPERTY,
|
||||
atom_constants.LIGHT_TYPES['capsule']
|
||||
)
|
||||
|
||||
# Update color and take screenshot in game mode
|
||||
color = math.Color(255.0, 0.0, 0.0, 0.0)
|
||||
area_light.get_set_test(0, "Controller|Configuration|Color", color)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("AreaLight_1", area_light_entity_name)
|
||||
|
||||
# Update intensity value to 0.0 and take screenshot in game mode
|
||||
area_light.get_set_test(0, "Controller|Configuration|Attenuation Radius|Mode", 1)
|
||||
area_light.get_set_test(0, "Controller|Configuration|Intensity", 0.0)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("AreaLight_2", area_light_entity_name)
|
||||
|
||||
# Update intensity value to 1000.0 and take screenshot in game mode
|
||||
area_light.get_set_test(0, "Controller|Configuration|Intensity", 1000.0)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("AreaLight_3", area_light_entity_name)
|
||||
|
||||
# Swap the "Capsule" light type option to "Spot (disk)" light type
|
||||
azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast,
|
||||
'SetComponentProperty',
|
||||
light_component_id_pair,
|
||||
LIGHT_TYPE_PROPERTY,
|
||||
atom_constants.LIGHT_TYPES['spot_disk']
|
||||
)
|
||||
area_light_rotation = math.Vector3(DEGREE_RADIAN_FACTOR * 90.0, 0.0, 0.0)
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", area_light.id, area_light_rotation)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("AreaLight_4", area_light_entity_name)
|
||||
|
||||
# Swap the "Spot (disk)" light type to the "Point (sphere)" light type and take screenshot.
|
||||
azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast,
|
||||
'SetComponentProperty',
|
||||
light_component_id_pair,
|
||||
LIGHT_TYPE_PROPERTY,
|
||||
atom_constants.LIGHT_TYPES['sphere']
|
||||
)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("AreaLight_5", area_light_entity_name)
|
||||
|
||||
editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntityById", area_light.id)
|
||||
|
||||
|
||||
def spot_light_test():
|
||||
"""
|
||||
Basic test for the Light component attached to a "spot_light" entity.
|
||||
|
||||
Test Case - Light Component: Spot (disk) with shadows & colors:
|
||||
1. Creates "spot_light" entity w/ a Light component attached to it.
|
||||
2. Selects the "directional_light" entity already present in the level and disables it.
|
||||
3. Selects the "global_skylight" entity already present in the level and disables the HDRi Skybox component,
|
||||
as well as the Global Skylight (IBL) component.
|
||||
4. Enters game mode to take a screenshot for comparison, then exits game mode.
|
||||
5. Selects the "ground_plane" entity and changes updates the material to a new material.
|
||||
6. Enters game mode to take a screenshot for comparison, then exits game mode.
|
||||
7. Selects the "spot_light" entity and increases the Light component Intensity to 800 lm
|
||||
8. Enters game mode to take a screenshot for comparison, then exits game mode.
|
||||
9. Selects the "spot_light" entity and sets the Light component Color to 47, 75, 37
|
||||
10. Enters game mode to take a screenshot for comparison, then exits game mode.
|
||||
11. Selects the "spot_light" entity and modifies the Shutter controls to the following values:
|
||||
- Enable shutters: True
|
||||
- Inner Angle: 60.0
|
||||
- Outer Angle: 75.0
|
||||
12. Enters game mode to take a screenshot for comparison, then exits game mode.
|
||||
13. Selects the "spot_light" entity and modifies the Shadow controls to the following values:
|
||||
- Enable Shadow: True
|
||||
- ShadowmapSize: 256
|
||||
14. Modifies the world translate position of the "spot_light" entity to 0.7, -2.0, 1.9 (for casting shadows better)
|
||||
15. Enters game mode to take a screenshot for comparison, then exits game mode.
|
||||
"""
|
||||
# Disable "Directional Light" component for the "directional_light" entity
|
||||
# "directional_light" entity is created by the create_basic_atom_level() function by default.
|
||||
directional_light_entity_id = hydra.find_entity_by_name("directional_light")
|
||||
directional_light = hydra.Entity(name='directional_light', id=directional_light_entity_id)
|
||||
directional_light_component_type = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Directional Light"], 0)[0]
|
||||
directional_light_component = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'GetComponentOfType', directional_light.id, directional_light_component_type
|
||||
).GetValue()
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [directional_light_component])
|
||||
general.idle_wait(0.5)
|
||||
|
||||
# Disable "Global Skylight (IBL)" and "HDRi Skybox" components for the "global_skylight" entity
|
||||
global_skylight_entity_id = hydra.find_entity_by_name("global_skylight")
|
||||
global_skylight = hydra.Entity(name='global_skylight', id=global_skylight_entity_id)
|
||||
global_skylight_component_type = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Global Skylight (IBL)"], 0)[0]
|
||||
global_skylight_component = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'GetComponentOfType', global_skylight.id, global_skylight_component_type
|
||||
).GetValue()
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [global_skylight_component])
|
||||
hdri_skybox_component_type = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["HDRi Skybox"], 0)[0]
|
||||
hdri_skybox_component = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'GetComponentOfType', global_skylight.id, hdri_skybox_component_type
|
||||
).GetValue()
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, "DisableComponents", [hdri_skybox_component])
|
||||
general.idle_wait(0.5)
|
||||
|
||||
# Create a "spot_light" entity with "Light" component using Light Type of "Spot (disk)"
|
||||
spot_light_entity_name = "spot_light"
|
||||
spot_light = hydra.Entity(spot_light_entity_name)
|
||||
spot_light.create_entity(math.Vector3(0.7, -2.0, 1.0), [LIGHT_COMPONENT])
|
||||
general.log(
|
||||
f"{spot_light_entity_name}_test: Component added to the entity: "
|
||||
f"{hydra.has_components(spot_light.id, [LIGHT_COMPONENT])}")
|
||||
rotation = math.Vector3(DEGREE_RADIAN_FACTOR * 300.0, 0.0, 0.0)
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", spot_light.id, rotation)
|
||||
light_component_type = hydra.attach_component_to_entity(spot_light.id, LIGHT_COMPONENT)
|
||||
editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast,
|
||||
'SetComponentProperty',
|
||||
light_component_type,
|
||||
LIGHT_TYPE_PROPERTY,
|
||||
atom_constants.LIGHT_TYPES['spot_disk']
|
||||
)
|
||||
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("SpotLight_1", spot_light_entity_name)
|
||||
|
||||
# Change default material of ground plane entity and take screenshot
|
||||
ground_plane_entity_id = hydra.find_entity_by_name("ground_plane")
|
||||
ground_plane = hydra.Entity(name='ground_plane', id=ground_plane_entity_id)
|
||||
ground_plane_asset_path = os.path.join("Materials", "Presets", "MacBeth", "22_neutral_5-0_0-70d.azmaterial")
|
||||
ground_plane_asset_value = asset.AssetCatalogRequestBus(
|
||||
bus.Broadcast, "GetAssetIdByPath", ground_plane_asset_path, math.Uuid(), False)
|
||||
material_property_path = "Default Material|Material Asset"
|
||||
material_component_type = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'FindComponentTypeIdsByEntityType', ["Material"], 0)[0]
|
||||
material_component = azlmbr.editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast, 'GetComponentOfType', ground_plane.id, material_component_type).GetValue()
|
||||
editor.EditorComponentAPIBus(
|
||||
azlmbr.bus.Broadcast,
|
||||
'SetComponentProperty',
|
||||
material_component,
|
||||
material_property_path,
|
||||
ground_plane_asset_value
|
||||
)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("SpotLight_2", spot_light_entity_name)
|
||||
|
||||
# Increase intensity value of the Spot light and take screenshot in game mode
|
||||
spot_light.get_set_test(0, "Controller|Configuration|Intensity", 800.0)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("SpotLight_3", spot_light_entity_name)
|
||||
|
||||
# Update the Spot light color and take screenshot in game mode
|
||||
color_value = math.Color(47.0 / 255.0, 75.0 / 255.0, 37.0 / 255.0, 255.0 / 255.0)
|
||||
spot_light.get_set_test(0, "Controller|Configuration|Color", color_value)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("SpotLight_4", spot_light_entity_name)
|
||||
|
||||
# Update the Shutter controls of the Light component and take screenshot
|
||||
spot_light.get_set_test(0, "Controller|Configuration|Shutters|Enable shutters", True)
|
||||
spot_light.get_set_test(0, "Controller|Configuration|Shutters|Inner angle", 60.0)
|
||||
spot_light.get_set_test(0, "Controller|Configuration|Shutters|Outer angle", 75.0)
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("SpotLight_5", spot_light_entity_name)
|
||||
|
||||
# Update the Shadow controls, move the spot_light entity world translate position and take screenshot
|
||||
spot_light.get_set_test(0, "Controller|Configuration|Shadows|Enable shadow", True)
|
||||
spot_light.get_set_test(0, "Controller|Configuration|Shadows|Shadowmap size", 256.0)
|
||||
azlmbr.components.TransformBus(
|
||||
azlmbr.bus.Event, "SetWorldTranslation", spot_light.id, math.Vector3(0.7, -2.0, 1.9))
|
||||
general.idle_wait(1.0)
|
||||
screenshot_utils.take_screenshot_game_mode("SpotLight_6", spot_light_entity_name)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
+179
-12
@@ -3,17 +3,184 @@ Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
|
||||
File to assist with common hydra component functions or constants used across various Atom tests.
|
||||
File to assist with common hydra component functions used across various Atom tests.
|
||||
"""
|
||||
import os
|
||||
|
||||
# Light type options for the Light component.
|
||||
LIGHT_TYPES = {
|
||||
'unknown': 0,
|
||||
'sphere': 1,
|
||||
'spot_disk': 2,
|
||||
'capsule': 3,
|
||||
'quad': 4,
|
||||
'polygon': 5,
|
||||
'simple_point': 6,
|
||||
'simple_spot': 7,
|
||||
}
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
helper = EditorTestHelper(log_prefix="Atom_EditorTestHelper")
|
||||
|
||||
|
||||
def create_basic_atom_level(level_name):
|
||||
"""
|
||||
Creates a new level inside the Editor matching level_name & adds the following:
|
||||
1. "default_level" entity to hold all other entities.
|
||||
2. Adds Grid, Global Skylight (IBL), ground Mesh, Directional Light, Sphere w/ material+mesh, & Camera components.
|
||||
3. Each of these components has its settings tweaked slightly to match the ideal scene to test Atom rendering.
|
||||
:param level_name: name of the level to create and apply this basic setup to.
|
||||
:return: None
|
||||
"""
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.camera as camera
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.object
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
|
||||
# Create a new level.
|
||||
new_level_name = level_name
|
||||
heightmap_resolution = 512
|
||||
heightmap_meters_per_pixel = 1
|
||||
terrain_texture_resolution = 412
|
||||
use_terrain = False
|
||||
|
||||
# Return codes are ECreateLevelResult defined in CryEdit.h
|
||||
return_code = general.create_level_no_prompt(
|
||||
new_level_name, heightmap_resolution, heightmap_meters_per_pixel, terrain_texture_resolution, use_terrain)
|
||||
if return_code == 1:
|
||||
general.log(f"{new_level_name} level already exists")
|
||||
elif return_code == 2:
|
||||
general.log("Failed to create directory")
|
||||
elif return_code == 3:
|
||||
general.log("Directory length is too long")
|
||||
elif return_code != 0:
|
||||
general.log("Unknown error, failed to create level")
|
||||
else:
|
||||
general.log(f"{new_level_name} level created successfully")
|
||||
|
||||
# Enable idle and update viewport.
|
||||
general.idle_enable(True)
|
||||
general.idle_wait(1.0)
|
||||
general.update_viewport()
|
||||
general.idle_wait(0.5) # half a second is more than enough for updating the viewport.
|
||||
|
||||
# Close out problematic windows, FPS meters, and anti-aliasing.
|
||||
if general.is_helpers_shown(): # Turn off the helper gizmos if visible
|
||||
general.toggle_helpers()
|
||||
general.idle_wait(1.0)
|
||||
if general.is_pane_visible("Error Report"): # Close Error Report windows that block focus.
|
||||
general.close_pane("Error Report")
|
||||
if general.is_pane_visible("Error Log"): # Close Error Log windows that block focus.
|
||||
general.close_pane("Error Log")
|
||||
general.idle_wait(1.0)
|
||||
general.run_console("r_displayInfo=0")
|
||||
general.run_console("r_antialiasingmode=0")
|
||||
general.idle_wait(1.0)
|
||||
|
||||
# Delete all existing entities & create default_level entity
|
||||
search_filter = azlmbr.entity.SearchFilter()
|
||||
all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter)
|
||||
editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities)
|
||||
default_level = hydra.Entity("default_level")
|
||||
default_position = math.Vector3(0.0, 0.0, 0.0)
|
||||
default_level.create_entity(default_position, ["Grid"])
|
||||
default_level.get_set_test(0, "Controller|Configuration|Secondary Grid Spacing", 1.0)
|
||||
|
||||
# Set the viewport up correctly after adding the parent default_level entity.
|
||||
screen_width = 1280
|
||||
screen_height = 720
|
||||
degree_radian_factor = 0.0174533 # Used by "Rotation" property for the Transform component.
|
||||
general.set_viewport_size(screen_width, screen_height)
|
||||
general.update_viewport()
|
||||
helper.wait_for_condition(
|
||||
function=lambda: helper.isclose(a=general.get_viewport_size().x, b=screen_width, rel_tol=0.1)
|
||||
and helper.isclose(a=general.get_viewport_size().y, b=screen_height, rel_tol=0.1),
|
||||
timeout_in_seconds=4.0
|
||||
)
|
||||
result = helper.isclose(a=general.get_viewport_size().x, b=screen_width, rel_tol=0.1) and helper.isclose(
|
||||
a=general.get_viewport_size().y, b=screen_height, rel_tol=0.1)
|
||||
general.log(general.get_viewport_size().x)
|
||||
general.log(general.get_viewport_size().y)
|
||||
general.log(general.get_viewport_size().z)
|
||||
general.log(f"Viewport is set to the expected size: {result}")
|
||||
general.log("Basic level created")
|
||||
general.run_console("r_DisplayInfo = 0")
|
||||
|
||||
# Create global_skylight entity and set the properties
|
||||
global_skylight = hydra.Entity("global_skylight")
|
||||
global_skylight.create_entity(
|
||||
entity_position=default_position,
|
||||
components=["HDRi Skybox", "Global Skylight (IBL)"],
|
||||
parent_id=default_level.id)
|
||||
global_skylight_asset_path = os.path.join(
|
||||
"LightingPresets", "greenwich_park_02_4k_iblskyboxcm_iblspecular.exr.streamingimage")
|
||||
global_skylight_asset_value = asset.AssetCatalogRequestBus(
|
||||
bus.Broadcast, "GetAssetIdByPath", global_skylight_asset_path, math.Uuid(), False)
|
||||
global_skylight.get_set_test(0, "Controller|Configuration|Cubemap Texture", global_skylight_asset_value)
|
||||
global_skylight.get_set_test(1, "Controller|Configuration|Diffuse Image", global_skylight_asset_value)
|
||||
global_skylight.get_set_test(1, "Controller|Configuration|Specular Image", global_skylight_asset_value)
|
||||
|
||||
# Create ground_plane entity and set the properties
|
||||
ground_plane = hydra.Entity("ground_plane")
|
||||
ground_plane.create_entity(
|
||||
entity_position=default_position,
|
||||
components=["Material"],
|
||||
parent_id=default_level.id)
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalUniformScale", ground_plane.id, 32.0)
|
||||
ground_plane_material_asset_path = os.path.join(
|
||||
"Materials", "Presets", "PBR", "metal_chrome.azmaterial")
|
||||
ground_plane_material_asset_value = asset.AssetCatalogRequestBus(
|
||||
bus.Broadcast, "GetAssetIdByPath", ground_plane_material_asset_path, math.Uuid(), False)
|
||||
ground_plane.get_set_test(0, "Default Material|Material Asset", ground_plane_material_asset_value)
|
||||
|
||||
# Work around to add the correct Atom Mesh component
|
||||
mesh_type_id = azlmbr.globals.property.EditorMeshComponentTypeId
|
||||
ground_plane.components.append(
|
||||
editor.EditorComponentAPIBus(
|
||||
bus.Broadcast, "AddComponentsOfType", ground_plane.id, [mesh_type_id]
|
||||
).GetValue()[0]
|
||||
)
|
||||
ground_plane_mesh_asset_path = os.path.join("Models", "plane.azmodel")
|
||||
ground_plane_mesh_asset_value = asset.AssetCatalogRequestBus(
|
||||
bus.Broadcast, "GetAssetIdByPath", ground_plane_mesh_asset_path, math.Uuid(), False)
|
||||
ground_plane.get_set_test(1, "Controller|Configuration|Mesh Asset", ground_plane_mesh_asset_value)
|
||||
|
||||
# Create directional_light entity and set the properties
|
||||
directional_light = hydra.Entity("directional_light")
|
||||
directional_light.create_entity(
|
||||
entity_position=math.Vector3(0.0, 0.0, 10.0),
|
||||
components=["Directional Light"],
|
||||
parent_id=default_level.id)
|
||||
directional_light_rotation = math.Vector3(degree_radian_factor * -90.0, 0.0, 0.0)
|
||||
azlmbr.components.TransformBus(
|
||||
azlmbr.bus.Event, "SetLocalRotation", directional_light.id, directional_light_rotation)
|
||||
|
||||
# Create sphere entity and set the properties
|
||||
sphere_entity = hydra.Entity("sphere")
|
||||
sphere_entity.create_entity(
|
||||
entity_position=math.Vector3(0.0, 0.0, 1.0),
|
||||
components=["Material"],
|
||||
parent_id=default_level.id)
|
||||
sphere_material_asset_path = os.path.join("Materials", "Presets", "PBR", "metal_brass_polished.azmaterial")
|
||||
sphere_material_asset_value = asset.AssetCatalogRequestBus(
|
||||
bus.Broadcast, "GetAssetIdByPath", sphere_material_asset_path, math.Uuid(), False)
|
||||
sphere_entity.get_set_test(0, "Default Material|Material Asset", sphere_material_asset_value)
|
||||
|
||||
# Work around to add the correct Atom Mesh component
|
||||
sphere_entity.components.append(
|
||||
editor.EditorComponentAPIBus(
|
||||
bus.Broadcast, "AddComponentsOfType", sphere_entity.id, [mesh_type_id]
|
||||
).GetValue()[0]
|
||||
)
|
||||
sphere_mesh_asset_path = os.path.join("Models", "sphere.azmodel")
|
||||
sphere_mesh_asset_value = asset.AssetCatalogRequestBus(
|
||||
bus.Broadcast, "GetAssetIdByPath", sphere_mesh_asset_path, math.Uuid(), False)
|
||||
sphere_entity.get_set_test(1, "Controller|Configuration|Mesh Asset", sphere_mesh_asset_value)
|
||||
|
||||
# Create camera component and set the properties
|
||||
camera_entity = hydra.Entity("camera")
|
||||
camera_entity.create_entity(
|
||||
entity_position=math.Vector3(5.5, -12.0, 9.0),
|
||||
components=["Camera"],
|
||||
parent_id=default_level.id)
|
||||
rotation = math.Vector3(
|
||||
degree_radian_factor * -27.0, degree_radian_factor * -12.0, degree_radian_factor * 25.0
|
||||
)
|
||||
azlmbr.components.TransformBus(azlmbr.bus.Event, "SetLocalRotation", camera_entity.id, rotation)
|
||||
camera_entity.get_set_test(0, "Controller|Configuration|Field of view", 60.0)
|
||||
camera.EditorCameraViewRequestBus(azlmbr.bus.Event, "ToggleCameraAsActiveView", camera_entity.id)
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
"""
|
||||
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
|
||||
|
||||
Hold constants used across both hydra and non-hydra scripts.
|
||||
"""
|
||||
|
||||
# Light type options for the Light component.
|
||||
LIGHT_TYPES = {
|
||||
'unknown': 0,
|
||||
'sphere': 1,
|
||||
'spot_disk': 2,
|
||||
'capsule': 3,
|
||||
'quad': 4,
|
||||
'polygon': 5,
|
||||
'simple_point': 6,
|
||||
'simple_spot': 7,
|
||||
}
|
||||
@@ -61,6 +61,25 @@ class BenchmarkHelper(object):
|
||||
general.log('Failed to capture pass timestamps.')
|
||||
return self.capturedData
|
||||
|
||||
def capture_cpu_frame_time(self, frame_number):
|
||||
"""
|
||||
Capture CPU frame times and block further execution until it has been written to the disk.
|
||||
"""
|
||||
self.handler = azlmbr.atom.ProfilingCaptureNotificationBusHandler()
|
||||
self.handler.connect()
|
||||
self.handler.add_callback('OnCaptureCpuFrameTimeFinished', self.on_data_captured)
|
||||
|
||||
self.done = False
|
||||
self.capturedData = False
|
||||
success = azlmbr.atom.ProfilingCaptureRequestBus(
|
||||
azlmbr.bus.Broadcast, "CaptureCpuFrameTime", f'{self.output_path}/cpu_frame{frame_number}_time.json')
|
||||
if success:
|
||||
self.wait_until_data()
|
||||
general.log('CPU frame time captured.')
|
||||
else:
|
||||
general.log('Failed to capture CPU frame time.')
|
||||
return self.capturedData
|
||||
|
||||
def on_data_captured(self, parameters):
|
||||
# the parameters come in as a tuple
|
||||
if parameters[0]:
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
"""
|
||||
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 azlmbr.materialeditor will fail with a ModuleNotFound error when using this script with Editor.exe
|
||||
This is because azlmbr.materialeditor only binds to MaterialEditor.exe and not Editor.exe
|
||||
You need to launch this script with MaterialEditor.exe in order for azlmbr.materialeditor to appear.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import azlmbr.atom
|
||||
import azlmbr.atomtools as atomtools
|
||||
import azlmbr.materialeditor as materialeditor
|
||||
import azlmbr.bus as bus
|
||||
|
||||
|
||||
def is_close(actual, expected, buffer=sys.float_info.min):
|
||||
"""
|
||||
:param actual: actual value
|
||||
:param expected: expected value
|
||||
:param buffer: acceptable variation from expected
|
||||
:return: bool
|
||||
"""
|
||||
return abs(actual - expected) < buffer
|
||||
|
||||
|
||||
def compare_colors(color1, color2, buffer=0.00001):
|
||||
"""
|
||||
Compares the red, green and blue properties of a color allowing a slight variance of buffer
|
||||
:param color1: first color to compare
|
||||
:param color2: second color
|
||||
:param buffer: allowed variance in individual color value
|
||||
:return: bool
|
||||
"""
|
||||
return (
|
||||
is_close(color1.r, color2.r, buffer)
|
||||
and is_close(color1.g, color2.g, buffer)
|
||||
and is_close(color1.b, color2.b, buffer)
|
||||
)
|
||||
|
||||
|
||||
def open_material(file_path):
|
||||
"""
|
||||
:return: uuid of material document opened
|
||||
"""
|
||||
return azlmbr.atomtools.AtomToolsDocumentSystemRequestBus(bus.Broadcast, "OpenDocument", file_path)
|
||||
|
||||
|
||||
def is_open(document_id):
|
||||
"""
|
||||
:return: bool
|
||||
"""
|
||||
return azlmbr.atomtools.AtomToolsDocumentRequestBus(bus.Event, "IsOpen", document_id)
|
||||
|
||||
|
||||
def save_document(document_id):
|
||||
"""
|
||||
:return: bool success
|
||||
"""
|
||||
return azlmbr.atomtools.AtomToolsDocumentSystemRequestBus(bus.Broadcast, "SaveDocument", document_id)
|
||||
|
||||
|
||||
def save_document_as_copy(document_id, target_path):
|
||||
"""
|
||||
:return: bool success
|
||||
"""
|
||||
return azlmbr.atomtools.AtomToolsDocumentSystemRequestBus(
|
||||
bus.Broadcast, "SaveDocumentAsCopy", document_id, target_path
|
||||
)
|
||||
|
||||
|
||||
def save_document_as_child(document_id, target_path):
|
||||
"""
|
||||
:return: bool success
|
||||
"""
|
||||
return azlmbr.atomtools.AtomToolsDocumentSystemRequestBus(
|
||||
bus.Broadcast, "SaveDocumentAsChild", document_id, target_path
|
||||
)
|
||||
|
||||
|
||||
def save_all():
|
||||
"""
|
||||
:return: bool success
|
||||
"""
|
||||
return azlmbr.atomtools.AtomToolsDocumentSystemRequestBus(bus.Broadcast, "SaveAllDocuments")
|
||||
|
||||
|
||||
def close_document(document_id):
|
||||
"""
|
||||
:return: bool success
|
||||
"""
|
||||
return azlmbr.atomtools.AtomToolsDocumentSystemRequestBus(bus.Broadcast, "CloseDocument", document_id)
|
||||
|
||||
|
||||
def close_all_documents():
|
||||
"""
|
||||
:return: bool success
|
||||
"""
|
||||
return azlmbr.atomtools.AtomToolsDocumentSystemRequestBus(bus.Broadcast, "CloseAllDocuments")
|
||||
|
||||
|
||||
def close_all_except_selected(document_id):
|
||||
"""
|
||||
:return: bool success
|
||||
"""
|
||||
return azlmbr.atomtools.AtomToolsDocumentSystemRequestBus(bus.Broadcast, "CloseAllDocumentsExcept", document_id)
|
||||
|
||||
|
||||
def get_property(document_id, property_name):
|
||||
"""
|
||||
:return: property value or invalid value if the document is not open or the property_name can't be found
|
||||
"""
|
||||
return azlmbr.atomtools.AtomToolsDocumentRequestBus(bus.Event, "GetPropertyValue", document_id, property_name)
|
||||
|
||||
|
||||
def set_property(document_id, property_name, value):
|
||||
azlmbr.atomtools.AtomToolsDocumentRequestBus(bus.Event, "SetPropertyValue", document_id, property_name, value)
|
||||
|
||||
|
||||
def is_pane_visible(pane_name):
|
||||
"""
|
||||
:return: bool
|
||||
"""
|
||||
return atomtools.AtomToolsWindowRequestBus(bus.Broadcast, "IsDockWidgetVisible", pane_name)
|
||||
|
||||
|
||||
def set_pane_visibility(pane_name, value):
|
||||
atomtools.AtomToolsWindowRequestBus(bus.Broadcast, "SetDockWidgetVisible", pane_name, value)
|
||||
|
||||
|
||||
def select_lighting_config(config_name):
|
||||
azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SelectLightingPresetByName", config_name)
|
||||
|
||||
|
||||
def set_grid_enable_disable(value):
|
||||
azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SetGridEnabled", value)
|
||||
|
||||
|
||||
def get_grid_enable_disable():
|
||||
"""
|
||||
:return: bool
|
||||
"""
|
||||
return azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "GetGridEnabled")
|
||||
|
||||
|
||||
def set_shadowcatcher_enable_disable(value):
|
||||
azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SetShadowCatcherEnabled", value)
|
||||
|
||||
|
||||
def get_shadowcatcher_enable_disable():
|
||||
"""
|
||||
:return: bool
|
||||
"""
|
||||
return azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "GetShadowCatcherEnabled")
|
||||
|
||||
|
||||
def select_model_config(configname):
|
||||
azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, "SelectModelPresetByName", configname)
|
||||
|
||||
|
||||
def wait_for_condition(function, timeout_in_seconds=1.0):
|
||||
# type: (function, float) -> bool
|
||||
"""
|
||||
Function to run until it returns True or timeout is reached
|
||||
the function can have no parameters and
|
||||
waiting idle__wait_* is handled here not in the function
|
||||
|
||||
:param function: a function that returns a boolean indicating a desired condition is achieved
|
||||
:param timeout_in_seconds: when reached, function execution is abandoned and False is returned
|
||||
"""
|
||||
with Timeout(timeout_in_seconds) as t:
|
||||
while True:
|
||||
try:
|
||||
azlmbr.atomtools.general.idle_wait_frames(1)
|
||||
except Exception:
|
||||
print("WARNING: Couldn't wait for frame")
|
||||
|
||||
if t.timed_out:
|
||||
return False
|
||||
|
||||
ret = function()
|
||||
if not isinstance(ret, bool):
|
||||
raise TypeError("return value for wait_for_condition function must be a bool")
|
||||
if ret:
|
||||
return True
|
||||
|
||||
|
||||
class Timeout:
|
||||
# type: (float) -> None
|
||||
"""
|
||||
contextual timeout
|
||||
:param seconds: float seconds to allow before timed_out is True
|
||||
"""
|
||||
|
||||
def __init__(self, seconds):
|
||||
self.seconds = seconds
|
||||
|
||||
def __enter__(self):
|
||||
self.die_after = time.time() + self.seconds
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
pass
|
||||
|
||||
@property
|
||||
def timed_out(self):
|
||||
return time.time() > self.die_after
|
||||
|
||||
|
||||
screenshotsFolder = os.path.join(azlmbr.paths.devroot, "AtomTest", "Cache" "pc", "Screenshots")
|
||||
|
||||
|
||||
class ScreenshotHelper:
|
||||
"""
|
||||
A helper to capture screenshots and wait for them.
|
||||
"""
|
||||
|
||||
def __init__(self, idle_wait_frames_callback):
|
||||
super().__init__()
|
||||
self.done = False
|
||||
self.capturedScreenshot = False
|
||||
self.max_frames_to_wait = 60
|
||||
|
||||
self.idle_wait_frames_callback = idle_wait_frames_callback
|
||||
|
||||
def capture_screenshot_blocking(self, filename):
|
||||
"""
|
||||
Capture a screenshot and block the execution until the screenshot has been written to the disk.
|
||||
"""
|
||||
self.handler = azlmbr.atom.FrameCaptureNotificationBusHandler()
|
||||
self.handler.connect()
|
||||
self.handler.add_callback("OnCaptureFinished", self.on_screenshot_captured)
|
||||
|
||||
self.done = False
|
||||
self.capturedScreenshot = False
|
||||
success = azlmbr.atom.FrameCaptureRequestBus(azlmbr.bus.Broadcast, "CaptureScreenshot", filename)
|
||||
if success:
|
||||
self.wait_until_screenshot()
|
||||
print("Screenshot taken.")
|
||||
else:
|
||||
print("screenshot failed")
|
||||
return self.capturedScreenshot
|
||||
|
||||
def on_screenshot_captured(self, parameters):
|
||||
# the parameters come in as a tuple
|
||||
if parameters[0]:
|
||||
print("screenshot saved: {}".format(parameters[1]))
|
||||
self.capturedScreenshot = True
|
||||
else:
|
||||
print("screenshot failed: {}".format(parameters[1]))
|
||||
self.done = True
|
||||
self.handler.disconnect()
|
||||
|
||||
def wait_until_screenshot(self):
|
||||
frames_waited = 0
|
||||
while self.done == False:
|
||||
self.idle_wait_frames_callback(1)
|
||||
if frames_waited > self.max_frames_to_wait:
|
||||
print("timeout while waiting for the screenshot to be written")
|
||||
self.handler.disconnect()
|
||||
break
|
||||
else:
|
||||
frames_waited = frames_waited + 1
|
||||
print("(waited {} frames)".format(frames_waited))
|
||||
|
||||
|
||||
def capture_screenshot(file_path):
|
||||
return ScreenshotHelper(azlmbr.atomtools.general.idle_wait_frames).capture_screenshot_blocking(
|
||||
os.path.join(file_path)
|
||||
)
|
||||
@@ -91,3 +91,20 @@ class ScreenshotHelper(object):
|
||||
else:
|
||||
frames_waited = frames_waited + 1
|
||||
general.log(f"(waited {frames_waited} frames)")
|
||||
|
||||
|
||||
def take_screenshot_game_mode(screenshot_name, entity_name=None):
|
||||
"""
|
||||
Enters game mode & takes a screenshot, then exits game mode after.
|
||||
:param screenshot_name: name to give the captured screenshot .ppm file.
|
||||
:param entity_name: name of the entity being tested (for generating unique log lines).
|
||||
:return: None
|
||||
"""
|
||||
general.enter_game_mode()
|
||||
helper.wait_for_condition(lambda: general.is_in_game_mode(), 2.0)
|
||||
general.log(f"{entity_name}_test: Entered game mode: {general.is_in_game_mode()}")
|
||||
ScreenshotHelper(general.idle_wait_frames).capture_screenshot_blocking(f"{screenshot_name}.ppm")
|
||||
general.idle_wait(1.0)
|
||||
general.exit_game_mode()
|
||||
helper.wait_for_condition(lambda: not general.is_in_game_mode(), 2.0)
|
||||
general.log(f"{entity_name}_test: Exit game mode: {not general.is_in_game_mode()}")
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:954d7d0df47c840a24e313893800eb3126d0c0d47c3380926776b51833778db7
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e81c19128f42ba362a2d5f3ccf159dfbc942d67ceeb1ac8c21f295a6fd9d2ce5
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5e20801213e065b6ea8c95ede81c23faa9b6dc70a2002dc5bced293e1bed989f
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e250f812e594e5152bf2d6f23caa8b53b78276bfdf344d7a8d355dd96cb995c0
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:95be359041f8291c74b335297a4dfe9902a180510f24a181b15e1a5ba4d3b024
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:118e43e4b915e262726183467cc4b82f244565213fea5b6bfe02be07f0851ab1
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:dc2ce3256a6552975962c9e113c52c1a22bf3817d417151f6f60640dd568e0fa
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:287d98890b35427688999760f9d066bcbff1a3bc9001534241dc212b32edabd8
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:66e91c92c868167c850078cd91714db47e10a96e23cc30191994486bd79c353f
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d950d173f5101820c5e18205401ca08ce5feeff2302ac2920b292750d86a8fa4
|
||||
size 6220817
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:72eddb7126eae0c839b933886e0fb69d78229f72d49ef13199de28df2b7879db
|
||||
size 6220817
|
||||
@@ -15,11 +15,11 @@ import pytest
|
||||
import ly_test_tools.environment.file_system as file_system
|
||||
from ly_test_tools.image.screenshot_compare_qssim import qssim as compare_screenshots
|
||||
from ly_test_tools.benchmark.data_aggregator import BenchmarkDataAggregator
|
||||
|
||||
import editor_python_test_tools.hydra_test_utils as hydra
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
DEFAULT_SUBFOLDER_PATH = 'user/PythonTests/Automated/Screenshots'
|
||||
EDITOR_TIMEOUT = 600
|
||||
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts")
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ class TestAllComponentsIndepthTests(object):
|
||||
"Trace::Assert",
|
||||
"Trace::Error",
|
||||
"Traceback (most recent call last):",
|
||||
"Screenshot failed"
|
||||
]
|
||||
|
||||
hydra.launch_and_validate_results(
|
||||
@@ -74,7 +75,7 @@ class TestAllComponentsIndepthTests(object):
|
||||
TEST_DIRECTORY,
|
||||
editor,
|
||||
"hydra_GPUTest_BasicLevelSetup.py",
|
||||
timeout=EDITOR_TIMEOUT,
|
||||
timeout=180,
|
||||
expected_lines=level_creation_expected_lines,
|
||||
unexpected_lines=unexpected_lines,
|
||||
halt_on_unexpected=True,
|
||||
@@ -85,6 +86,60 @@ class TestAllComponentsIndepthTests(object):
|
||||
for test_screenshot, golden_screenshot in zip(test_screenshots, golden_images):
|
||||
compare_screenshots(test_screenshot, golden_screenshot)
|
||||
|
||||
def test_LightComponent_ScreenshotMatchesGoldenImage(
|
||||
self, request, editor, workspace, project, launcher_platform, level):
|
||||
"""
|
||||
Please review the hydra script run by this test for more specific test info.
|
||||
Tests that the Light component screenshots in a rendered level appear the same as the golden images.
|
||||
"""
|
||||
screenshot_names = [
|
||||
"AreaLight_1.ppm",
|
||||
"AreaLight_2.ppm",
|
||||
"AreaLight_3.ppm",
|
||||
"AreaLight_4.ppm",
|
||||
"AreaLight_5.ppm",
|
||||
"SpotLight_1.ppm",
|
||||
"SpotLight_2.ppm",
|
||||
"SpotLight_3.ppm",
|
||||
"SpotLight_4.ppm",
|
||||
"SpotLight_5.ppm",
|
||||
"SpotLight_6.ppm",
|
||||
]
|
||||
test_screenshots = []
|
||||
for screenshot in screenshot_names:
|
||||
screenshot_path = os.path.join(workspace.paths.project(), DEFAULT_SUBFOLDER_PATH, screenshot)
|
||||
test_screenshots.append(screenshot_path)
|
||||
file_system.delete(test_screenshots, True, True)
|
||||
|
||||
golden_images = []
|
||||
for golden_image in screenshot_names:
|
||||
golden_image_path = os.path.join(golden_images_directory(), golden_image)
|
||||
golden_images.append(golden_image_path)
|
||||
|
||||
expected_lines = ["Light component tests completed."]
|
||||
unexpected_lines = [
|
||||
"Trace::Assert",
|
||||
"Trace::Error",
|
||||
"Traceback (most recent call last):",
|
||||
"Screenshot failed",
|
||||
]
|
||||
hydra.launch_and_validate_results(
|
||||
request,
|
||||
TEST_DIRECTORY,
|
||||
editor,
|
||||
"hydra_GPUTest_LightComponent.py",
|
||||
timeout=180,
|
||||
expected_lines=expected_lines,
|
||||
unexpected_lines=unexpected_lines,
|
||||
halt_on_unexpected=True,
|
||||
cfg_args=[level],
|
||||
null_renderer=False,
|
||||
)
|
||||
|
||||
for test_screenshot, golden_screenshot in zip(test_screenshots, golden_images):
|
||||
compare_screenshots(test_screenshot, golden_screenshot)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('rhi', ['dx12', 'vulkan'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
@pytest.mark.parametrize("launcher_platform", ["windows_editor"])
|
||||
@@ -99,6 +154,7 @@ class TestPerformanceBenchmarkSuite(object):
|
||||
expected_lines = [
|
||||
"Benchmark metadata captured.",
|
||||
"Pass timestamps captured.",
|
||||
"CPU frame time captured.",
|
||||
"Capturing complete.",
|
||||
"Captured data successfully."
|
||||
]
|
||||
@@ -106,6 +162,7 @@ class TestPerformanceBenchmarkSuite(object):
|
||||
unexpected_lines = [
|
||||
"Failed to capture data.",
|
||||
"Failed to capture pass timestamps.",
|
||||
"Failed to capture CPU frame time.",
|
||||
"Failed to capture benchmark metadata."
|
||||
]
|
||||
|
||||
@@ -114,7 +171,7 @@ class TestPerformanceBenchmarkSuite(object):
|
||||
TEST_DIRECTORY,
|
||||
editor,
|
||||
"hydra_GPUTest_AtomFeatureIntegrationBenchmark.py",
|
||||
timeout=EDITOR_TIMEOUT,
|
||||
timeout=600,
|
||||
expected_lines=expected_lines,
|
||||
unexpected_lines=unexpected_lines,
|
||||
halt_on_unexpected=True,
|
||||
|
||||
@@ -11,8 +11,9 @@ 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 atom_renderer.atom_utils.atom_component_helper import LIGHT_TYPES
|
||||
from atom_renderer.atom_utils.atom_constants import LIGHT_TYPES
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
EDITOR_TIMEOUT = 120
|
||||
@@ -31,7 +32,7 @@ class TestAtomEditorComponentsMain(object):
|
||||
Tests the following Atom components and verifies all "expected_lines" appear in Editor.log:
|
||||
1. Display Mapper
|
||||
2. Light
|
||||
3. Radius Weight Modifier
|
||||
3. PostFX Radius Weight Modifier
|
||||
4. PostFX Layer
|
||||
5. Physical Sky
|
||||
6. Global Skylight (IBL)
|
||||
@@ -125,18 +126,18 @@ class TestAtomEditorComponentsMain(object):
|
||||
"PostFX Layer_test: Entity deleted: True",
|
||||
"PostFX Layer_test: UNDO entity deletion works: True",
|
||||
"PostFX Layer_test: REDO entity deletion works: True",
|
||||
# Radius Weight Modifier Component
|
||||
"Radius Weight Modifier Entity successfully created",
|
||||
"Radius Weight Modifier_test: Component added to the entity: True",
|
||||
"Radius Weight Modifier_test: Component removed after UNDO: True",
|
||||
"Radius Weight Modifier_test: Component added after REDO: True",
|
||||
"Radius Weight Modifier_test: Entered game mode: True",
|
||||
"Radius Weight Modifier_test: Exit game mode: True",
|
||||
"Radius Weight Modifier_test: Entity is hidden: True",
|
||||
"Radius Weight Modifier_test: Entity is shown: True",
|
||||
"Radius Weight Modifier_test: Entity deleted: True",
|
||||
"Radius Weight Modifier_test: UNDO entity deletion works: True",
|
||||
"Radius Weight Modifier_test: REDO entity deletion works: True",
|
||||
# PostFX Radius Weight Modifier Component
|
||||
"PostFX Radius Weight Modifier Entity successfully created",
|
||||
"PostFX Radius Weight Modifier_test: Component added to the entity: True",
|
||||
"PostFX Radius Weight Modifier_test: Component removed after UNDO: True",
|
||||
"PostFX Radius Weight Modifier_test: Component added after REDO: True",
|
||||
"PostFX Radius Weight Modifier_test: Entered game mode: True",
|
||||
"PostFX Radius Weight Modifier_test: Exit game mode: True",
|
||||
"PostFX Radius Weight Modifier_test: Entity is hidden: True",
|
||||
"PostFX Radius Weight Modifier_test: Entity is shown: True",
|
||||
"PostFX Radius Weight Modifier_test: Entity deleted: True",
|
||||
"PostFX Radius Weight Modifier_test: UNDO entity deletion works: True",
|
||||
"PostFX Radius Weight Modifier_test: REDO entity deletion works: True",
|
||||
# Light Component
|
||||
"Light Entity successfully created",
|
||||
"Light_test: Component added to the entity: True",
|
||||
@@ -242,3 +243,65 @@ class TestAtomEditorComponentsMain(object):
|
||||
null_renderer=True,
|
||||
cfg_args=cfg_args,
|
||||
)
|
||||
|
||||
|
||||
@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"])
|
||||
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 = [
|
||||
# "Trace::Assert",
|
||||
# "Trace::Error",
|
||||
"Traceback (most recent call last):"
|
||||
]
|
||||
|
||||
hydra.launch_and_validate_results(
|
||||
request,
|
||||
TEST_DIRECTORY,
|
||||
generic_launcher,
|
||||
"hydra_AtomMaterialEditor_BasicTests.py",
|
||||
run_python="--runpython",
|
||||
timeout=80,
|
||||
expected_lines=expected_lines,
|
||||
unexpected_lines=unexpected_lines,
|
||||
halt_on_unexpected=True,
|
||||
log_file_name="MaterialEditor.log",
|
||||
)
|
||||
|
||||
@@ -13,7 +13,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}
|
||||
PYTEST_MARKS "SUITE_main and not REQUIRES_gpu"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
@@ -28,7 +27,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}
|
||||
PYTEST_MARKS "SUITE_periodic and not REQUIRES_gpu"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
@@ -44,7 +42,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_REQUIRES gpu
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}
|
||||
PYTEST_MARKS "SUITE_main and REQUIRES_gpu"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
@@ -59,7 +56,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}
|
||||
PYTEST_MARKS "SUITE_sandbox"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
|
||||
@@ -61,7 +61,7 @@ class AssetPickerUIUXTest(EditorTestHelper):
|
||||
5) Verify if Mesh Asset is assigned via both OK/Enter options
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Lumberyard Editor command terminal
|
||||
- This test file must be called from the O3DE Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
|
||||
+2
-2
@@ -37,7 +37,7 @@ class TestBasicEditorWorkflows(EditorTestHelper):
|
||||
async def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
Open Lumberyard editor and check if basic Editor workflows are completable.
|
||||
Open O3DE editor and check if basic Editor workflows are completable.
|
||||
|
||||
Expected Behavior:
|
||||
- A new level can be created
|
||||
@@ -48,7 +48,7 @@ class TestBasicEditorWorkflows(EditorTestHelper):
|
||||
- Level can be exported
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Lumberyard Editor command terminal
|
||||
- This test file must be called from the O3DE Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class TestEditMenuOptions(EditorTestHelper):
|
||||
2) Interact with Edit Menu options
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Lumberyard Editor command terminal
|
||||
- This test file must be called from the O3DE Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ class TestFileMenuOptions(EditorTestHelper):
|
||||
2) Interact with File Menu options
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Lumberyard Editor command terminal
|
||||
- This test file must be called from the O3DE Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class TestViewMenuOptions(EditorTestHelper):
|
||||
2) Interact with View Menu options
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Lumberyard Editor command terminal
|
||||
- This test file must be called from the O3DE Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE main
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -33,7 +32,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE sandbox
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_sandbox"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -49,7 +47,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_filter"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -64,7 +61,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_modifier"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -79,7 +75,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_regression"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -94,7 +89,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_area"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -109,7 +103,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_misc"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -124,7 +117,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg
|
||||
PYTEST_MARKS "SUITE_periodic and dynveg_surfacetagemitter"
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -138,9 +130,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
NAME AutomatedTesting::LandscapeCanvasTests_Main
|
||||
TEST_SERIAL
|
||||
TEST_SUITE main
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas
|
||||
PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark"
|
||||
TIMEOUT 1500
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/test_LandscapeCanvas_Main.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -153,9 +143,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
NAME AutomatedTesting::LandscapeCanvasTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas
|
||||
PYTEST_MARKS "SUITE_periodic"
|
||||
TIMEOUT 1500
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/test_LandscapeCanvas_Periodic.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -169,8 +157,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
NAME AutomatedTesting::GradientSignalTests_Periodic
|
||||
TEST_SERIAL
|
||||
TEST_SUITE periodic
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/gradient_signal
|
||||
TIMEOUT 1500
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/gradient_signal/test_GradientSignal_Periodic.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
|
||||
+16
-9
@@ -10,6 +10,7 @@ import sys
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.math as math
|
||||
@@ -107,7 +108,7 @@ class TestPhysXColliderSurfaceTagEmitter(EditorTestHelper):
|
||||
# Create an entity with a PhysX Collider and our PhysX Collider Surface Tag Emitter
|
||||
collider_entity = hydra.Entity("Collider Surface")
|
||||
collider_entity.create_entity(
|
||||
entity_center_point,
|
||||
entity_center_point,
|
||||
["PhysX Collider", "PhysX Collider Surface Tag Emitter"]
|
||||
)
|
||||
if collider_entity.id.IsValid():
|
||||
@@ -153,23 +154,29 @@ class TestPhysXColliderSurfaceTagEmitter(EditorTestHelper):
|
||||
self.test_success = self.test_success and baseline_success
|
||||
|
||||
# Setup collider entity with a PhysX Mesh
|
||||
test_physx_mesh_asset_path = asset.AssetCatalogRequestBus(
|
||||
test_physx_mesh_asset_id = asset.AssetCatalogRequestBus(
|
||||
bus.Broadcast, "GetAssetIdByPath", os.path.join("levels", "physics",
|
||||
"c4044697_material_perfacematerialvalidation",
|
||||
"test.pxmesh"), math.Uuid(), False)
|
||||
hydra.get_set_test(collider_entity, 0, "Shape Configuration|Shape", 7)
|
||||
hydra.get_set_test(collider_entity, 0, "Shape Configuration|Asset|PhysX Mesh", test_physx_mesh_asset_path)
|
||||
|
||||
# Remove/re-add component due to LYN-5496
|
||||
collider_entity.remove_component("PhysX Collider")
|
||||
collider_entity.add_component("PhysX Collider")
|
||||
self.wait_for_condition(lambda: editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled',
|
||||
collider_entity.components[1]), 5.0)
|
||||
hydra.get_set_test(collider_entity, 1, "Shape Configuration|Shape", 7)
|
||||
hydra.get_set_test(collider_entity, 1, "Shape Configuration|Asset|PhysX Mesh", test_physx_mesh_asset_id)
|
||||
|
||||
# Set the asset scale to match the test heights of the shapes tested
|
||||
asset_scale = math.Vector3(1.0, 1.0, 9.0)
|
||||
collider_entity.get_set_test(0, "Shape Configuration|Asset|Configuration|Asset Scale", asset_scale)
|
||||
collider_entity.get_set_test(1, "Shape Configuration|Asset|Configuration|Asset Scale", asset_scale)
|
||||
|
||||
# Test: Generate a new surface on the collider.
|
||||
# There should be one instance at the very top of the collider mesh, and none on the baseline surface
|
||||
# (We use a small query box to only check for one placed instance point)
|
||||
self.log("Starting PhysX Mesh Collider Test")
|
||||
hydra.get_set_test(collider_entity, 1, "Configuration|Generated Tags", [surface_tag])
|
||||
hydra.get_set_test(collider_entity, 1, "Configuration|Extended Tags", [invalid_tag])
|
||||
hydra.get_set_test(collider_entity, 0, "Configuration|Generated Tags", [surface_tag])
|
||||
hydra.get_set_test(collider_entity, 0, "Configuration|Extended Tags", [invalid_tag])
|
||||
top_point_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(top_point, 0.25, 1), 5.0)
|
||||
self.test_success = self.test_success and top_point_success
|
||||
baseline_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(baseline_surface_point,
|
||||
@@ -180,8 +187,8 @@ class TestPhysXColliderSurfaceTagEmitter(EditorTestHelper):
|
||||
# There should be no instances at the very top of the collider mesh, and none on the baseline surface within
|
||||
# our query box as PhysX meshes are treated as hollow shells, not solid volumes.
|
||||
# (We use a small query box to only check for one placed instance point)
|
||||
hydra.get_set_test(collider_entity, 1, "Configuration|Generated Tags", [invalid_tag])
|
||||
hydra.get_set_test(collider_entity, 1, "Configuration|Extended Tags", [surface_tag])
|
||||
hydra.get_set_test(collider_entity, 0, "Configuration|Generated Tags", [invalid_tag])
|
||||
hydra.get_set_test(collider_entity, 0, "Configuration|Extended Tags", [surface_tag])
|
||||
top_point_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(top_point, 0.25, 0), 5.0)
|
||||
self.test_success = self.test_success and top_point_success
|
||||
baseline_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(baseline_surface_point,
|
||||
|
||||
+96
-102
@@ -4,124 +4,118 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.paths
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
|
||||
class TestGradientGeneratorIncompatibilities(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientGeneratorIncompatibilities", args=["level"])
|
||||
def GradientGenerators_Incompatibilities():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that components are disabled when conflicting components are present on the same entity.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that components are disabled when conflicting components are present on the same entity.
|
||||
Expected Behavior:
|
||||
Gradient Generator components are incompatible with Vegetation area components.
|
||||
|
||||
Expected Behavior:
|
||||
Gradient Generator components are incompatible with Vegetation area components.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Create a new entity in the level
|
||||
3) Add each Gradient Generator component to an entity, and add a Vegetation Area component to the same entity
|
||||
4) Verify that components are only enabled when entity is free of a conflicting component
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Create a new entity in the level
|
||||
3) Add each Gradient Generator component to an entity, and add a Vegetation Area component to the same entity
|
||||
4) Verify that components are only enabled when entity is free of a conflicting component
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
:return: None
|
||||
"""
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
|
||||
gradient_generators = [
|
||||
'Altitude Gradient',
|
||||
'Constant Gradient',
|
||||
'FastNoise Gradient',
|
||||
'Image Gradient',
|
||||
'Perlin Noise Gradient',
|
||||
'Random Noise Gradient',
|
||||
'Shape Falloff Gradient',
|
||||
'Slope Gradient',
|
||||
'Surface Mask Gradient'
|
||||
]
|
||||
require_transform_modifiers = [
|
||||
'FastNoise Gradient',
|
||||
'Image Gradient',
|
||||
'Perlin Noise Gradient',
|
||||
'Random Noise Gradient'
|
||||
]
|
||||
vegetation_areas = [
|
||||
'Vegetation Layer Spawner',
|
||||
'Vegetation Layer Blender',
|
||||
'Vegetation Layer Blocker',
|
||||
'Vegetation Layer Blocker (Mesh)'
|
||||
]
|
||||
area_dependencies = {
|
||||
'Vegetation Layer Spawner': 'Vegetation Asset List',
|
||||
'Vegetation Layer Blocker (Mesh)': 'Mesh'
|
||||
}
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
gradient_generators = [
|
||||
'Altitude Gradient',
|
||||
'Constant Gradient',
|
||||
'FastNoise Gradient',
|
||||
'Image Gradient',
|
||||
'Perlin Noise Gradient',
|
||||
'Random Noise Gradient',
|
||||
'Shape Falloff Gradient',
|
||||
'Slope Gradient',
|
||||
'Surface Mask Gradient'
|
||||
]
|
||||
require_transform_modifiers = [
|
||||
'FastNoise Gradient',
|
||||
'Image Gradient',
|
||||
'Perlin Noise Gradient',
|
||||
'Random Noise Gradient'
|
||||
]
|
||||
vegetation_areas = [
|
||||
'Vegetation Layer Spawner',
|
||||
'Vegetation Layer Blender',
|
||||
'Vegetation Layer Blocker',
|
||||
'Vegetation Layer Blocker (Mesh)'
|
||||
]
|
||||
area_dependencies = {
|
||||
'Vegetation Layer Spawner': 'Vegetation Asset List',
|
||||
'Vegetation Layer Blocker (Mesh)': 'Mesh'
|
||||
}
|
||||
|
||||
# For every gradient generator component, verify that they are incompatible
|
||||
# which each vegetation area component
|
||||
for component_name in gradient_generators:
|
||||
for vegetation_area_name in vegetation_areas:
|
||||
# Create a new Entity in the level
|
||||
entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Most of these need a shape, so use a Box Shape
|
||||
hydra.add_component('Box Shape', entity_id)
|
||||
# For every gradient generator component, verify that they are incompatible
|
||||
# which each vegetation area component
|
||||
for component_name in gradient_generators:
|
||||
for vegetation_area_name in vegetation_areas:
|
||||
# Create a new Entity in the level
|
||||
entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
|
||||
|
||||
# Add the specific vegetation area dependencies (if necessary)
|
||||
if vegetation_area_name in area_dependencies:
|
||||
hydra.add_component(area_dependencies[vegetation_area_name], entity_id)
|
||||
# Most of these need a shape, so use a Box Shape
|
||||
hydra.add_component('Box Shape', entity_id)
|
||||
|
||||
# Add the vegetation area component we are validating against, then add the
|
||||
# gradient generator afterwards, so that the gradient generator will actually
|
||||
# be disabled (if it was present before, it would only get deactivated instead of disabled
|
||||
# by the vegetation area)
|
||||
area_component = hydra.add_component(vegetation_area_name, entity_id)
|
||||
gradient_component = hydra.add_component(component_name, entity_id)
|
||||
# Add the specific vegetation area dependencies (if necessary)
|
||||
if vegetation_area_name in area_dependencies:
|
||||
hydra.add_component(area_dependencies[vegetation_area_name], entity_id)
|
||||
|
||||
# Verify the gradient generator component is disabled since the vegetation area is incompatible
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_component)
|
||||
self.test_success = self.test_success and not active
|
||||
if not active:
|
||||
self.log(f"{component_name} is disabled before removing {vegetation_area_name} component")
|
||||
# Add the vegetation area component we are validating against, then add the
|
||||
# gradient generator afterwards, so that the gradient generator will actually
|
||||
# be disabled (if it was present before, it would only get deactivated instead of disabled
|
||||
# by the vegetation area)
|
||||
area_component = hydra.add_component(vegetation_area_name, entity_id)
|
||||
gradient_component = hydra.add_component(component_name, entity_id)
|
||||
|
||||
# Remove the vegetation area component
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [area_component])
|
||||
# Verify the gradient generator component is disabled since the vegetation area is incompatible
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_component)
|
||||
component_is_disabled = (
|
||||
f"{component_name} is disabled before removing {vegetation_area_name} component",
|
||||
f"{component_name} is unexpectedly enabled before removing {vegetation_area_name} component"
|
||||
)
|
||||
Report.result(component_is_disabled, not active)
|
||||
|
||||
# Add required dependencies for our gradient generators after the vegetation
|
||||
# area has been removed, because the transform modifier is also incompatible
|
||||
# with the vegetation areas
|
||||
if component_name in require_transform_modifiers:
|
||||
hydra.add_component('Gradient Transform Modifier', entity_id)
|
||||
# Remove the vegetation area component
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [area_component])
|
||||
|
||||
# Verify the gradient generator component is enabled now that the vegetation area is gone
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_component)
|
||||
self.test_success = self.test_success and active
|
||||
if active:
|
||||
self.log(f"{component_name} is enabled after removing {vegetation_area_name} component")
|
||||
# Add required dependencies for our gradient generators after the vegetation
|
||||
# area has been removed, because the transform modifier is also incompatible
|
||||
# with the vegetation areas
|
||||
if component_name in require_transform_modifiers:
|
||||
hydra.add_component('Gradient Transform Modifier', entity_id)
|
||||
|
||||
# Verify the gradient generator component is enabled now that the vegetation area is gone
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_component)
|
||||
component_is_enabled = (
|
||||
f"{component_name} is enabled after removing {vegetation_area_name} component",
|
||||
f"{component_name} is unexpectedly disabled after removing {vegetation_area_name} component"
|
||||
)
|
||||
Report.result(component_is_enabled, active)
|
||||
|
||||
|
||||
test = TestGradientGeneratorIncompatibilities()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientGenerators_Incompatibilities)
|
||||
|
||||
+133
-135
@@ -4,164 +4,162 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.paths
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
|
||||
class TestGradientModifiersIncompatibilities(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientModifiersIncompatibilities", args=["level"])
|
||||
def GradientModifiers_Incompatibilities():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that components are disabled when conflicting components are present on the same entity.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that components are disabled when conflicting components are present on the same entity.
|
||||
Expected Behavior:
|
||||
Gradient Modifier components are incompatible with Vegetation area components.
|
||||
|
||||
Expected Behavior:
|
||||
Gradient Modifier components are incompatible with Vegetation area components.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Create a new entity in the level
|
||||
3) Add each Gradient Modifier component to an entity, and add a Vegetation Area component to the same entity
|
||||
4) Verify that components are only enabled when entity is free of a conflicting component
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Create a new entity in the level
|
||||
3) Add each Gradient Modifier component to an entity, and add a Vegetation Area component to the same entity
|
||||
4) Verify that components are only enabled when entity is free of a conflicting component
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
:return: None
|
||||
"""
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
|
||||
gradient_generators = [
|
||||
'Altitude Gradient',
|
||||
'Constant Gradient',
|
||||
'FastNoise Gradient',
|
||||
'Image Gradient',
|
||||
'Perlin Noise Gradient',
|
||||
'Random Noise Gradient',
|
||||
'Shape Falloff Gradient',
|
||||
'Slope Gradient',
|
||||
'Surface Mask Gradient'
|
||||
]
|
||||
require_transform_modifiers = [
|
||||
'FastNoise Gradient',
|
||||
'Image Gradient',
|
||||
'Perlin Noise Gradient',
|
||||
'Random Noise Gradient'
|
||||
]
|
||||
gradient_modifiers = [
|
||||
'Dither Gradient Modifier',
|
||||
'Gradient Mixer',
|
||||
'Invert Gradient Modifier',
|
||||
'Levels Gradient Modifier',
|
||||
'Posterize Gradient Modifier',
|
||||
'Smooth-Step Gradient Modifier',
|
||||
'Threshold Gradient Modifier'
|
||||
]
|
||||
vegetation_areas = [
|
||||
'Vegetation Layer Spawner',
|
||||
'Vegetation Layer Blender',
|
||||
'Vegetation Layer Blocker',
|
||||
'Vegetation Layer Blocker (Mesh)'
|
||||
]
|
||||
area_dependencies = {
|
||||
'Vegetation Layer Spawner': 'Vegetation Asset List',
|
||||
'Vegetation Layer Blocker (Mesh)': 'Mesh'
|
||||
}
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
gradient_generators = [
|
||||
'Altitude Gradient',
|
||||
'Constant Gradient',
|
||||
'FastNoise Gradient',
|
||||
'Image Gradient',
|
||||
'Perlin Noise Gradient',
|
||||
'Random Noise Gradient',
|
||||
'Shape Falloff Gradient',
|
||||
'Slope Gradient',
|
||||
'Surface Mask Gradient'
|
||||
]
|
||||
require_transform_modifiers = [
|
||||
'FastNoise Gradient',
|
||||
'Image Gradient',
|
||||
'Perlin Noise Gradient',
|
||||
'Random Noise Gradient'
|
||||
]
|
||||
gradient_modifiers = [
|
||||
'Dither Gradient Modifier',
|
||||
'Gradient Mixer',
|
||||
'Invert Gradient Modifier',
|
||||
'Levels Gradient Modifier',
|
||||
'Posterize Gradient Modifier',
|
||||
'Smooth-Step Gradient Modifier',
|
||||
'Threshold Gradient Modifier'
|
||||
]
|
||||
vegetation_areas = [
|
||||
'Vegetation Layer Spawner',
|
||||
'Vegetation Layer Blender',
|
||||
'Vegetation Layer Blocker',
|
||||
'Vegetation Layer Blocker (Mesh)'
|
||||
]
|
||||
area_dependencies = {
|
||||
'Vegetation Layer Spawner': 'Vegetation Asset List',
|
||||
'Vegetation Layer Blocker (Mesh)': 'Mesh'
|
||||
}
|
||||
|
||||
# For every gradient modifier component, verify that they are incompatible
|
||||
# which each vegetation area and gradient generator/modifier component
|
||||
all_gradients = gradient_modifiers + gradient_generators
|
||||
for component_name in gradient_modifiers:
|
||||
for vegetation_area_name in vegetation_areas:
|
||||
# Create a new Entity in the level
|
||||
entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Most of these need a shape, so use a Box Shape
|
||||
hydra.add_component('Box Shape', entity_id)
|
||||
# For every gradient modifier component, verify that they are incompatible
|
||||
# which each vegetation area and gradient generator/modifier component
|
||||
all_gradients = gradient_modifiers + gradient_generators
|
||||
for component_name in gradient_modifiers:
|
||||
for vegetation_area_name in vegetation_areas:
|
||||
# Create a new Entity in the level
|
||||
entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
|
||||
|
||||
# Add the specific vegetation area dependencies (if necessary)
|
||||
if vegetation_area_name in area_dependencies:
|
||||
hydra.add_component(area_dependencies[vegetation_area_name], entity_id)
|
||||
# Most of these need a shape, so use a Box Shape
|
||||
hydra.add_component('Box Shape', entity_id)
|
||||
|
||||
# Add the vegetation area component we are validating against, then add the
|
||||
# gradient modifier afterwards, so that the gradient modifier will actually
|
||||
# be disabled (if it was present before, it would only get deactivated instead of disabled
|
||||
# by the vegetation area)
|
||||
area_component = hydra.add_component(vegetation_area_name, entity_id)
|
||||
gradient_component = hydra.add_component(component_name, entity_id)
|
||||
# Add the specific vegetation area dependencies (if necessary)
|
||||
if vegetation_area_name in area_dependencies:
|
||||
hydra.add_component(area_dependencies[vegetation_area_name], entity_id)
|
||||
|
||||
# Verify the gradient modifier component is disabled since the vegetation area is incompatible
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_component)
|
||||
self.test_success = self.test_success and not active
|
||||
if not active:
|
||||
self.log("{gradient} is disabled before removing {vegetation_area} component".format(gradient=component_name, vegetation_area=vegetation_area_name))
|
||||
# Add the vegetation area component we are validating against, then add the
|
||||
# gradient modifier afterwards, so that the gradient modifier will actually
|
||||
# be disabled (if it was present before, it would only get deactivated instead of disabled
|
||||
# by the vegetation area)
|
||||
area_component = hydra.add_component(vegetation_area_name, entity_id)
|
||||
gradient_component = hydra.add_component(component_name, entity_id)
|
||||
|
||||
# Remove the vegetation area component
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [area_component])
|
||||
# Verify the gradient modifier component is disabled since the vegetation area is incompatible
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_component)
|
||||
component_is_disabled = (
|
||||
f"{component_name} is disabled before removing {vegetation_area_name} component",
|
||||
f"{component_name} is unexpectedly enabled before removing {vegetation_area_name} component"
|
||||
)
|
||||
Report.result(component_is_disabled, not active)
|
||||
|
||||
# Verify the gradient modifier component is enabled now that the vegetation area is gone
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_component)
|
||||
self.test_success = self.test_success and active
|
||||
if active:
|
||||
self.log("{gradient} is enabled after removing {vegetation_area} component".format(gradient=component_name, vegetation_area=vegetation_area_name))
|
||||
# Remove the vegetation area component
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [area_component])
|
||||
|
||||
for gradient_name in all_gradients:
|
||||
# Create a new Entity in the level
|
||||
entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
|
||||
# Verify the gradient modifier component is enabled now that the vegetation area is gone
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_component)
|
||||
component_is_enabled = (
|
||||
f"{component_name} is enabled after removing {vegetation_area_name} component",
|
||||
f"{component_name} is unexpectedly disabled after removing {vegetation_area_name} component"
|
||||
)
|
||||
Report.result(component_is_enabled, active)
|
||||
|
||||
# Most of these need a shape, so use a Box Shape
|
||||
hydra.add_component('Box Shape', entity_id)
|
||||
for gradient_name in all_gradients:
|
||||
# Create a new Entity in the level
|
||||
entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
|
||||
|
||||
# Add the specific gradient generator dependencies (if necessary)
|
||||
conflicting_components = []
|
||||
if gradient_name in require_transform_modifiers:
|
||||
component = hydra.add_component('Gradient Transform Modifier', entity_id)
|
||||
conflicting_components.append(component)
|
||||
# Most of these need a shape, so use a Box Shape
|
||||
hydra.add_component('Box Shape', entity_id)
|
||||
|
||||
# Add the gradient component we are validating against, then add the
|
||||
# gradient modifier afterwards, so that the gradient modifier will actually
|
||||
# be disabled (if it was present before, it would only get deactivated instead of disabled
|
||||
# by the other gradient)
|
||||
component = hydra.add_component(gradient_name, entity_id)
|
||||
# Add the specific gradient generator dependencies (if necessary)
|
||||
conflicting_components = []
|
||||
if gradient_name in require_transform_modifiers:
|
||||
component = hydra.add_component('Gradient Transform Modifier', entity_id)
|
||||
conflicting_components.append(component)
|
||||
gradient_component = hydra.add_component(component_name, entity_id)
|
||||
|
||||
# Verify the gradient modifier component is disabled since the other gradient is incompatible
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_component)
|
||||
self.test_success = self.test_success and not active
|
||||
if not active:
|
||||
self.log("{gradient} is disabled before removing {conflicting_gradient} component".format(gradient=component_name, conflicting_gradient=gradient_name))
|
||||
# Add the gradient component we are validating against, then add the
|
||||
# gradient modifier afterwards, so that the gradient modifier will actually
|
||||
# be disabled (if it was present before, it would only get deactivated instead of disabled
|
||||
# by the other gradient)
|
||||
component = hydra.add_component(gradient_name, entity_id)
|
||||
conflicting_components.append(component)
|
||||
gradient_component = hydra.add_component(component_name, entity_id)
|
||||
|
||||
# Remove the conflicting gradient component (and transform modifier if it was added)
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', conflicting_components)
|
||||
# Verify the gradient modifier component is disabled since the other gradient is incompatible
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_component)
|
||||
component_is_disabled = (
|
||||
f"{component_name} is disabled before removing {gradient_name} component",
|
||||
f"{component_name} is unexpectedly enabled before removing {gradient_name} component"
|
||||
)
|
||||
Report.result(component_is_disabled, not active)
|
||||
|
||||
# Verify the gradient modifier component is enabled now that the other gradient is gone
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_component)
|
||||
self.test_success = self.test_success and active
|
||||
if active:
|
||||
self.log("{gradient} is enabled after removing {conflicting_gradient} component".format(gradient=component_name, conflicting_gradient=gradient_name))
|
||||
# Remove the conflicting gradient component (and transform modifier if it was added)
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', conflicting_components)
|
||||
|
||||
# Verify the gradient modifier component is enabled now that the other gradient is gone
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_component)
|
||||
component_is_enabled = (
|
||||
f"{component_name} is enabled after removing {gradient_name} component",
|
||||
f"{component_name} is unexpectedly disabled after removing {gradient_name} component"
|
||||
)
|
||||
Report.result(component_is_enabled, active)
|
||||
|
||||
|
||||
test = TestGradientModifiersIncompatibilities()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientModifiers_Incompatibilities)
|
||||
|
||||
+98
-102
@@ -5,129 +5,125 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
import azlmbr.entity as EntityId
|
||||
def GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin():
|
||||
"""
|
||||
Summary:
|
||||
A temporary level is created. An entity for each test case is created and added with the corresponding
|
||||
components to verify if the gradient transform is set to the world origin.
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
Expected Behavior:
|
||||
1) Preview image updates to reflect change in transform of the gradient sampler.
|
||||
2) New Preview Position property is exposed, and set to 0,0,0 (world origin).
|
||||
3) Preview Size is set to 1,1,1 by default.
|
||||
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Create entity with Random Noise gradient and verify gradient position after clearing pinned entity
|
||||
3) Create entity with Levels Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
4) Create entity with Posterize Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
5) Create entity with Smooth-Step Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
6) Create entity with Threshold Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
7) Create entity with FastNoise Gradient and verify gradient position after clearing pinned entity
|
||||
8) Create entity with Dither Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
9) Create entity with Invert Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
10) Create entity with Perlin Noise Gradient and verify gradient position after clearing pinned entity
|
||||
|
||||
class TestGradientPreviewSettings(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientPreviewSettings_ClearPinnedEntity", args=["level"])
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
A temporary level is created. An entity for each test case is created and added with the corresponding
|
||||
components to verify if the gradient transform is set to the world origin.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
Expected Behavior:
|
||||
1) Preview image updates to reflect change in transform of the gradient sampler.
|
||||
2) New Preview Position property is exposed, and set to 0,0,0 (world origin).
|
||||
3) Preview Size is set to 1,1,1 by default.
|
||||
import sys
|
||||
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Create entity with Random Noise gradient and verify gradient position after clearing pinned entity
|
||||
3) Create entity with Levels Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
4) Create entity with Posterize Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
5) Create entity with Smooth-Step Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
6) Create entity with Threshold Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
7) Create entity with FastNoise Gradient and verify gradient position after clearing pinned entity
|
||||
8) Create entity with Dither Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
9) Create entity with Invert Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
10) Create entity with Perlin Noise Gradient and verify gradient position after clearing pinned entity
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.math as math
|
||||
import azlmbr.entity as EntityId
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
:return: None
|
||||
"""
|
||||
WORLD_ORIGIN = math.Vector3(0.0, 0.0, 0.0)
|
||||
EXPECTED_SIZE = math.Vector3(1.0, 1.0, 1.0)
|
||||
CLOSE_THRESHOLD = sys.float_info.min
|
||||
|
||||
WORLD_ORIGIN = math.Vector3(0.0, 0.0, 0.0)
|
||||
EXPECTED_SIZE = math.Vector3(1.0, 1.0, 1.0)
|
||||
CLOSE_THRESHOLD = sys.float_info.min
|
||||
def create_entity(entity_name, components_to_add):
|
||||
entity_position = math.Vector3(125.0, 136.0, 32.0)
|
||||
entity_id = editor.ToolsApplicationRequestBus(
|
||||
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
|
||||
)
|
||||
entity = hydra.Entity(entity_name, entity_id)
|
||||
if entity_id.IsValid():
|
||||
print(f"{entity_name} entity Created")
|
||||
entity.components = []
|
||||
for component in components_to_add:
|
||||
entity.components.append(hydra.add_component(component, entity_id))
|
||||
return entity
|
||||
|
||||
def create_entity(enity_name, components_to_add):
|
||||
entity_position = math.Vector3(125.0, 136.0, 32.0)
|
||||
entity_id = editor.ToolsApplicationRequestBus(
|
||||
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
|
||||
def clear_entityid_check_position(entity_name, components_to_add, check_preview_size=False):
|
||||
entity = create_entity(entity_name, components_to_add)
|
||||
hydra.get_set_test(entity, 0, "Preview Settings|Pin Preview to Shape", EntityId.EntityId())
|
||||
preview_position = hydra.get_component_property_value(
|
||||
entity.components[0], "Preview Settings|Preview Position"
|
||||
)
|
||||
preview_set_to_origin = (
|
||||
f"{entity_name}: Preview Position set to world origin",
|
||||
f"{entity_name}: Preview Position set to unexpected coords"
|
||||
)
|
||||
Report.result(preview_set_to_origin, preview_position.IsClose(WORLD_ORIGIN, CLOSE_THRESHOLD))
|
||||
if check_preview_size:
|
||||
preview_size = hydra.get_component_property_value(entity.components[0], "Preview Settings|Preview Size")
|
||||
preview_size_default_set = (
|
||||
f"{entity_name}: Preview Size set as expected",
|
||||
f"{entity_name}: Preview Size set to unexpected value. Expected {EXPECTED_SIZE}, Found {preview_size}"
|
||||
)
|
||||
entity = hydra.Entity(enity_name, entity_id)
|
||||
if entity_id.IsValid():
|
||||
print(f"{enity_name} entity Created")
|
||||
entity.components = []
|
||||
for component in components_to_add:
|
||||
entity.components.append(hydra.add_component(component, entity_id))
|
||||
return entity
|
||||
Report.result(preview_size_default_set, preview_size.IsClose(EXPECTED_SIZE, CLOSE_THRESHOLD))
|
||||
return entity
|
||||
|
||||
def clear_entityid_check_position(entity_name, components_to_add, check_preview_size=False):
|
||||
entity = create_entity(entity_name, components_to_add)
|
||||
hydra.get_set_test(entity, 0, "Preview Settings|Pin Preview to Shape", EntityId.EntityId())
|
||||
preview_position = hydra.get_component_property_value(
|
||||
entity.components[0], "Preview Settings|Preview Position"
|
||||
)
|
||||
if preview_position.IsClose(WORLD_ORIGIN, CLOSE_THRESHOLD):
|
||||
print(f"{entity_name} --- Preview Position set to world origin")
|
||||
if check_preview_size:
|
||||
preview_size = hydra.get_component_property_value(entity.components[0], "Preview Settings|Preview Size")
|
||||
if preview_size.IsClose(EXPECTED_SIZE, CLOSE_THRESHOLD):
|
||||
print(f"{entity_name} --- Preview Size set to (1, 1, 1)")
|
||||
return entity
|
||||
# 1) Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# 1) Open level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
# 2) Create entity with Random Noise gradient and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position(
|
||||
"Random Noise Gradient", ["Random Noise Gradient", "Gradient Transform Modifier", "Box Shape"], True
|
||||
)
|
||||
|
||||
# 2) Create entity with Random Noise gradient and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position(
|
||||
"Random Noise Gradient", ["Random Noise Gradient", "Gradient Transform Modifier", "Box Shape"], True
|
||||
)
|
||||
# 3) Create entity with Levels Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position("Levels Gradient Modifier", ["Levels Gradient Modifier"])
|
||||
|
||||
# 3) Create entity with Levels Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position("Levels Gradient Modifier", ["Levels Gradient Modifier"])
|
||||
# 4) Create entity with Posterize Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position("Posterize Gradient Modifier", ["Posterize Gradient Modifier"])
|
||||
|
||||
# 4) Create entity with Posterize Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position("Posterize Gradient Modifier", ["Posterize Gradient Modifier"])
|
||||
# 5) Create entity with Smooth-Step Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position("Smooth-Step Gradient Modifier", ["Smooth-Step Gradient Modifier"])
|
||||
|
||||
# 5) Create entity with Smooth-Step Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position("Smooth-Step Gradient Modifier", ["Smooth-Step Gradient Modifier"])
|
||||
# 6) Create entity with Threshold Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position("Threshold Gradient Modifier", ["Threshold Gradient Modifier"])
|
||||
|
||||
# 6) Create entity with Threshold Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position("Threshold Gradient Modifier", ["Threshold Gradient Modifier"])
|
||||
# 7) Create entity with FastNoise Gradient and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position(
|
||||
"FastNoise Gradient", ["FastNoise Gradient", "Gradient Transform Modifier", "Box Shape"], True
|
||||
)
|
||||
|
||||
# 7) Create entity with FastNoise Gradient and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position(
|
||||
"FastNoise Gradient", ["FastNoise Gradient", "Gradient Transform Modifier", "Box Shape"], True
|
||||
)
|
||||
# 8) Create entity with Dither Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position("Dither Gradient Modifier", ["Dither Gradient Modifier"], True)
|
||||
|
||||
# 8) Create entity with Dither Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position("Dither Gradient Modifier", ["Dither Gradient Modifier"], True)
|
||||
# 9) Create entity with Invert Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position("Invert Gradient Modifier", ["Invert Gradient Modifier"])
|
||||
|
||||
# 9) Create entity with Invert Gradient Modifier and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position("Invert Gradient Modifier", ["Invert Gradient Modifier"])
|
||||
|
||||
# 10) Create entity with Perlin Noise Gradient and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position(
|
||||
"Perlin Noise Gradient", ["Perlin Noise Gradient", "Gradient Transform Modifier", "Box Shape"], True
|
||||
)
|
||||
# 10) Create entity with Perlin Noise Gradient and verify gradient position after clearing pinned entity
|
||||
clear_entityid_check_position(
|
||||
"Perlin Noise Gradient", ["Perlin Noise Gradient", "Gradient Transform Modifier", "Box Shape"], True
|
||||
)
|
||||
|
||||
|
||||
test = TestGradientPreviewSettings()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin)
|
||||
|
||||
+70
-79
@@ -5,18 +5,6 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.paths
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
|
||||
class Scoped:
|
||||
def __init__(self, constructor, destructor, *args):
|
||||
@@ -33,81 +21,84 @@ class TestParams:
|
||||
self.accessed_component = accessed_component
|
||||
|
||||
|
||||
class TestGradientPreviewSettings(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientPreviewSettings_DefaultPinnedEntity", args=["level"])
|
||||
def GradientPreviewSettings_DefaultPinnedEntityIsSelf():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies default values for the pinned entity for Gradient Preview settings.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies default values for the pinned entity for Gradient Preview settings.
|
||||
Expected Behavior:
|
||||
Pinned entity is self for all gradient generator/modifiers.
|
||||
|
||||
Expected Behavior:
|
||||
Pinned entity is self for all gradient generator/modifiers.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Create a new entity in the level
|
||||
3) Add each Gradient Generator component to an entity, and verify the Pin Preview to Shape property is set to
|
||||
self
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Create a new entity in the level
|
||||
3) Add each Gradient Generator component to an entity, and verify the Pin Preview to Shape property is set to
|
||||
self
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
:return: None
|
||||
"""
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
|
||||
def execute_test(test_id, function, *args):
|
||||
if function(*args):
|
||||
self.log(test_id + ' has Preview pinned to own Entity result: SUCCESS')
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
def create_entity():
|
||||
return editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
|
||||
|
||||
def delete_entity(entity_id):
|
||||
editor.ToolsApplicationRequestBus(bus.Broadcast, 'DeleteEntityAndAllDescendants', entity_id)
|
||||
|
||||
def attach_components(component_list, entity_id):
|
||||
components = []
|
||||
for i in component_list:
|
||||
components.append(hydra.add_component(i, entity_id))
|
||||
return components
|
||||
|
||||
def validate_id_is_current(param):
|
||||
entity_ptr = Scoped(create_entity, delete_entity)
|
||||
added_components = attach_components(param.required_components, entity_ptr.data)
|
||||
value = hydra.get_component_property_value(added_components[param.accessed_component],
|
||||
'Preview Settings|Pin Preview to Shape')
|
||||
self.test_success = self.test_success and entity_ptr.data.Equal(value)
|
||||
return entity_ptr.data.Equal(value)
|
||||
|
||||
param_list = [
|
||||
TestParams(['Gradient Transform Modifier', 'Box Shape', 'Perlin Noise Gradient'], 2),
|
||||
TestParams(['Random Noise Gradient', 'Gradient Transform Modifier', 'Box Shape'], 0),
|
||||
TestParams(['FastNoise Gradient', 'Gradient Transform Modifier', 'Box Shape'], 0),
|
||||
TestParams(['Dither Gradient Modifier'], 0),
|
||||
TestParams(['Invert Gradient Modifier'], 0),
|
||||
TestParams(['Levels Gradient Modifier'], 0),
|
||||
TestParams(['Posterize Gradient Modifier'], 0),
|
||||
TestParams(['Smooth-Step Gradient Modifier'], 0),
|
||||
TestParams(['Threshold Gradient Modifier'], 0)
|
||||
]
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
def execute_test(test_id, function, *args):
|
||||
pinned_to_self = (
|
||||
f"{test_id} has Preview pinned to self",
|
||||
f"{test_id} has Preview pinned to a different entity"
|
||||
)
|
||||
Report.result(pinned_to_self, function(*args))
|
||||
|
||||
for param in param_list:
|
||||
execute_test(param.required_components[param.accessed_component],
|
||||
validate_id_is_current, param)
|
||||
def create_entity():
|
||||
return editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
|
||||
|
||||
def delete_entity(entity_id):
|
||||
editor.ToolsApplicationRequestBus(bus.Broadcast, 'DeleteEntityAndAllDescendants', entity_id)
|
||||
|
||||
def attach_components(component_list, entity_id):
|
||||
components = []
|
||||
for i in component_list:
|
||||
components.append(hydra.add_component(i, entity_id))
|
||||
return components
|
||||
|
||||
def validate_id_is_current(param):
|
||||
entity_ptr = Scoped(create_entity, delete_entity)
|
||||
added_components = attach_components(param.required_components, entity_ptr.data)
|
||||
value = hydra.get_component_property_value(added_components[param.accessed_component],
|
||||
'Preview Settings|Pin Preview to Shape')
|
||||
return entity_ptr.data.Equal(value)
|
||||
|
||||
param_list = [
|
||||
TestParams(['Gradient Transform Modifier', 'Box Shape', 'Perlin Noise Gradient'], 2),
|
||||
TestParams(['Random Noise Gradient', 'Gradient Transform Modifier', 'Box Shape'], 0),
|
||||
TestParams(['FastNoise Gradient', 'Gradient Transform Modifier', 'Box Shape'], 0),
|
||||
TestParams(['Dither Gradient Modifier'], 0),
|
||||
TestParams(['Invert Gradient Modifier'], 0),
|
||||
TestParams(['Levels Gradient Modifier'], 0),
|
||||
TestParams(['Posterize Gradient Modifier'], 0),
|
||||
TestParams(['Smooth-Step Gradient Modifier'], 0),
|
||||
TestParams(['Threshold Gradient Modifier'], 0)
|
||||
]
|
||||
|
||||
# 1) Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
for param in param_list:
|
||||
execute_test(param.required_components[param.accessed_component],
|
||||
validate_id_is_current, param)
|
||||
|
||||
|
||||
test = TestGradientPreviewSettings()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientPreviewSettings_DefaultPinnedEntityIsSelf)
|
||||
|
||||
+67
-77
@@ -5,92 +5,82 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
import azlmbr.entity as EntityId
|
||||
def GradientSampling_GradientReferencesAddRemoveSuccessfully():
|
||||
"""
|
||||
Summary:
|
||||
An existing gradient generator can be pinned and cleared to/from the Gradient Entity Id field
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
Expected Behavior:
|
||||
Gradient generator is assigned to the Gradient Entity Id field.
|
||||
Gradient generator is removed from the field.
|
||||
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Create a new entity with components "Random Noise Gradient", "Gradient Transform Modifier" and "Box Shape"
|
||||
3) Create a new entity with Gradient Modifier's, pin and clear the random noise entity id to the Gradient Id
|
||||
field in Gradient Modifier
|
||||
|
||||
class TestGradientSampling(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientSampling_GradientReferences", args=["level"])
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
An existing gradient generator can be pinned and cleared to/from the Gradient Entity Id field
|
||||
:return: None
|
||||
"""
|
||||
|
||||
Expected Behavior:
|
||||
Gradient generator is assigned to the Gradient Entity Id field.
|
||||
Gradient generator is removed from the field.
|
||||
import azlmbr.math as math
|
||||
import azlmbr.entity as EntityId
|
||||
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Create a new entity with components "Random Noise Gradient", "Gradient Transform Modifier" and "Box Shape"
|
||||
3) Create a new entity with Gradient Modifier's, pin and clear the random noise entity id to the Gradient Id
|
||||
field in Gradient Modifier
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
def modifier_pin_clear_to_gradiententityid(modifier):
|
||||
entity_position = math.Vector3(125.0, 136.0, 32.0)
|
||||
component_to_add = [modifier]
|
||||
gradient_modifier = hydra.Entity(modifier)
|
||||
gradient_modifier.create_entity(entity_position, component_to_add)
|
||||
gradient_modifier.get_set_test(0, "Configuration|Gradient|Gradient Entity Id", random_noise.id)
|
||||
entity = hydra.get_component_property_value(
|
||||
gradient_modifier.components[0], "Configuration|Gradient|Gradient Entity Id"
|
||||
)
|
||||
if entity.Equal(random_noise.id):
|
||||
print(f"Gradient Generator is pinned to the {modifier} successfully")
|
||||
else:
|
||||
print(f"Failed to pin Gradient Generator to the {modifier}")
|
||||
hydra.get_set_test(gradient_modifier, 0, "Configuration|Gradient|Gradient Entity Id", EntityId.EntityId())
|
||||
entity = hydra.get_component_property_value(
|
||||
gradient_modifier.components[0], "Configuration|Gradient|Gradient Entity Id"
|
||||
)
|
||||
if entity.Equal(EntityId.EntityId()):
|
||||
print(f"Gradient Generator is cleared from the {modifier} successfully")
|
||||
else:
|
||||
print(f"Failed to clear Gradient Generator from the {modifier}")
|
||||
|
||||
# 1) Open level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
|
||||
# 2) Create a new entity with components "Random Noise Gradient", "Gradient Transform Modifier" and "Box Shape"
|
||||
def modifier_pin_clear_to_gradiententityid(modifier):
|
||||
entity_position = math.Vector3(125.0, 136.0, 32.0)
|
||||
components_to_add = ["Random Noise Gradient", "Gradient Transform Modifier", "Box Shape"]
|
||||
random_noise = hydra.Entity("Random_Noise")
|
||||
random_noise.create_entity(entity_position, components_to_add)
|
||||
component_to_add = [modifier]
|
||||
gradient_modifier = hydra.Entity(modifier)
|
||||
gradient_modifier.create_entity(entity_position, component_to_add)
|
||||
gradient_modifier.get_set_test(0, "Configuration|Gradient|Gradient Entity Id", random_noise.id)
|
||||
entity = hydra.get_component_property_value(
|
||||
gradient_modifier.components[0], "Configuration|Gradient|Gradient Entity Id"
|
||||
)
|
||||
gradient_pinned_to_modifier = (
|
||||
f"Gradient Generator is pinned to the {modifier} successfully",
|
||||
f"Failed to pin Gradient Generator to the {modifier}"
|
||||
)
|
||||
Report.result(gradient_pinned_to_modifier, entity.Equal(random_noise.id))
|
||||
hydra.get_set_test(gradient_modifier, 0, "Configuration|Gradient|Gradient Entity Id", EntityId.EntityId())
|
||||
entity = hydra.get_component_property_value(
|
||||
gradient_modifier.components[0], "Configuration|Gradient|Gradient Entity Id"
|
||||
)
|
||||
gradient_cleared_from_modifier = (
|
||||
f"Gradient Generator is cleared from the {modifier} successfully",
|
||||
f"Failed to clear Gradient Generator from the {modifier}"
|
||||
)
|
||||
Report.result(gradient_cleared_from_modifier, entity.Equal(EntityId.EntityId()))
|
||||
|
||||
# 3) Create a new entity with Gradient Modifier's, pin and clear the random noise entity id to the Gradient Id
|
||||
# field in Gradient Modifier
|
||||
modifier_pin_clear_to_gradiententityid("Dither Gradient Modifier")
|
||||
modifier_pin_clear_to_gradiententityid("Invert Gradient Modifier")
|
||||
modifier_pin_clear_to_gradiententityid("Levels Gradient Modifier")
|
||||
modifier_pin_clear_to_gradiententityid("Posterize Gradient Modifier")
|
||||
modifier_pin_clear_to_gradiententityid("Smooth-Step Gradient Modifier")
|
||||
modifier_pin_clear_to_gradiententityid("Threshold Gradient Modifier")
|
||||
# 1) Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# 2) Create a new entity with components "Random Noise Gradient", "Gradient Transform Modifier" and "Box Shape"
|
||||
entity_position = math.Vector3(125.0, 136.0, 32.0)
|
||||
components_to_add = ["Random Noise Gradient", "Gradient Transform Modifier", "Box Shape"]
|
||||
random_noise = hydra.Entity("Random_Noise")
|
||||
random_noise.create_entity(entity_position, components_to_add)
|
||||
|
||||
# 3) Create a new entity with Gradient Modifier's, pin and clear the random noise entity id to the Gradient Id
|
||||
# field in Gradient Modifier
|
||||
modifier_pin_clear_to_gradiententityid("Dither Gradient Modifier")
|
||||
modifier_pin_clear_to_gradiententityid("Invert Gradient Modifier")
|
||||
modifier_pin_clear_to_gradiententityid("Levels Gradient Modifier")
|
||||
modifier_pin_clear_to_gradiententityid("Posterize Gradient Modifier")
|
||||
modifier_pin_clear_to_gradiententityid("Smooth-Step Gradient Modifier")
|
||||
modifier_pin_clear_to_gradiententityid("Threshold Gradient Modifier")
|
||||
|
||||
|
||||
test = TestGradientSampling()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientSampling_GradientReferencesAddRemoveSuccessfully)
|
||||
|
||||
+95
-105
@@ -5,114 +5,104 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import azlmbr.math as math
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.paths
|
||||
import azlmbr.editor as editor
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
|
||||
class TestGradientSurfaceTagEmitterDependencies(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(
|
||||
self, log_prefix="GradientSurfaceTagEmitter_ComponentDependencies", args=["level"]
|
||||
def GradientSurfaceTagEmitter_ComponentDependencies():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Gradient Surface Tag Emitter component is dependent on a gradient component.
|
||||
|
||||
Expected Result:
|
||||
Gradient Surface Tag Emitter component is disabled until a Gradient Generator, Modifier or Gradient Reference
|
||||
component (and any sub-dependencies) is added to the entity.
|
||||
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Create a new entity with a Gradient Surface Tag Emitter component
|
||||
3) Verify the component is disabled until a dependent component is also added to the entity
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import azlmbr.math as math
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.editor as editor
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
def is_enabled(EntityComponentIdPair):
|
||||
return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair)
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Create an entity with Gradient Surface Tag Emitter component
|
||||
position = math.Vector3(512.0, 512.0, 32.0)
|
||||
gradient = hydra.Entity("gradient")
|
||||
gradient.create_entity(position, ["Gradient Surface Tag Emitter"])
|
||||
|
||||
# Make sure Gradient Surface Tag Emitter is disabled
|
||||
gradient_surface_tag_disabled = (
|
||||
"Gradient Surface Tag Emitter is Disabled",
|
||||
"Gradient Surface Tag Emitter is Enabled, but should be Disabled without dependencies met"
|
||||
)
|
||||
Report.result(gradient_surface_tag_disabled, not is_enabled(gradient.components[0]))
|
||||
|
||||
# Verify Gradient Surface Tag Emitter component is enabled after adding Gradient, Generator, Modifier
|
||||
# or Reference component
|
||||
new_components_to_add = [
|
||||
"Dither Gradient Modifier",
|
||||
"Gradient Mixer",
|
||||
"Invert Gradient Modifier",
|
||||
"Levels Gradient Modifier",
|
||||
"Posterize Gradient Modifier",
|
||||
"Smooth-Step Gradient Modifier",
|
||||
"Threshold Gradient Modifier",
|
||||
"Altitude Gradient",
|
||||
"Constant Gradient",
|
||||
"FastNoise Gradient",
|
||||
"Image Gradient",
|
||||
"Perlin Noise Gradient",
|
||||
"Random Noise Gradient",
|
||||
"Reference Gradient",
|
||||
"Shape Falloff Gradient",
|
||||
"Slope Gradient",
|
||||
"Surface Mask Gradient",
|
||||
]
|
||||
for component in new_components_to_add:
|
||||
component_list = ["FastNoise Gradient", "Image Gradient", "Perlin Noise Gradient", "Random Noise Gradient"]
|
||||
if component in component_list:
|
||||
for Component in ["Gradient Transform Modifier", "Box Shape"]:
|
||||
hydra.add_component(Component, gradient.id)
|
||||
typeIdsList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', [component],
|
||||
entity.EntityType().Game)
|
||||
ComponentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', gradient.id, [typeIdsList[0]])
|
||||
Components = ComponentOutcome.GetValue()
|
||||
ComponentIdPair = Components[0]
|
||||
gradient_enabled = is_enabled(gradient.components[0])
|
||||
new_components_enabled = is_enabled(ComponentIdPair)
|
||||
dependencies_met = (
|
||||
f"{component} and Gradient Surface Tag Emitter are enabled",
|
||||
f"{component} and Gradient Surface Tag Emitter are disabled"
|
||||
)
|
||||
Report.result(dependencies_met, new_components_enabled and gradient_enabled)
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Gradient Surface Tag Emitter component is dependent on a gradient component.
|
||||
|
||||
Expected Result:
|
||||
Gradient Surface Tag Emitter component is disabled until a Gradient Generator, Modifier or Gradient Reference
|
||||
component (and any sub-dependencies) is added to the entity.
|
||||
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Create a new entity with a Gradient Surface Tag Emitter component
|
||||
3) Verify the component is disabled until a dependent component is also added to the entity
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
def is_enabled(EntityComponentIdPair):
|
||||
return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair)
|
||||
|
||||
# Create empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
|
||||
# Create an entity with Gradient Surface Tag Emitter component
|
||||
position = math.Vector3(512.0, 512.0, 32.0)
|
||||
gradient = hydra.Entity("gradient")
|
||||
gradient.create_entity(position, ["Gradient Surface Tag Emitter"])
|
||||
|
||||
# Make sure Gradient Surface Tag Emitter is disabled
|
||||
is_enable = is_enabled(gradient.components[0])
|
||||
if not is_enable:
|
||||
self.log("Gradient Surface Tag Emitter is Disabled")
|
||||
elif not is_enable:
|
||||
self.log("Gradient Surface Tag Emitter is Enabled, but should be Disabled without dependencies met")
|
||||
|
||||
# Verify Gradient Surface Tag Emitter component is enabled after adding Gradient, Generator, Modifier
|
||||
# or Reference component
|
||||
new_components_to_add = [
|
||||
"Dither Gradient Modifier",
|
||||
"Gradient Mixer",
|
||||
"Invert Gradient Modifier",
|
||||
"Levels Gradient Modifier",
|
||||
"Posterize Gradient Modifier",
|
||||
"Smooth-Step Gradient Modifier",
|
||||
"Threshold Gradient Modifier",
|
||||
"Altitude Gradient",
|
||||
"Constant Gradient",
|
||||
"FastNoise Gradient",
|
||||
"Image Gradient",
|
||||
"Perlin Noise Gradient",
|
||||
"Random Noise Gradient",
|
||||
"Reference Gradient",
|
||||
"Shape Falloff Gradient",
|
||||
"Slope Gradient",
|
||||
"Surface Mask Gradient",
|
||||
]
|
||||
for component in new_components_to_add:
|
||||
component_list = ["FastNoise Gradient", "Image Gradient", "Perlin Noise Gradient", "Random Noise Gradient"]
|
||||
if component in component_list:
|
||||
for Component in ["Gradient Transform Modifier", "Box Shape"]:
|
||||
hydra.add_component(Component, gradient.id)
|
||||
typeIdsList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', [component],
|
||||
entity.EntityType().Game)
|
||||
ComponentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', gradient.id, [typeIdsList[0]])
|
||||
Components = ComponentOutcome.GetValue()
|
||||
ComponentIdPair = Components[0]
|
||||
gradient_enabled = new_components_enabled = False
|
||||
gradient_enabled = is_enabled(gradient.components[0])
|
||||
new_components_enabled = is_enabled(ComponentIdPair)
|
||||
if new_components_enabled and gradient_enabled:
|
||||
self.log(f"{component} and Gradient Surface Tag Emitter are enabled")
|
||||
else:
|
||||
self.log(f"{component} and Gradient Surface Tag Emitter are disabled")
|
||||
if component in component_list:
|
||||
hydra.remove_component("Gradient Transform Modifier", gradient.id)
|
||||
hydra.remove_component("Box Shape", gradient.id)
|
||||
hydra.remove_component(component, gradient.id)
|
||||
if component in component_list:
|
||||
hydra.remove_component("Gradient Transform Modifier", gradient.id)
|
||||
hydra.remove_component("Box Shape", gradient.id)
|
||||
hydra.remove_component(component, gradient.id)
|
||||
|
||||
|
||||
test = TestGradientSurfaceTagEmitterDependencies()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientSurfaceTagEmitter_ComponentDependencies)
|
||||
|
||||
+60
-66
@@ -5,75 +5,69 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
import azlmbr.surface_data as surface_data
|
||||
def GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully():
|
||||
"""
|
||||
Summary:
|
||||
Entity with Gradient Surface Tag Emitter and Reference Gradient components is created.
|
||||
And new surface tag has been added and removed.
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
Expected Behavior:
|
||||
A new Surface Tag can be added and removed from the component
|
||||
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Create an entity with Gradient Surface Tag Emitter and Reference Gradient components.
|
||||
3) Add/ remove Surface Tags
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import azlmbr.math as math
|
||||
import azlmbr.surface_data as surface_data
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# 1) Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# 2) Create an entity with Gradient Surface Tag Emitter and Reference Gradient components.
|
||||
entity_position = math.Vector3(125.0, 136.0, 32.0)
|
||||
components_to_add = ["Gradient Surface Tag Emitter", "Reference Gradient"]
|
||||
entity = hydra.Entity("entity")
|
||||
entity.create_entity(entity_position, components_to_add)
|
||||
|
||||
# 3) Add/ remove Surface Tags
|
||||
tag = surface_data.SurfaceTag()
|
||||
tag.SetTag("water")
|
||||
pte = hydra.get_property_tree(entity.components[0])
|
||||
path = "Configuration|Extended Tags"
|
||||
pte.add_container_item(path, 0, tag)
|
||||
success = helper.wait_for_condition(lambda: pte.get_container_count(path).GetValue() == 1, 1.0)
|
||||
tag_added_to_container = (
|
||||
"Successfully added surface tag",
|
||||
"Failed to add surface tag"
|
||||
)
|
||||
Report.result(tag_added_to_container, success)
|
||||
pte.remove_container_item(path, 0)
|
||||
success = helper.wait_for_condition(lambda: pte.get_container_count(path).GetValue() == 0, 1.0)
|
||||
tag_removed_from_container = (
|
||||
"Successfully removed surface tag",
|
||||
"Failed to remove surface tag"
|
||||
)
|
||||
Report.result(tag_removed_from_container, success)
|
||||
|
||||
|
||||
class TestGradientSurfaceTagEmitter(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSucessfully",
|
||||
args=["level"])
|
||||
if __name__ == "__main__":
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
Entity with Gradient Surface Tag Emitter and Reference Gradient components is created.
|
||||
And new surface tag has been added and removed.
|
||||
|
||||
Expected Behavior:
|
||||
A new Surface Tag can be added and removed from the component
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully)
|
||||
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Create an entity with Gradient Surface Tag Emitter and Reference Gradient components.
|
||||
3) Add/ remove Surface Tags
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
# 1) Open level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
|
||||
# 2) Create an entity with Gradient Surface Tag Emitter and Reference Gradient components.
|
||||
entity_position = math.Vector3(125.0, 136.0, 32.0)
|
||||
components_to_add = ["Gradient Surface Tag Emitter", "Reference Gradient"]
|
||||
entity = hydra.Entity("entity")
|
||||
entity.create_entity(entity_position, components_to_add)
|
||||
|
||||
# 3) Add/ remove Surface Tags
|
||||
tag = surface_data.SurfaceTag()
|
||||
tag.SetTag("water")
|
||||
pte = hydra.get_property_tree(entity.components[0])
|
||||
path = "Configuration|Extended Tags"
|
||||
pte.add_container_item(path, 0, tag)
|
||||
success = self.wait_for_condition(lambda: pte.get_container_count(path).GetValue() == 1)
|
||||
self.test_success = self.test_success and success
|
||||
print(f"Added SurfaceTag: container count is {pte.get_container_count(path).GetValue()}")
|
||||
pte.remove_container_item(path, 0)
|
||||
success = self.wait_for_condition(lambda: pte.get_container_count(path).GetValue() == 0)
|
||||
self.test_success = self.test_success and success
|
||||
print(f"Removed SurfaceTag: container count is {pte.get_container_count(path).GetValue()}")
|
||||
|
||||
|
||||
test = TestGradientSurfaceTagEmitter()
|
||||
test.run()
|
||||
|
||||
+81
-97
@@ -5,118 +5,102 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.math as math
|
||||
import azlmbr.entity as EntityId
|
||||
def GradientTransform_ComponentIncompatibleWithExpectedGradients():
|
||||
"""
|
||||
Summary:
|
||||
A New level is created. A New entity is created with components Gradient Transform Modifier and Box Shape.
|
||||
Adding components Constant Gradient, Altitude Gradient, Gradient Mixer, Reference Gradient, Shape
|
||||
Falloff Gradient, Slope Gradient and Surface Mask Gradient to the same entity.
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
Expected Behavior:
|
||||
All added components are disabled and inform the user that they are incompatible with the Gradient Transform
|
||||
Modifier
|
||||
|
||||
Test Steps:
|
||||
1) Create level
|
||||
2) Create a new entity with components Gradient Transform Modifier and Box Shape
|
||||
3) Make sure all components are enabled in Entity
|
||||
4) Add Constant Gradient, Altitude Gradient, Gradient Mixer, Reference Gradient, Shape
|
||||
Falloff Gradient, Slope Gradient and Surface Mask Gradient to the same entity
|
||||
5) Make sure all newly added components are disabled
|
||||
|
||||
class TestGradientTransform_ComponentIncompatibleWithExpectedGradients(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientTransform_ComponentIncompatibleWithExpectedGradients",
|
||||
args=["level"])
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
A New level is created. A New entity is created with components Gradient Transform Modifier and Box Shape.
|
||||
Adding components Constant Gradient, Altitude Gradient, Gradient Mixer, Reference Gradient, Shape
|
||||
Falloff Gradient, Slope Gradient and Surface Mask Gradient to the same entity.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
Expected Behavior:
|
||||
All added components are disabled and inform the user that they are incompatible with the Gradient Transform
|
||||
Modifier
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.math as math
|
||||
import azlmbr.entity as EntityId
|
||||
|
||||
Test Steps:
|
||||
1) Create level
|
||||
2) Create a new entity with components Gradient Transform Modifier and Box Shape
|
||||
3) Make sure all components are enabled in Entity
|
||||
4) Add Constant Gradient, Altitude Gradient, Gradient Mixer, Reference Gradient, Shape
|
||||
Falloff Gradient, Slope Gradient and Surface Mask Gradient to the same entity
|
||||
5) Make sure all newly added components are disabled
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
def is_enabled(EntityComponentIdPair):
|
||||
return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair)
|
||||
|
||||
:return: None
|
||||
"""
|
||||
# 1) Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
def is_enabled(EntityComponentIdPair):
|
||||
return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair)
|
||||
# 2) Create a new entity with components Gradient Transform Modifier and Box Shape
|
||||
entity_position = math.Vector3(125.0, 136.0, 32.0)
|
||||
components_to_add = ["Gradient Transform Modifier", "Box Shape"]
|
||||
gradient_id = editor.ToolsApplicationRequestBus(
|
||||
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
|
||||
)
|
||||
gradient = hydra.Entity("gradient", gradient_id)
|
||||
|
||||
# 1) Create level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
gradient.components = []
|
||||
|
||||
for component in components_to_add:
|
||||
gradient.components.append(hydra.add_component(component, gradient_id))
|
||||
entity_created = (
|
||||
"Entity created successfully",
|
||||
"Failed to create entity"
|
||||
)
|
||||
Report.critical_result(entity_created, gradient_id.isValid())
|
||||
|
||||
# 3) Make sure all components are enabled in Entity
|
||||
index = 0
|
||||
for component in components_to_add:
|
||||
components_enabled = (
|
||||
f"{component} is enabled",
|
||||
f"{component} is unexpectedly disabled"
|
||||
)
|
||||
Report.critical_result(components_enabled, is_enabled(gradient.components[index]))
|
||||
index += 1
|
||||
|
||||
# 2) Create a new entity with components Gradient Transform Modifier and Box Shape
|
||||
entity_position = math.Vector3(125.0, 136.0, 32.0)
|
||||
components_to_add = ["Gradient Transform Modifier", "Box Shape"]
|
||||
gradient_id = editor.ToolsApplicationRequestBus(
|
||||
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
|
||||
# 4) Add Constant Gradient, Altitude Gradient, Gradient Mixer, Reference Gradient, Shape
|
||||
# Falloff Gradient, Slope Gradient and Surface Mask Gradient to the same entity
|
||||
new_components_to_add = [
|
||||
"Constant Gradient",
|
||||
"Altitude Gradient",
|
||||
"Gradient Mixer",
|
||||
"Reference Gradient",
|
||||
"Shape Falloff Gradient",
|
||||
"Slope Gradient",
|
||||
"Surface Mask Gradient",
|
||||
]
|
||||
new_components_enabled = False
|
||||
for component in new_components_to_add:
|
||||
gradient.components.append(hydra.add_component(component, gradient_id))
|
||||
gradient_components_disabled = (
|
||||
f"{component} is disabled",
|
||||
f"{component} is enabled, but should be disabled"
|
||||
)
|
||||
gradient = hydra.Entity("gradient", gradient_id)
|
||||
|
||||
gradient.components = []
|
||||
|
||||
for component in components_to_add:
|
||||
gradient.components.append(hydra.add_component(component, gradient_id))
|
||||
if gradient_id.isValid():
|
||||
self.log("New Entity Created")
|
||||
|
||||
# 3) Make sure all components are enabled in Entity
|
||||
index = 0
|
||||
for component in components_to_add:
|
||||
is_enable = is_enabled(gradient.components[index])
|
||||
if is_enable:
|
||||
self.log(f"{component} is Enabled")
|
||||
self.test_success = self.test_success and is_enable
|
||||
elif not is_enable:
|
||||
self.log(f"{component} is disabled, but it should be enabled")
|
||||
self.test_success = self.test_success and is_enable
|
||||
break
|
||||
index += 1
|
||||
|
||||
# 4) Add Constant Gradient, Altitude Gradient, Gradient Mixer, Reference Gradient, Shape
|
||||
# Falloff Gradient, Slope Gradient and Surface Mask Gradient to the same entity
|
||||
new_components_to_add = [
|
||||
"Constant Gradient",
|
||||
"Altitude Gradient",
|
||||
"Gradient Mixer",
|
||||
"Reference Gradient",
|
||||
"Shape Falloff Gradient",
|
||||
"Slope Gradient",
|
||||
"Surface Mask Gradient",
|
||||
]
|
||||
index = 2
|
||||
new_components_enabled = False
|
||||
for component in new_components_to_add:
|
||||
gradient.components.append(hydra.add_component(component, gradient_id))
|
||||
new_components_enabled = is_enabled(gradient.components[index])
|
||||
if new_components_enabled:
|
||||
self.log(f"{component} is enabled, but should be disabled")
|
||||
break
|
||||
Report.result(gradient_components_disabled, not is_enabled(gradient.components[2]))
|
||||
if not is_enabled(gradient.components[2]):
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, "RemoveComponents", component)
|
||||
|
||||
# 5) Make sure all newly added components are disabled
|
||||
if not new_components_enabled:
|
||||
self.log("All newly added components are incompatible and disabled")
|
||||
self.test_success = self.test_success and not new_components_enabled
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
test = TestGradientTransform_ComponentIncompatibleWithExpectedGradients()
|
||||
test.run()
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientTransform_ComponentIncompatibleWithExpectedGradients)
|
||||
|
||||
+69
-85
@@ -5,104 +5,88 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.math as math
|
||||
import azlmbr.entity as EntityId
|
||||
def GradientTransform_ComponentIncompatibleWithSpawners():
|
||||
"""
|
||||
Summary:
|
||||
A simple level is opened. A New entity is created with components Gradient Transform Modifier and Box Shape.
|
||||
Adding a component Vegetation Layer Spawner to the same entity.
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
Expected Behavior:
|
||||
The Vegetation Layer Spawner is deactivated and it is communicated that it is incompatible with Gradient
|
||||
Transform Modifier
|
||||
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Create a new entity with components Gradient Transform Modifier and Box Shape
|
||||
3) Make sure all components are enabled in Entity
|
||||
4) Add Vegetation Layer Spawner to the same entity
|
||||
5) Make sure newly added component is disabled
|
||||
|
||||
class TestGradientTransform_ComponentIncompatibleWithSpawners(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientTransform_ComponentIncompatibleWithSpawners",
|
||||
args=["level"])
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
A New level is created. A New entity is created with components Gradient Transform Modifier and Box Shape.
|
||||
Adding a component Vegetation Layer Spawner to the same entity.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
Expected Behavior:
|
||||
The Vegetation Layer Spawner is deactivated and it is communicated that it is incompatible with Gradient
|
||||
Transform Modifier
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.math as math
|
||||
import azlmbr.entity as EntityId
|
||||
|
||||
Test Steps:
|
||||
1) Create level
|
||||
2) Create a new entity with components Gradient Transform Modifier and Box Shape
|
||||
3) Make sure all components are enabled in Entity
|
||||
4) Add Vegetation Layer Spawner to the same entity
|
||||
5) Make sure newly added component is disabled
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
def is_enabled(EntityComponentIdPair):
|
||||
return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair)
|
||||
|
||||
:return: None
|
||||
"""
|
||||
# 1) Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
def is_enabled(EntityComponentIdPair):
|
||||
return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", EntityComponentIdPair)
|
||||
# 2) Create a new entity with components Gradient Transform Modifier and Box Shape
|
||||
entity_position = math.Vector3(125.0, 136.0, 32.0)
|
||||
components_to_add = ["Gradient Transform Modifier", "Box Shape"]
|
||||
gradient_id = editor.ToolsApplicationRequestBus(
|
||||
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
|
||||
)
|
||||
gradient = hydra.Entity("gradient", gradient_id)
|
||||
|
||||
# 1) Create level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
gradient.components = []
|
||||
|
||||
for component in components_to_add:
|
||||
gradient.components.append(hydra.add_component(component, gradient_id))
|
||||
entity_created = (
|
||||
"Entity created successfully",
|
||||
"Failed to create entity"
|
||||
)
|
||||
Report.critical_result(entity_created, gradient_id.isValid())
|
||||
|
||||
# 3) Make sure all components are enabled in Entity
|
||||
index = 0
|
||||
for component in components_to_add:
|
||||
components_enabled = (
|
||||
f"{component} is enabled",
|
||||
f"{component} is unexpectedly disabled"
|
||||
)
|
||||
Report.critical_result(components_enabled, is_enabled(gradient.components[index]))
|
||||
index += 1
|
||||
|
||||
# 2) Create a new entity with components Gradient Transform Modifier and Box Shape
|
||||
entity_position = math.Vector3(125.0, 136.0, 32.0)
|
||||
components_to_add = ["Gradient Transform Modifier", "Box Shape"]
|
||||
gradient_id = editor.ToolsApplicationRequestBus(
|
||||
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
|
||||
)
|
||||
gradient = hydra.Entity("gradient", gradient_id)
|
||||
# 4) Add Vegetation Layer Spawner to the same entity
|
||||
gradient.components.append(hydra.add_component("Vegetation Layer Spawner", gradient_id))
|
||||
|
||||
gradient.components = []
|
||||
|
||||
for component in components_to_add:
|
||||
gradient.components.append(hydra.add_component(component, gradient_id))
|
||||
if gradient_id.isValid():
|
||||
self.log("New Entity Created")
|
||||
|
||||
# 3) Make sure all components are enabled in Entity
|
||||
index = 0
|
||||
for component in components_to_add:
|
||||
is_enable = is_enabled(gradient.components[index])
|
||||
if is_enable:
|
||||
self.log(f"{component} is Enabled")
|
||||
self.test_success = self.test_success and is_enable
|
||||
elif not is_enable:
|
||||
self.log(f"{component} is Disabled. But It should be Enabled in an Entity")
|
||||
self.test_success = self.test_success and is_enable
|
||||
break
|
||||
index += 1
|
||||
|
||||
# 4) Add Vegetation Layer Spawner to the same entity
|
||||
new_component_to_add = "Vegetation Layer Spawner"
|
||||
index = 2
|
||||
gradient.components.append(hydra.add_component(new_component_to_add, gradient_id))
|
||||
new_component_enabled = is_enabled(gradient.components[index])
|
||||
|
||||
# 5) Make sure newly added component is disabled
|
||||
if not new_component_enabled:
|
||||
self.log(f"{new_component_to_add} is incompatible and disabled")
|
||||
self.test_success = self.test_success and not new_component_enabled
|
||||
elif new_component_enabled:
|
||||
self.log(f"{new_component_to_add} is compatible and enabled. But It should be Incompatible and disabled")
|
||||
self.test_success = self.test_success and new_component_enabled
|
||||
# 5) Make sure newly added component is disabled
|
||||
spawner_component_disabled = (
|
||||
"Spawner component is disabled",
|
||||
"Spawner component is unexpectedly enabled"
|
||||
)
|
||||
Report.result(spawner_component_disabled, not is_enabled(gradient.components[2]))
|
||||
|
||||
|
||||
test = TestGradientTransform_ComponentIncompatibleWithSpawners()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientTransform_ComponentIncompatibleWithSpawners)
|
||||
|
||||
+64
-69
@@ -5,87 +5,82 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
"""
|
||||
C3430292: Frequency Zoom can manually be set higher than 8.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
import azlmbr.entity as EntityId
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
class Tests:
|
||||
entity_created = (
|
||||
"Entity created successfully",
|
||||
"Failed to create entity"
|
||||
)
|
||||
components_added = (
|
||||
"All expected components added to entity",
|
||||
"Failed to add expected components to entity"
|
||||
)
|
||||
higher_zoom_value_set = (
|
||||
"Frequency Zoom is equal to expected value",
|
||||
"Frequency Zoom is not equal to expected value"
|
||||
)
|
||||
|
||||
|
||||
class TestGradientTransformFrequencyZoom(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientTransform_FrequencyZoomBeyondSliders", args=["level"])
|
||||
def GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange():
|
||||
"""
|
||||
Summary:
|
||||
Frequency Zoom can manually be set higher than 8 in a random noise gradient
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
Frequency Zoom can manually be set higher than 8 in a random noise gradient
|
||||
Expected Behavior:
|
||||
The value properly changes, despite the value being outside of the slider limit
|
||||
|
||||
Expected Behavior:
|
||||
The value properly changes, despite the value being outside of the slider limit
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Create entity
|
||||
3) Add components to the entity
|
||||
4) Set the frequency value of the component
|
||||
5) Verify if the frequency value is set to higher value
|
||||
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Create entity
|
||||
3) Add components to the entity
|
||||
4) Set the frequency value of the component
|
||||
5) Verify if the frequency value is set to higher value
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
:return: None
|
||||
"""
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.math as math
|
||||
import azlmbr.entity as EntityId
|
||||
|
||||
# 1) Open level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# 2) Create entity
|
||||
entity_position = math.Vector3(125.0, 136.0, 32.0)
|
||||
entity_id = editor.ToolsApplicationRequestBus(
|
||||
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
|
||||
)
|
||||
if entity_id.IsValid():
|
||||
print("Entity Created")
|
||||
# 1) Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# 3) Add components to the entity
|
||||
components_to_add = ["Random Noise Gradient", "Gradient Transform Modifier", "Box Shape"]
|
||||
entity = hydra.Entity("entity", entity_id)
|
||||
entity.components = []
|
||||
for component in components_to_add:
|
||||
entity.components.append(hydra.add_component(component, entity_id))
|
||||
print("Components added to the entity")
|
||||
# 2) Create entity
|
||||
entity_position = math.Vector3(125.0, 136.0, 32.0)
|
||||
entity_id = editor.ToolsApplicationRequestBus(
|
||||
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
|
||||
)
|
||||
Report.critical_result(Tests.entity_created, entity_id.IsValid())
|
||||
|
||||
# 4) Set the frequency value of the component
|
||||
hydra.get_set_test(entity, 1, "Configuration|Frequency Zoom", 10)
|
||||
# 3) Add components to the entity
|
||||
components_to_add = ["Random Noise Gradient", "Gradient Transform Modifier", "Box Shape"]
|
||||
entity = hydra.Entity("entity", entity_id)
|
||||
entity.components = []
|
||||
for component in components_to_add:
|
||||
entity.components.append(hydra.add_component(component, entity_id))
|
||||
Report.critical_result(Tests.components_added, len(entity.components) == 3)
|
||||
|
||||
# 5) Verify if the frequency value is set to higher value
|
||||
curr_value = hydra.get_component_property_value(entity.components[1], "Configuration|Frequency Zoom")
|
||||
if curr_value == 10.0:
|
||||
print("Frequency Zoom is equal to expected value")
|
||||
else:
|
||||
print("Frequency Zoom is not equal to expected value")
|
||||
# 4) Set the frequency value of the component
|
||||
hydra.get_set_test(entity, 1, "Configuration|Frequency Zoom", 10)
|
||||
|
||||
# 5) Verify if the frequency value is set to higher value
|
||||
curr_value = hydra.get_component_property_value(entity.components[1], "Configuration|Frequency Zoom")
|
||||
Report.result(Tests.higher_zoom_value_set, curr_value == 10.0)
|
||||
|
||||
|
||||
test = TestGradientTransformFrequencyZoom()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange)
|
||||
|
||||
+64
-66
@@ -4,73 +4,71 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.paths
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
|
||||
class TestGradientTransformRequiresShape(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientTransformRequiresShape", args=["level"])
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Gradient Transform Modifier component is dependent on a shape component.
|
||||
|
||||
Expected Result:
|
||||
Gradient Transform Modifier component is disabled until a shape component is added to the entity.
|
||||
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Create a new entity with a Gradient Transform Modifier component
|
||||
3) Verify the component is disabled until a shape component is also added to the entity
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
|
||||
# Create a new Entity in the level
|
||||
entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
|
||||
|
||||
# Add a Gradient Transform Component (that will be disabled since there is no shape on the Entity)
|
||||
gradient_transform_component = hydra.add_component('Gradient Transform Modifier', entity_id)
|
||||
|
||||
# Verify the Gradient Transform Component is not active before adding the Shape
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_transform_component)
|
||||
self.test_success = self.test_success and not active
|
||||
if not active:
|
||||
self.log("Gradient Transform component is not active without a Shape component on the Entity")
|
||||
|
||||
# Add a Shape component to the same Entity
|
||||
hydra.add_component('Box Shape', entity_id)
|
||||
|
||||
# Check if the Gradient Transform Component is active now after adding the Shape
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_transform_component)
|
||||
self.test_success = self.test_success and active
|
||||
if active:
|
||||
self.log("Gradient Transform Modifier component is active now that the Entity has a Shape")
|
||||
class Tests:
|
||||
disabled_without_shape = (
|
||||
"Gradient Transform Modifier component is disabled without a Shape component on the Entity",
|
||||
"Gradient Transform Modifier component is unexpectedly enabled without a Shape component on the Entity",
|
||||
)
|
||||
enabled_with_shape = (
|
||||
"Gradient Transform Modifier component is enabled now that the Entity has a Shape",
|
||||
"Gradient Transform Modifier component is still disabled alongside a Shape component",
|
||||
)
|
||||
|
||||
|
||||
test = TestGradientTransformRequiresShape()
|
||||
test.run()
|
||||
def GradientTransform_RequiresShape():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Gradient Transform Modifier component is dependent on a shape component.
|
||||
|
||||
Expected Result:
|
||||
Gradient Transform Modifier component is disabled until a shape component is added to the entity.
|
||||
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Create a new entity with a Gradient Transform Modifier component
|
||||
3) Verify the component is disabled until a shape component is also added to the entity
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Create a new Entity in the level
|
||||
entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
|
||||
|
||||
# Add a Gradient Transform Component (that will be disabled since there is no shape on the Entity)
|
||||
gradient_transform_component = hydra.add_component('Gradient Transform Modifier', entity_id)
|
||||
|
||||
# Verify the Gradient Transform Component is not active before adding the Shape
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_transform_component)
|
||||
Report.result(Tests.disabled_without_shape, not active)
|
||||
|
||||
# Add a Shape component to the same Entity
|
||||
hydra.add_component('Box Shape', entity_id)
|
||||
|
||||
# Check if the Gradient Transform Component is active now after adding the Shape
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', gradient_transform_component)
|
||||
Report.result(Tests.enabled_with_shape, active)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientTransform_RequiresShape)
|
||||
|
||||
+73
-71
@@ -5,89 +5,91 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.entity as EntityId
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
class Tests:
|
||||
image_gradient_entity_created = (
|
||||
"Image Gradient entity created",
|
||||
"Failed to create Image Gradient entity",
|
||||
)
|
||||
image_gradient_asset_found = (
|
||||
"image_grad_test_gsi.png was found in the workspace",
|
||||
"image_grad_test_gsi.png was not found in the workspace"
|
||||
)
|
||||
image_gradient_assigned = (
|
||||
"Successfully assigned image gradient asset",
|
||||
"Failed to assign image gradient asset"
|
||||
)
|
||||
|
||||
|
||||
class TestImageGradient(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="ImageGradient_ProcessedImageAssignedSucessfully",
|
||||
args=["level"])
|
||||
def ImageGradient_ProcessedImageAssignedSuccessfully():
|
||||
"""
|
||||
Summary:
|
||||
Level created with Entity having Image Gradient and Gradient Transform Modifier components.
|
||||
Save any new image to your workspace with the suffix "_gsi" and assign as image asset.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
Level created with Entity having Image Gradient and Gradient Transform Modifier components.
|
||||
Save any new image to your workspace with the suffix "_gsi" and assign as image asset.
|
||||
|
||||
Expected Behavior:
|
||||
Image can be assigned as the Image Asset for the Image as Gradient component.
|
||||
Expected Behavior:
|
||||
Image can be assigned as the Image Asset for the Image as Gradient component.
|
||||
|
||||
Test Steps:
|
||||
1) Create level
|
||||
2) Create an entity with Image Gradient and Gradient Transform Modifier components.
|
||||
3) Assign the newly processed gradient image as Image asset.
|
||||
Test Steps:
|
||||
1) Open a level
|
||||
2) Create an entity with Image Gradient and Gradient Transform Modifier components.
|
||||
3) Assign the newly processed gradient image as Image asset.
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
:return: None
|
||||
"""
|
||||
|
||||
# 1) Create level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
import os
|
||||
|
||||
# 2) Create an entity with Image Gradient and Gradient Transform Modifier components
|
||||
components_to_add = ["Image Gradient", "Gradient Transform Modifier", "Box Shape"]
|
||||
entity_position = math.Vector3(512.0, 512.0, 32.0)
|
||||
new_entity_id = editor.ToolsApplicationRequestBus(
|
||||
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
|
||||
)
|
||||
if new_entity_id.IsValid():
|
||||
print("Image Gradient Entity created")
|
||||
image_gradient_entity = hydra.Entity("Image Gradient Entity", new_entity_id)
|
||||
image_gradient_entity.components = []
|
||||
for component in components_to_add:
|
||||
image_gradient_entity.add_component(component)
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.entity as EntityId
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.math as math
|
||||
|
||||
# 3) Assign the processed gradient signal image as the Image Gradient's image asset and verify success
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# First, check for the base image in the workspace
|
||||
base_image = "image_grad_test_gsi.png"
|
||||
base_image_path = os.path.join("AutomatedTesting", "Assets", "ImageGradients", base_image)
|
||||
if os.path.isfile(base_image_path):
|
||||
print(f"{base_image} was found in the workspace")
|
||||
# 1) Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Next, assign the processed image to the Image Gradient's Image Asset property
|
||||
processed_image_path = os.path.join("Assets", "ImageGradients", "image_grad_test_gsi.gradimage")
|
||||
asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", processed_image_path, math.Uuid(),
|
||||
False)
|
||||
hydra.get_set_test(image_gradient_entity, 0, "Configuration|Image Asset", asset_id)
|
||||
# 2) Create an entity with Image Gradient and Gradient Transform Modifier components
|
||||
components_to_add = ["Image Gradient", "Gradient Transform Modifier", "Box Shape"]
|
||||
entity_position = math.Vector3(512.0, 512.0, 32.0)
|
||||
new_entity_id = editor.ToolsApplicationRequestBus(
|
||||
bus.Broadcast, "CreateNewEntityAtPosition", entity_position, EntityId.EntityId()
|
||||
)
|
||||
Report.critical_result(Tests.image_gradient_entity_created, new_entity_id.IsValid())
|
||||
image_gradient_entity = hydra.Entity("Image Gradient Entity", new_entity_id)
|
||||
image_gradient_entity.components = []
|
||||
for component in components_to_add:
|
||||
image_gradient_entity.add_component(component)
|
||||
|
||||
# Finally, verify if the gradient image is assigned as the Image Asset
|
||||
success = hydra.get_component_property_value(image_gradient_entity.components[0], "Configuration|Image Asset") == asset_id
|
||||
self.test_success = self.test_success and success
|
||||
# 3) Assign the processed gradient signal image as the Image Gradient's image asset and verify success
|
||||
|
||||
# First, check for the base image in the workspace
|
||||
base_image = "image_grad_test_gsi.png"
|
||||
base_image_path = os.path.join("AutomatedTesting", "Assets", "ImageGradients", base_image)
|
||||
Report.critical_result(Tests.image_gradient_asset_found, os.path.isfile(base_image_path))
|
||||
|
||||
# Next, assign the processed image to the Image Gradient's Image Asset property
|
||||
processed_image_path = os.path.join("Assets", "ImageGradients", "image_grad_test_gsi.gradimage")
|
||||
asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", processed_image_path, math.Uuid(),
|
||||
False)
|
||||
hydra.get_set_test(image_gradient_entity, 0, "Configuration|Image Asset", asset_id)
|
||||
|
||||
# Finally, verify if the gradient image is assigned as the Image Asset
|
||||
success = hydra.get_component_property_value(image_gradient_entity.components[0], "Configuration|Image Asset") == asset_id
|
||||
Report.result(Tests.image_gradient_assigned, success)
|
||||
|
||||
|
||||
test = TestImageGradient()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(ImageGradient_ProcessedImageAssignedSuccessfully)
|
||||
|
||||
+65
-67
@@ -4,74 +4,72 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.paths
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
|
||||
class TestImageGradientRequiresShape(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="ImageGradientRequiresShape", args=["level"])
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Image Gradient component is dependent on a shape component.
|
||||
|
||||
Expected Result:
|
||||
Gradient Transform Modifier component is disabled until a shape component is added to the entity.
|
||||
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Create a new entity with a Image Gradient component
|
||||
3) Verify the component is disabled until a shape component is also added to the entity
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
|
||||
# Create a new Entity in the level
|
||||
entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
|
||||
|
||||
# Add an Image Gradient and Gradient Transform Component (should be disabled until a Shape exists on the Entity)
|
||||
image_gradient_component = hydra.add_component('Image Gradient', entity_id)
|
||||
hydra.add_component('Gradient Transform Modifier', entity_id)
|
||||
|
||||
# Verify the Image Gradient Component is not active before adding the Shape
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', image_gradient_component)
|
||||
self.test_success = self.test_success and not active
|
||||
if not active:
|
||||
self.log("Image Gradient component is not active without a Shape component on the Entity")
|
||||
|
||||
# Add a Shape component to the same Entity
|
||||
hydra.add_component('Box Shape', entity_id)
|
||||
|
||||
# Check if the Image Gradient Component is active now after adding the Shape
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', image_gradient_component)
|
||||
self.test_success = self.test_success and active
|
||||
if active:
|
||||
self.log("Image Gradient component is active now that the Entity has a Shape")
|
||||
class Tests:
|
||||
disabled_without_shape = (
|
||||
"Image Gradient component is disabled without a Shape component on the Entity",
|
||||
"Image Gradient component is unexpectedly enabled without a Shape component on the Entity",
|
||||
)
|
||||
enabled_with_shape = (
|
||||
"Image Gradient component is enabled now that the Entity has a Shape",
|
||||
"Image Gradient component is still disabled alongside a Shape component",
|
||||
)
|
||||
|
||||
|
||||
test = TestImageGradientRequiresShape()
|
||||
test.run()
|
||||
def ImageGradient_RequiresShape():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Image Gradient component is dependent on a shape component.
|
||||
|
||||
Expected Result:
|
||||
Gradient Transform Modifier component is disabled until a shape component is added to the entity.
|
||||
|
||||
Test Steps:
|
||||
1) Open level
|
||||
2) Create a new entity with a Image Gradient component
|
||||
3) Verify the component is disabled until a shape component is also added to the entity
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Create a new Entity in the level
|
||||
entity_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
|
||||
|
||||
# Add an Image Gradient and Gradient Transform Component (should be disabled until a Shape exists on the Entity)
|
||||
image_gradient_component = hydra.add_component('Image Gradient', entity_id)
|
||||
hydra.add_component('Gradient Transform Modifier', entity_id)
|
||||
|
||||
# Verify the Image Gradient Component is not active before adding the Shape
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', image_gradient_component)
|
||||
Report.result(Tests.disabled_without_shape, not active)
|
||||
|
||||
# Add a Shape component to the same Entity
|
||||
hydra.add_component('Box Shape', entity_id)
|
||||
|
||||
# Check if the Image Gradient Component is active now after adding the Shape
|
||||
active = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', image_gradient_component)
|
||||
Report.result(Tests.enabled_with_shape, active)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(ImageGradient_RequiresShape)
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
"""
|
||||
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 os
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared')
|
||||
from base import TestAutomationBase
|
||||
|
||||
|
||||
@pytest.mark.SUITE_periodic
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(TestAutomationBase):
|
||||
|
||||
def test_GradientGenerators_Incompatibilities(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientGenerators_Incompatibilities as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_GradientModifiers_Incompatibilities(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientModifiers_Incompatibilities as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_GradientPreviewSettings_DefaultPinnedEntityIsSelf(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientPreviewSettings_DefaultPinnedEntityIsSelf as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_GradientSampling_GradientReferencesAddRemoveSuccessfully(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientSampling_GradientReferencesAddRemoveSuccessfully as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_GradientSurfaceTagEmitter_ComponentDependencies(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientSurfaceTagEmitter_ComponentDependencies as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_GradientTransform_RequiresShape(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientTransform_RequiresShape as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_GradientTransform_ComponentIncompatibleWithSpawners(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientTransform_ComponentIncompatibleWithSpawners as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_GradientTransform_ComponentIncompatibleWithExpectedGradients(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientTransform_ComponentIncompatibleWithExpectedGradients as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_ImageGradient_RequiresShape(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import ImageGradient_RequiresShape as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_ImageGradient_ProcessedImageAssignedSuccessfully(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import ImageGradient_ProcessedImageAssignedSuccessfully as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
"""
|
||||
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 pytest
|
||||
|
||||
from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite
|
||||
|
||||
|
||||
@pytest.mark.SUITE_periodic
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(EditorTestSuite):
|
||||
|
||||
class test_GradientGenerators_Incompatibilities(EditorSharedTest):
|
||||
from .EditorScripts import GradientGenerators_Incompatibilities as test_module
|
||||
|
||||
class test_GradientModifiers_Incompatibilities(EditorSharedTest):
|
||||
from .EditorScripts import GradientModifiers_Incompatibilities as test_module
|
||||
|
||||
class test_GradientPreviewSettings_DefaultPinnedEntityIsSelf(EditorSharedTest):
|
||||
from .EditorScripts import GradientPreviewSettings_DefaultPinnedEntityIsSelf as test_module
|
||||
|
||||
class test_GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin(EditorSharedTest):
|
||||
from .EditorScripts import GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin as test_module
|
||||
|
||||
class test_GradientSampling_GradientReferencesAddRemoveSuccessfully(EditorSharedTest):
|
||||
from .EditorScripts import GradientSampling_GradientReferencesAddRemoveSuccessfully as test_module
|
||||
|
||||
class test_GradientSurfaceTagEmitter_ComponentDependencies(EditorSharedTest):
|
||||
from .EditorScripts import GradientSurfaceTagEmitter_ComponentDependencies as test_module
|
||||
|
||||
class test_GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully(EditorSharedTest):
|
||||
from .EditorScripts import GradientSurfaceTagEmitter_SurfaceTagsAddRemoveSuccessfully as test_module
|
||||
|
||||
class test_GradientTransform_RequiresShape(EditorSharedTest):
|
||||
from .EditorScripts import GradientTransform_RequiresShape as test_module
|
||||
|
||||
class test_GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange(EditorSharedTest):
|
||||
from .EditorScripts import GradientTransform_FrequencyZoomCanBeSetBeyondSliderRange as test_module
|
||||
|
||||
class test_GradientTransform_ComponentIncompatibleWithSpawners(EditorSharedTest):
|
||||
from .EditorScripts import GradientTransform_ComponentIncompatibleWithSpawners as test_module
|
||||
|
||||
class test_GradientTransform_ComponentIncompatibleWithExpectedGradients(EditorSharedTest):
|
||||
from .EditorScripts import GradientTransform_ComponentIncompatibleWithExpectedGradients as test_module
|
||||
|
||||
class test_ImageGradient_RequiresShape(EditorSharedTest):
|
||||
from .EditorScripts import ImageGradient_RequiresShape as test_module
|
||||
|
||||
class test_ImageGradient_ProcessedImageAssignedSuccessfully(EditorSharedTest):
|
||||
from .EditorScripts import ImageGradient_ProcessedImageAssignedSuccessfully as test_module
|
||||
+119
-116
@@ -5,144 +5,147 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
new_graph_created = (
|
||||
"Successfully created new graph",
|
||||
"Failed to create new graph"
|
||||
)
|
||||
graph_registered = (
|
||||
"Graph registered with Landscape Canvas",
|
||||
"Failed to register graph"
|
||||
)
|
||||
dependencies_added = (
|
||||
"Node created new Entity with all required components",
|
||||
"Failed to create node with all required components"
|
||||
)
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
newEntityId = None
|
||||
|
||||
|
||||
class TestAreaNodeComponentDependency(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="AreaNodeComponentDependency", args=["level"])
|
||||
def AreaNodes_DependentComponentsAdded():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities with
|
||||
proper dependent components.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities with
|
||||
proper dependent components.
|
||||
Expected Behavior:
|
||||
All expected component dependencies are met when adding an area node to a graph.
|
||||
|
||||
Expected Behavior:
|
||||
All expected component dependencies are met when adding an area node to a graph.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the area nodes to the graph area, and ensure the proper dependent components are added
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the area nodes to the graph area, and ensure the proper dependent components are added
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
:return: None
|
||||
"""
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=128,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=128,
|
||||
use_terrain=False,
|
||||
)
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
|
||||
if general.is_pane_visible('Landscape Canvas'):
|
||||
self.log('Landscape Canvas pane is open')
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId
|
||||
if newGraphId:
|
||||
self.log("New graph created")
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
self.test_success = self.test_success and success
|
||||
if success:
|
||||
self.log("Graph registered with Landscape Canvas")
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding these vegetation area nodes has the main target Vegetation Layer Component
|
||||
# as well as automatically adding all required dependency components
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
|
||||
|
||||
# Vegetation area mapping with the key being the node name and the value is the
|
||||
# expected Components that should be added to the Entity created for the node
|
||||
areas = {
|
||||
'SpawnerAreaNode': [
|
||||
'Vegetation Layer Spawner',
|
||||
'Vegetation Asset List',
|
||||
'Vegetation Reference Shape'
|
||||
],
|
||||
'MeshBlockerAreaNode': [
|
||||
'Vegetation Layer Blocker (Mesh)',
|
||||
'Mesh'
|
||||
],
|
||||
'BlockerAreaNode': [
|
||||
'Vegetation Layer Blocker',
|
||||
'Vegetation Reference Shape'
|
||||
]
|
||||
}
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# Retrieve a mapping of the TypeIds for all the components
|
||||
# we will be checking for
|
||||
componentNames = []
|
||||
for name in areas:
|
||||
componentNames.extend(areas[name])
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding these vegetation area nodes has the main target Vegetation Layer Component
|
||||
# as well as automatically adding all required dependency components
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
|
||||
# Create nodes for the vegetation areas that have additional required dependencies and check if
|
||||
# the Entity created by adding the node has the appropriate component and required
|
||||
# additional components added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in areas:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
# Vegetation area mapping with the key being the node name and the value is the
|
||||
# expected Components that should be added to the Entity created for the node
|
||||
areas = {
|
||||
'SpawnerAreaNode': [
|
||||
'Vegetation Layer Spawner',
|
||||
'Vegetation Asset List',
|
||||
'Vegetation Reference Shape'
|
||||
],
|
||||
'MeshBlockerAreaNode': [
|
||||
'Vegetation Layer Blocker (Mesh)',
|
||||
'Mesh'
|
||||
],
|
||||
'BlockerAreaNode': [
|
||||
'Vegetation Layer Blocker',
|
||||
'Vegetation Reference Shape'
|
||||
]
|
||||
}
|
||||
|
||||
components = areas[nodeName]
|
||||
success = False
|
||||
for component in components:
|
||||
componentTypeId = componentTypeIds[component]
|
||||
success = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
|
||||
componentTypeId)
|
||||
if not success:
|
||||
break
|
||||
self.test_success = self.test_success and success
|
||||
if success:
|
||||
self.log("{node} created new Entity with all required components".format(node=nodeName))
|
||||
# Retrieve a mapping of the TypeIds for all the components
|
||||
# we will be checking for
|
||||
componentNames = []
|
||||
for name in areas:
|
||||
componentNames.extend(areas[name])
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
|
||||
x += 40.0
|
||||
y += 40.0
|
||||
# Create nodes for the vegetation areas that have additional required dependencies and check if
|
||||
# the Entity created by adding the node has the appropriate component and required
|
||||
# additional components added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in areas:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
components = areas[nodeName]
|
||||
success = False
|
||||
for component in components:
|
||||
componentTypeId = componentTypeIds[component]
|
||||
success = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
|
||||
componentTypeId)
|
||||
if not success:
|
||||
break
|
||||
Report.info(nodeName)
|
||||
Report.result(Tests.dependencies_added, success)
|
||||
|
||||
x += 40.0
|
||||
y += 40.0
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestAreaNodeComponentDependency()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(AreaNodes_DependentComponentsAdded)
|
||||
|
||||
+102
-98
@@ -5,125 +5,129 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
new_graph_created = (
|
||||
"Successfully created new graph",
|
||||
"Failed to create new graph"
|
||||
)
|
||||
graph_registered = (
|
||||
"Graph registered with Landscape Canvas",
|
||||
"Failed to register graph"
|
||||
)
|
||||
component_added = (
|
||||
"New entity created with the expected component",
|
||||
"Expected component was not found on entity"
|
||||
)
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
newEntityId = None
|
||||
|
||||
|
||||
class TestGradientNodeEntityCreate(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="AreaNodeEntityCreate", args=["level"])
|
||||
def AreaNodes_EntityCreatedOnNodeAdd():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
|
||||
Expected Behavior:
|
||||
New entities are created when dragging area nodes to graph area.
|
||||
|
||||
Expected Behavior:
|
||||
New entities are created when dragging area nodes to graph area.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the area nodes to the graph area, and ensure a new entity is created
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the area nodes to the graph area, and ensure a new entity is created
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
:return: None
|
||||
"""
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=128,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=128,
|
||||
use_terrain=False,
|
||||
)
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
|
||||
if general.is_pane_visible('Landscape Canvas'):
|
||||
self.log('Landscape Canvas pane is open')
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId
|
||||
if newGraphId:
|
||||
self.log("New graph created")
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
self.test_success = self.test_success and success
|
||||
if success:
|
||||
self.log("Graph registered with Landscape Canvas")
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding vegetation area nodes has the appropriate Vegetation Layer Component
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Vegetation Area mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the Entity created for the node
|
||||
areas = {
|
||||
'AreaBlenderNode': 'Vegetation Layer Blender',
|
||||
'BlockerAreaNode': 'Vegetation Layer Blocker',
|
||||
'MeshBlockerAreaNode': 'Vegetation Layer Blocker (Mesh)',
|
||||
'SpawnerAreaNode': 'Vegetation Layer Spawner'
|
||||
}
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
|
||||
|
||||
# Retrieve a mapping of the TypeIds for all the components
|
||||
# we will be checking for
|
||||
componentNames = []
|
||||
for name in areas:
|
||||
componentNames.append(areas[name])
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# Create nodes for all the vegetation areas we support and check if the Entity created by
|
||||
# adding the node has the appropriate Component added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in areas:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding vegetation area nodes has the appropriate Vegetation Layer Component
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
|
||||
areaComponent = areas[nodeName]
|
||||
componentTypeId = componentTypeIds[areaComponent]
|
||||
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, componentTypeId)
|
||||
self.test_success = self.test_success and hasComponent
|
||||
if hasComponent:
|
||||
self.log("{node} created new Entity with {component} Component".format(node=nodeName, component=areaComponent))
|
||||
# Vegetation Area mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the Entity created for the node
|
||||
areas = {
|
||||
'AreaBlenderNode': 'Vegetation Layer Blender',
|
||||
'BlockerAreaNode': 'Vegetation Layer Blocker',
|
||||
'MeshBlockerAreaNode': 'Vegetation Layer Blocker (Mesh)',
|
||||
'SpawnerAreaNode': 'Vegetation Layer Spawner'
|
||||
}
|
||||
|
||||
x += 40.0
|
||||
y += 40.0
|
||||
# Retrieve a mapping of the TypeIds for all the components
|
||||
# we will be checking for
|
||||
componentNames = []
|
||||
for name in areas:
|
||||
componentNames.append(areas[name])
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
# Create nodes for all the vegetation areas we support and check if the Entity created by
|
||||
# adding the node has the appropriate Component added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in areas:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
|
||||
areaComponent = areas[nodeName]
|
||||
componentTypeId = componentTypeIds[areaComponent]
|
||||
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, componentTypeId)
|
||||
Report.info(f"Node: {nodeName} | Component: {areaComponent}")
|
||||
Report.result(Tests.component_added, hasComponent)
|
||||
|
||||
x += 40.0
|
||||
y += 40.0
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestGradientNodeEntityCreate()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(AreaNodes_EntityCreatedOnNodeAdd)
|
||||
|
||||
+99
-94
@@ -5,123 +5,128 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
new_graph_created = (
|
||||
"Successfully created new graph",
|
||||
"Failed to create new graph"
|
||||
)
|
||||
graph_registered = (
|
||||
"Graph registered with Landscape Canvas",
|
||||
"Failed to register graph"
|
||||
)
|
||||
entity_deleted = (
|
||||
"Entity was deleted when node was removed",
|
||||
"Entity was not deleted as expected when node was removed"
|
||||
)
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
createdEntityId = None
|
||||
deletedEntityId = None
|
||||
|
||||
|
||||
class TestAreaNodeEntityDelete(EditorTestHelper):
|
||||
def AreaNodes_EntityRemovedOnNodeDelete():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
|
||||
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="AreaNodeEntityDelete", args=["level"])
|
||||
Expected Behavior:
|
||||
Entities are removed when area nodes are deleted from a graph.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the area nodes to the graph area, and ensure a new entity is created
|
||||
4) Delete the nodes, and ensure the newly created entities are removed
|
||||
|
||||
Expected Behavior:
|
||||
Entities are removed when area nodes are deleted from a graph.
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the area nodes to the graph area, and ensure a new entity is created
|
||||
4) Delete the nodes, and ensure the newly created entities are removed
|
||||
:return: None
|
||||
"""
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
|
||||
:return: None
|
||||
"""
|
||||
def onEntityCreated(parameters):
|
||||
global createdEntityId
|
||||
createdEntityId = parameters[0]
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
def onEntityDeleted(parameters):
|
||||
global deletedEntityId
|
||||
deletedEntityId = parameters[0]
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=128,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=128,
|
||||
use_terrain=False,
|
||||
)
|
||||
def onEntityCreated(parameters):
|
||||
global createdEntityId
|
||||
createdEntityId = parameters[0]
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
|
||||
if general.is_pane_visible('Landscape Canvas'):
|
||||
self.log('Landscape Canvas pane is open')
|
||||
def onEntityDeleted(parameters):
|
||||
global deletedEntityId
|
||||
deletedEntityId = parameters[0]
|
||||
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId
|
||||
if newGraphId:
|
||||
self.log("New graph created")
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
self.test_success = self.test_success and success
|
||||
if success:
|
||||
self.log("Graph registered with Landscape Canvas")
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding gradient nodes has the appropriate Gradient Component
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
|
||||
|
||||
# Vegetation Area mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the Entity created for the node
|
||||
areas = [
|
||||
'AreaBlenderNode',
|
||||
'BlockerAreaNode',
|
||||
'MeshBlockerAreaNode',
|
||||
'SpawnerAreaNode',
|
||||
]
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# Create nodes for all the gradients we support and check if the Entity created by
|
||||
# adding the node has the appropriate Component added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in areas:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding gradient nodes has the appropriate Gradient Component
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
|
||||
|
||||
removed = graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, node)
|
||||
# Vegetation Area mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the Entity created for the node
|
||||
areas = [
|
||||
'AreaBlenderNode',
|
||||
'BlockerAreaNode',
|
||||
'MeshBlockerAreaNode',
|
||||
'SpawnerAreaNode',
|
||||
]
|
||||
|
||||
# Verify that the created Entity for this node matches the Entity that gets
|
||||
# deleted when the node is removed
|
||||
self.test_success = self.test_success and removed and createdEntityId.invoke("Equal", deletedEntityId)
|
||||
if removed and createdEntityId.invoke("Equal", deletedEntityId):
|
||||
self.log("{node} corresponding Entity was deleted when node is removed".format(node=nodeName))
|
||||
# Create nodes for all the gradients we support and check if the Entity created by
|
||||
# adding the node has the appropriate Component added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in areas:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
|
||||
nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
removed = graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, node)
|
||||
|
||||
# Verify that the created Entity for this node matches the Entity that gets
|
||||
# deleted when the node is removed
|
||||
Report.info(f"Node: {nodeName}")
|
||||
Report.result(Tests.entity_deleted, removed and createdEntityId.invoke("Equal", deletedEntityId))
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestAreaNodeEntityDelete()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(AreaNodes_EntityRemovedOnNodeDelete)
|
||||
|
||||
+179
-167
@@ -5,197 +5,209 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.math as math
|
||||
import azlmbr.slice as slice
|
||||
import azlmbr.paths
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
class Tests:
|
||||
slice_instantiated = (
|
||||
"Slice instantiated successfully",
|
||||
"Failed to instantiate slice"
|
||||
)
|
||||
lc_entity_found = (
|
||||
"LandscapeCanvas entity found",
|
||||
"Failed to find LandscapeCanvas entity"
|
||||
)
|
||||
spawner_entity_found = (
|
||||
"BushSpawner entity found",
|
||||
"Failed to find BushSpawner entity"
|
||||
)
|
||||
dist_filter_component_found = (
|
||||
"Vegetation Distribution Filter component on BushSpawner entity found",
|
||||
"Failed to find Distribution Filter component on BushSpawner entity"
|
||||
)
|
||||
existing_graph_opened = (
|
||||
"Opened existing graph from slice",
|
||||
"Failed to open existing graph"
|
||||
)
|
||||
dist_filter_node_found = (
|
||||
"Vegetation Distribution Filter node found on graph",
|
||||
"Failed to find Distribution Filter node on graph"
|
||||
)
|
||||
alt_filter_component_found = (
|
||||
"Vegetation Altitude Filter component on BushSpawner entity found",
|
||||
"Failed to find Altitude Filter component on BushSpawner entity"
|
||||
)
|
||||
alt_filter_node_found = (
|
||||
"Vegetation Altitude Filter node found on graph",
|
||||
"Failed to find Altitude Filter node on graph"
|
||||
)
|
||||
dist_filter_component_removed = (
|
||||
"Vegetation Distribution Filter component removed from BushSpawner entity",
|
||||
"Failed to remove Distribution Filter component from BushSpawner entity"
|
||||
)
|
||||
dist_filter_node_removed = (
|
||||
"Vegetation Distribution Filter node removed from graph",
|
||||
"Failed to remove Distribution Filter node from graph"
|
||||
)
|
||||
child_entity_added = (
|
||||
"New entity successfully added as a child of the BushSpawner entity",
|
||||
"New entity added with an unexpected parent"
|
||||
)
|
||||
box_shape_component_found = (
|
||||
"Box Shape component on Box entity found",
|
||||
"Failed to find Box Shape component on Box entity"
|
||||
)
|
||||
box_shape_node_found = (
|
||||
"Box Shape node found on graph",
|
||||
"Failed to find Box Shape node on graph"
|
||||
)
|
||||
|
||||
|
||||
class TestComponentUpdatesUpdateGraph(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="ComponentUpdatesUpdateGraph", args=["level"])
|
||||
def ComponentUpdates_UpdateGraph():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas graphs update properly when components are added/removed outside of
|
||||
Landscape Canvas.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas graphs update properly when components are added/removed outside of
|
||||
Landscape Canvas.
|
||||
Expected Behavior:
|
||||
Graphs properly reflect component changes made to entities outside of Landscape Canvas.
|
||||
|
||||
Expected Behavior:
|
||||
Graphs properly reflect component changes made to entities outside of Landscape Canvas.
|
||||
Test Steps:
|
||||
1. Open Level
|
||||
2. Find LandscapeCanvas named entity
|
||||
3. Ensure Vegetation Distribution Component is present on the BushSpawner entity
|
||||
4. Open graph and ensure Distribution Filter wrapped node is present
|
||||
5. Delete the Vegetation Distribution Filter component from the BushSpawner entity via Entity Inspector
|
||||
6. Ensure the Vegetation Distribution Filter component was deleted from the BushSpawner entity and node is
|
||||
no longer present in the graph
|
||||
7. Add Vegetation Altitude Filter to the BushSpawner entity through Entity Inspector
|
||||
8. Ensure Altitude Filter was added to the BushSpawner node in the open graph
|
||||
9. Add a new entity with unique name as a child of the Landscape Canvas entity
|
||||
10. Add a Box Shape component to the new child entity
|
||||
11. Ensure Box Shape node is present on the open graph
|
||||
|
||||
Test Steps:
|
||||
1. Open Level
|
||||
2. Find LandscapeCanvas named entity
|
||||
3. Ensure Vegetation Distribution Component is present on the BushSpawner entity
|
||||
4. Open graph and ensure Distribution Filter wrapped node is present
|
||||
5. Delete the Vegetation Distribution Filter component from the BushSpawner entity via Entity Inspector
|
||||
6. Ensure the Vegetation Distribution Filter component was deleted from the BushSpawner entity and node is
|
||||
no longer present in the graph
|
||||
7. Add Vegetation Altitude Filter to the BushSpawner entity through Entity Inspector
|
||||
8. Ensure Altitude Filter was added to the BushSpawner node in the open graph
|
||||
9. Add a new entity with unique name as a child of the Landscape Canvas entity
|
||||
10. Add a Box Shape component to the new child entity
|
||||
11. Ensure Box Shape node is present on the open graph
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
:return: None
|
||||
"""
|
||||
import os
|
||||
|
||||
# Create a new empty level and instantiate LC_BushFlowerBlender.slice
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=128,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=128,
|
||||
use_terrain=False,
|
||||
)
|
||||
transform = math.Transform_CreateIdentity()
|
||||
position = math.Vector3(64.0, 64.0, 32.0)
|
||||
transform.invoke('SetPosition', position)
|
||||
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice")
|
||||
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(),
|
||||
False)
|
||||
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform)
|
||||
self.test_success = self.test_success and test_slice.IsValid()
|
||||
if test_slice.IsValid():
|
||||
self.log("Slice spawned!")
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.math as math
|
||||
import azlmbr.slice as slice
|
||||
|
||||
# Find root entity in the loaded level
|
||||
search_filter = entity.SearchFilter()
|
||||
search_filter.names = ["LandscapeCanvas"]
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Allow a few seconds for matching entity to be found
|
||||
self.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0)
|
||||
lc_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
|
||||
slice_root_id = lc_matching_entities[0] #Entity with Landscape Canvas component
|
||||
self.test_success = self.test_success and slice_root_id.IsValid()
|
||||
if slice_root_id.IsValid():
|
||||
self.log("LandscapeCanvas entity found")
|
||||
# Open a simple level and instantiate LC_BushFlowerBlender.slice
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
transform = math.Transform_CreateIdentity()
|
||||
position = math.Vector3(64.0, 64.0, 32.0)
|
||||
transform.invoke('SetPosition', position)
|
||||
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice")
|
||||
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(),
|
||||
False)
|
||||
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform)
|
||||
Report.critical_result(Tests.slice_instantiated, test_slice.IsValid())
|
||||
|
||||
# Find the BushSpawner entity
|
||||
search_filter.names = ["BushSpawner"]
|
||||
spawner_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
|
||||
spawner_id = spawner_matching_entities[0] #Entity with Vegetation Layer Spawner component
|
||||
self.test_success = self.test_success and spawner_id.IsValid()
|
||||
if spawner_id.IsValid():
|
||||
self.log("BushSpawner entity found")
|
||||
# Find root entity in the loaded level
|
||||
search_filter = entity.SearchFilter()
|
||||
search_filter.names = ["LandscapeCanvas"]
|
||||
|
||||
# Get needed component type ids
|
||||
distribution_filter_type_id = hydra.get_component_type_id("Vegetation Distribution Filter")
|
||||
altitude_filter_type_id = hydra.get_component_type_id("Vegetation Altitude Filter")
|
||||
box_shape_type_id = hydra.get_component_type_id("Box Shape")
|
||||
# Allow a few seconds for matching entity to be found
|
||||
helper.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0)
|
||||
lc_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
|
||||
slice_root_id = lc_matching_entities[0] #Entity with Landscape Canvas component
|
||||
Report.critical_result(Tests.lc_entity_found, slice_root_id.IsValid())
|
||||
|
||||
# Verify the BushSpawner entity has a Distribution Filter
|
||||
has_distribution_filter = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', spawner_id,
|
||||
distribution_filter_type_id)
|
||||
self.test_success = self.test_success and has_distribution_filter
|
||||
if has_distribution_filter:
|
||||
self.log("Vegetation Distribution Filter on BushSpawner entity found")
|
||||
# Find the BushSpawner entity
|
||||
search_filter.names = ["BushSpawner"]
|
||||
spawner_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
|
||||
spawner_id = spawner_matching_entities[0] #Entity with Vegetation Layer Spawner component
|
||||
Report.critical_result(Tests.spawner_entity_found, spawner_id.IsValid())
|
||||
|
||||
# Open Landscape Canvas and the existing graph
|
||||
general.open_pane('Landscape Canvas')
|
||||
open_graph = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id)
|
||||
self.test_success = self.test_success and open_graph.IsValid()
|
||||
if open_graph.IsValid():
|
||||
self.log("Graph opened")
|
||||
# Get needed component type ids
|
||||
distribution_filter_type_id = hydra.get_component_type_id("Vegetation Distribution Filter")
|
||||
altitude_filter_type_id = hydra.get_component_type_id("Vegetation Altitude Filter")
|
||||
box_shape_type_id = hydra.get_component_type_id("Box Shape")
|
||||
|
||||
# Verify that Distribution Filter node is present on the graph
|
||||
spawner_distribution_filter_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', spawner_id,
|
||||
distribution_filter_type_id)
|
||||
spawner_distribution_filter_component_id = spawner_distribution_filter_component.GetValue()
|
||||
distribution_filter_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast,
|
||||
'GetNodeMatchingEntityComponentInGraph',
|
||||
open_graph,
|
||||
spawner_distribution_filter_component_id)
|
||||
self.test_success = self.test_success and distribution_filter_node is not None
|
||||
if distribution_filter_node is not None:
|
||||
self.log("Distribution Filter node found on graph")
|
||||
else:
|
||||
self.log("Distribution Filter node not found on graph")
|
||||
# Verify the BushSpawner entity has a Distribution Filter
|
||||
has_distribution_filter = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', spawner_id,
|
||||
distribution_filter_type_id)
|
||||
Report.critical_result(Tests.dist_filter_component_found, has_distribution_filter)
|
||||
|
||||
# Add a Vegetation Altitude Filter component to the BushSpawner entity, and verify the node is added to the graph
|
||||
spawner_altitude_filter_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', spawner_id,
|
||||
altitude_filter_type_id)
|
||||
spawner_altitude_filter_component_id = spawner_altitude_filter_component.GetValue()
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentOfType', spawner_id, altitude_filter_type_id)
|
||||
has_altitude_filter = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', spawner_id,
|
||||
altitude_filter_type_id)
|
||||
altitude_filter_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetNodeMatchingEntityComponentInGraph',
|
||||
open_graph, spawner_altitude_filter_component_id)
|
||||
self.test_success = self.test_success and has_altitude_filter and altitude_filter_node is not None
|
||||
if has_altitude_filter:
|
||||
self.log("Vegetation Altitude Filter on BushSpawner entity found")
|
||||
# Open Landscape Canvas and the existing graph
|
||||
general.open_pane('Landscape Canvas')
|
||||
open_graph = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id)
|
||||
Report.critical_result(Tests.existing_graph_opened, open_graph.IsValid())
|
||||
|
||||
if altitude_filter_node is not None:
|
||||
self.log("Altitude Filter node found on graph")
|
||||
else:
|
||||
self.log("Altitude Filter node not found on graph")
|
||||
# Verify that Distribution Filter node is present on the graph
|
||||
spawner_distribution_filter_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', spawner_id,
|
||||
distribution_filter_type_id)
|
||||
spawner_distribution_filter_component_id = spawner_distribution_filter_component.GetValue()
|
||||
distribution_filter_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast,
|
||||
'GetNodeMatchingEntityComponentInGraph',
|
||||
open_graph,
|
||||
spawner_distribution_filter_component_id)
|
||||
Report.critical_result(Tests.dist_filter_node_found, distribution_filter_node is not None)
|
||||
|
||||
# Remove the Distribution Filter
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [spawner_distribution_filter_component_id])
|
||||
general.idle_wait(1.0)
|
||||
# Add a Vegetation Altitude Filter component to the BushSpawner entity, and verify the node is added to the graph
|
||||
spawner_altitude_filter_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', spawner_id,
|
||||
altitude_filter_type_id)
|
||||
spawner_altitude_filter_component_id = spawner_altitude_filter_component.GetValue()
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentOfType', spawner_id, altitude_filter_type_id)
|
||||
has_altitude_filter = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', spawner_id,
|
||||
altitude_filter_type_id)
|
||||
altitude_filter_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetNodeMatchingEntityComponentInGraph',
|
||||
open_graph, spawner_altitude_filter_component_id)
|
||||
Report.result(Tests.dist_filter_component_found, has_altitude_filter)
|
||||
Report.result(Tests.dist_filter_node_found, altitude_filter_node is not None)
|
||||
|
||||
# Verify the Distribution Filter was successfully removed from entity and the node was likewise removed
|
||||
has_distribution_filter = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', spawner_id,
|
||||
distribution_filter_type_id)
|
||||
self.test_success = self.test_success and not has_distribution_filter
|
||||
if not has_distribution_filter:
|
||||
self.log("Vegetation Distribution Filter removed from BushSpawner entity")
|
||||
# Remove the Distribution Filter
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [spawner_distribution_filter_component_id])
|
||||
general.idle_wait(1.0)
|
||||
|
||||
distribution_filter_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast,
|
||||
'GetAllNodesMatchingEntityComponent',
|
||||
spawner_distribution_filter_component_id)
|
||||
self.test_success = self.test_success and not distribution_filter_node
|
||||
if distribution_filter_node:
|
||||
self.log("Distribution Filter node is still present on the graph")
|
||||
else:
|
||||
self.log("Distribution Filter node was removed from the graph")
|
||||
# Verify the Distribution Filter was successfully removed from entity and the node was likewise removed
|
||||
has_distribution_filter = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', spawner_id,
|
||||
distribution_filter_type_id)
|
||||
Report.result(Tests.dist_filter_component_removed, not has_distribution_filter)
|
||||
|
||||
# Add a new child entity of BushSpawner entity
|
||||
box_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', spawner_id)
|
||||
if editor.EditorEntityInfoRequestBus(bus.Event, 'GetParent', box_id) == spawner_id:
|
||||
self.log("New entity successfully added as a child of the BushSpawner entity")
|
||||
else:
|
||||
self.log("New entity added with an unexpected parent")
|
||||
distribution_filter_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast,
|
||||
'GetAllNodesMatchingEntityComponent',
|
||||
spawner_distribution_filter_component_id)
|
||||
Report.result(Tests.dist_filter_node_removed, not distribution_filter_node)
|
||||
|
||||
# Add a Box Shape component to the new entity and verify it was properly added
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentOfType', box_id, box_shape_type_id)
|
||||
has_box_shape = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', box_id,
|
||||
box_shape_type_id)
|
||||
self.test_success = self.test_success and has_box_shape
|
||||
if has_box_shape:
|
||||
self.log("Box Shape on Box entity found")
|
||||
# Add a new child entity of BushSpawner entity
|
||||
box_id = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', spawner_id)
|
||||
Report.result(Tests.child_entity_added, editor.EditorEntityInfoRequestBus(bus.Event, 'GetParent', box_id) ==
|
||||
spawner_id)
|
||||
|
||||
# Verify the Box Shape node appear on the graph
|
||||
box_shape_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', box_id,
|
||||
box_shape_type_id)
|
||||
# Add a Box Shape component to the new entity and verify it was properly added
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentOfType', box_id, box_shape_type_id)
|
||||
has_box_shape = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', box_id,
|
||||
box_shape_type_id)
|
||||
Report.result(Tests.box_shape_component_found, has_box_shape)
|
||||
|
||||
box_shape_component_id = box_shape_component.GetValue()
|
||||
box_shape_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent',
|
||||
box_shape_component_id)
|
||||
self.test_success = self.test_success and box_shape_node is not None
|
||||
if box_shape_node is not None:
|
||||
self.log("Box Shape node found on graph")
|
||||
else:
|
||||
self.log("Box Shape node not found on graph")
|
||||
# Verify the Box Shape node appears on the graph
|
||||
box_shape_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', box_id,
|
||||
box_shape_type_id)
|
||||
|
||||
box_shape_component_id = box_shape_component.GetValue()
|
||||
box_shape_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent',
|
||||
box_shape_component_id)
|
||||
Report.result(Tests.box_shape_node_found, box_shape_node is not None)
|
||||
|
||||
|
||||
test = TestComponentUpdatesUpdateGraph()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(ComponentUpdates_UpdateGraph)
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
|
||||
class Tests:
|
||||
lc_component_added = (
|
||||
"Landscape Canvas component successfully added to entity",
|
||||
"Failed to add Landscape Canvas component to entity"
|
||||
)
|
||||
lc_component_removed = (
|
||||
"Landscape Canvas component successfully removed from entity",
|
||||
"Failed to remove Landscape Canvas component from entity"
|
||||
)
|
||||
|
||||
|
||||
def Component_AddedRemoved():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas component can be added to/removed from an entity.
|
||||
|
||||
Expected Behavior:
|
||||
Closing a tabbed graph only closes the appropriate graph.
|
||||
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Create a new entity
|
||||
3) Add a Landscape Canvas component to the entity
|
||||
4) Remove the Landscape Canvas component from the entity
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Create an Entity at the root of the level
|
||||
newEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
|
||||
|
||||
# Find the component TypeId for our Landscape Canvas component
|
||||
landscape_canvas_type_id = hydra.get_component_type_id("Landscape Canvas")
|
||||
|
||||
# Add the Landscape Canvas Component to our Entity
|
||||
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', newEntityId, [landscape_canvas_type_id])
|
||||
components = componentOutcome.GetValue()
|
||||
landscapeCanvasComponent = components[0]
|
||||
|
||||
# Validate the Landscape Canvas Component exists
|
||||
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, landscape_canvas_type_id)
|
||||
Report.result(Tests.lc_component_added, hasComponent)
|
||||
|
||||
# Remove the Landscape Canvas Component
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [landscapeCanvasComponent])
|
||||
|
||||
# Validate the Landscape Canvas Component is no longer on our Entity
|
||||
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, landscape_canvas_type_id)
|
||||
Report.result(Tests.lc_component_removed, not hasComponent)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Component_AddedRemoved)
|
||||
-106
@@ -1,106 +0,0 @@
|
||||
"""
|
||||
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 os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.paths
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
new_root_entity_id = None
|
||||
|
||||
|
||||
class TestCreateNewGraph(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="CreateNewGraph", args=["level"])
|
||||
|
||||
def on_entity_created(self, parameters):
|
||||
global new_root_entity_id
|
||||
new_root_entity_id = parameters[0]
|
||||
|
||||
print("New root entity created")
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that new graphs can be created in Landscape Canvas.
|
||||
|
||||
Expected Behavior:
|
||||
New graphs can be created, and proper entity is created to hold graph data with a Landscape Canvas component.
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Ensures the root entity created contains a Landscape Canvas component
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=128,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=128,
|
||||
use_terrain=False,
|
||||
)
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane("Landscape Canvas")
|
||||
self.test_success = self.test_success and general.is_pane_visible("Landscape Canvas")
|
||||
if general.is_pane_visible("Landscape Canvas"):
|
||||
self.log("Landscape Canvas pane is open")
|
||||
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# with the new graph has our Landscape Canvas component automatically added
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback("OnEditorEntityCreated", self.on_entity_created)
|
||||
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, "CreateNewGraph", editorId)
|
||||
self.test_success = self.test_success and newGraphId
|
||||
if newGraphId:
|
||||
self.log("New graph created")
|
||||
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
success = graph.AssetEditorRequestBus(bus.Event, "ContainsGraph", editorId, newGraphId)
|
||||
self.test_success = self.test_success and success
|
||||
if success:
|
||||
self.log("Graph registered with Landscape Canvas")
|
||||
|
||||
# Check if the entity created when we create a new graph has the
|
||||
# Landscape Canvas component already added to it
|
||||
landscape_canvas_type_id = hydra.get_component_type_id("Landscape Canvas")
|
||||
success = editor.EditorComponentAPIBus(bus.Broadcast, "HasComponentOfType", new_root_entity_id,
|
||||
landscape_canvas_type_id)
|
||||
self.test_success = self.test_success and success
|
||||
if success:
|
||||
self.log("Root entity has Landscape Canvas component")
|
||||
|
||||
# Close Landscape Canvas tool and verify
|
||||
general.close_pane("Landscape Canvas")
|
||||
self.test_success = self.test_success and not general.is_pane_visible("Landscape Canvas")
|
||||
if not general.is_pane_visible("Landscape Canvas"):
|
||||
self.log("Landscape Canvas pane is closed")
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestCreateNewGraph()
|
||||
test.run()
|
||||
+104
-103
@@ -5,131 +5,132 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
new_graph_created = (
|
||||
"Successfully created new graph",
|
||||
"Failed to create new graph"
|
||||
)
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
newEntityId = None
|
||||
|
||||
|
||||
class TestDisabledNodeDuplication(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="DisabledNodeDuplication", args=["level"])
|
||||
def Edit_DisabledNodeDuplication():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies Editor stability after duplicating disabled Landscape Canvas nodes.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies Editor stability after duplicating disabled Landscape Canvas nodes.
|
||||
Expected Behavior:
|
||||
Editor remains stable and free of crashes.
|
||||
|
||||
Expected Behavior:
|
||||
Editor remains stable and free of crashes.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Create several new nodes, disable the nodes via disabling/deleting components, and duplicate the nodes
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Create several new nodes, disable the nodes via disabling/deleting components, and duplicate the nodes
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
:return: None
|
||||
"""
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=128,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=128,
|
||||
use_terrain=False,
|
||||
)
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
|
||||
if general.is_pane_visible('Landscape Canvas'):
|
||||
self.log('Landscape Canvas pane is open')
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId
|
||||
if newGraphId:
|
||||
self.log("New graph created")
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Listen for entity creation notifications so when we add a new node
|
||||
# we can access the corresponding Entity that was created so that we
|
||||
# can disable/remove components on that Entity
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Mapping of our Landscape Canvas nodes with corresponding dependent components
|
||||
# that we can disable/remove to reproduce the crash
|
||||
nodes = {
|
||||
'SpawnerAreaNode': 'Vegetation Asset List',
|
||||
'MeshBlockerAreaNode': 'Mesh',
|
||||
'BlockerAreaNode': 'Vegetation Reference Shape',
|
||||
'FastNoiseGradientNode': 'Gradient Transform Modifier',
|
||||
'ImageGradientNode': 'Gradient Transform Modifier',
|
||||
'PerlinNoiseGradientNode': 'Gradient Transform Modifier',
|
||||
'RandomNoiseGradientNode': 'Gradient Transform Modifier'
|
||||
}
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Retrieve a mapping of the TypeIds for all the components
|
||||
# we will be checking for
|
||||
componentNames = list(set(nodes.values())) # Convert to set then back to list to remove any duplicates
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
|
||||
|
||||
# Iterate through creating our nodes and then disabling/deleting required components
|
||||
# and then duplicating the node to reproduce the crash
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in nodes:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
# Listen for entity creation notifications so when we add a new node
|
||||
# we can access the corresponding Entity that was created so that we
|
||||
# can disable/remove components on that Entity
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
|
||||
dependentComponentName = nodes[nodeName]
|
||||
componentTypeId = componentTypeIds[dependentComponentName]
|
||||
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', newEntityId, componentTypeId)
|
||||
component = componentOutcome.GetValue()
|
||||
# Mapping of our Landscape Canvas nodes with corresponding dependent components
|
||||
# that we can disable/remove to reproduce the crash
|
||||
nodes = {
|
||||
'SpawnerAreaNode': 'Vegetation Asset List',
|
||||
'MeshBlockerAreaNode': 'Mesh',
|
||||
'BlockerAreaNode': 'Vegetation Reference Shape',
|
||||
'FastNoiseGradientNode': 'Gradient Transform Modifier',
|
||||
'ImageGradientNode': 'Gradient Transform Modifier',
|
||||
'PerlinNoiseGradientNode': 'Gradient Transform Modifier',
|
||||
'RandomNoiseGradientNode': 'Gradient Transform Modifier'
|
||||
}
|
||||
|
||||
# First make sure we can duplicate a node with a dependent component that is disabled
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [component])
|
||||
general.idle_wait(1.0)
|
||||
graph.SceneRequestBus(bus.Event, 'DuplicateSelection', newGraphId) # This duplication would cause a crash without the fix
|
||||
self.log("{node} duplicated with disabled component".format(node=nodeName))
|
||||
# Retrieve a mapping of the TypeIds for all the components
|
||||
# we will be checking for
|
||||
componentNames = list(set(nodes.values())) # Convert to set then back to list to remove any duplicates
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
|
||||
# Then, make sure we can duplicate the node with a dependent component that is deleted
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [component])
|
||||
general.idle_wait(1.0)
|
||||
graph.SceneRequestBus(bus.Event, 'DuplicateSelection', newGraphId) # This duplication would cause a crash without the fix
|
||||
self.log("{node} duplicated with deleted component".format(node=nodeName))
|
||||
# Iterate through creating our nodes and then disabling/deleting required components
|
||||
# and then duplicating the node to reproduce the crash
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in nodes:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
|
||||
x += 40.0
|
||||
y += 40.0
|
||||
dependentComponentName = nodes[nodeName]
|
||||
componentTypeId = componentTypeIds[dependentComponentName]
|
||||
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', newEntityId, componentTypeId)
|
||||
component = componentOutcome.GetValue()
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
# First make sure we can duplicate a node with a dependent component that is disabled
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'DisableComponents', [component])
|
||||
helper.wait_for_condition(lambda: not editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled',
|
||||
[component]), 1.0)
|
||||
graph.SceneRequestBus(bus.Event, 'DuplicateSelection', newGraphId) # This duplication would cause a crash without the fix
|
||||
Report.info("{node} duplicated with disabled component".format(node=nodeName))
|
||||
|
||||
# Then, make sure we can duplicate the node with a dependent component that is deleted
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [component])
|
||||
helper.wait_for_condition(lambda: not editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType',
|
||||
componentTypeIds[dependentComponentName]), 1.0)
|
||||
graph.SceneRequestBus(bus.Event, 'DuplicateSelection', newGraphId) # This duplication would cause a crash without the fix
|
||||
Report.info("{node} duplicated with deleted component".format(node=nodeName))
|
||||
|
||||
x += 40.0
|
||||
y += 40.0
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestDisabledNodeDuplication()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Edit_DisabledNodeDuplication)
|
||||
|
||||
+125
-124
@@ -5,133 +5,134 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.math as math
|
||||
import azlmbr.slice as slice
|
||||
import azlmbr.paths
|
||||
class Tests:
|
||||
slice_spawned = (
|
||||
"Slice instantiated successfully",
|
||||
"Failed to instantiate slice"
|
||||
)
|
||||
lc_entity_found = (
|
||||
"Landscape Canvas entity found",
|
||||
"Failed to find Landscape Canvas entity"
|
||||
)
|
||||
spawner_entity_found = (
|
||||
"Spawner entity found",
|
||||
"Failed to find Spawner entity"
|
||||
)
|
||||
graph_opened = (
|
||||
"Graph successfully opened",
|
||||
"Graph failed to open"
|
||||
)
|
||||
spawner_node_found = (
|
||||
"Vegetation Layer Spawner node found on graph",
|
||||
"Failed to find Vegetation Layer Spawner node on graph"
|
||||
)
|
||||
spawner_node_removed = (
|
||||
"Vegetation Layer Spawner node was successfully removed",
|
||||
"Failed to remove Vegetation Layer Spawner node"
|
||||
)
|
||||
def Edit_UndoNodeDelete_SliceEntity():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies Editor stability after undoing the deletion of nodes on a slice entity.
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
Expected Behavior:
|
||||
Editor remains stable and free of crashes.
|
||||
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Instantiate a slice with a Landscape Canvas setup
|
||||
3) Find a specific node on the graph, and delete it
|
||||
4) Restore the node with Undo
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.math as math
|
||||
import azlmbr.slice as slice
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Instantiate slice
|
||||
transform = math.Transform_CreateIdentity()
|
||||
position = math.Vector3(64.0, 64.0, 32.0)
|
||||
transform.invoke('SetPosition', position)
|
||||
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice")
|
||||
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(),
|
||||
False)
|
||||
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform)
|
||||
Report.result(Tests.slice_spawned, test_slice.IsValid())
|
||||
|
||||
# Find root entity in the loaded level
|
||||
search_filter = entity.SearchFilter()
|
||||
search_filter.names = ["LandscapeCanvas"]
|
||||
|
||||
# Allow a few seconds for matching entity to be found
|
||||
helper.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0)
|
||||
lc_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
|
||||
slice_root_id = lc_matching_entities[0] # Entity with Landscape Canvas component
|
||||
Report.result(Tests.lc_entity_found, slice_root_id.IsValid())
|
||||
|
||||
# Find the BushSpawner entity
|
||||
search_filter.names = ["BushSpawner"]
|
||||
spawner_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
|
||||
spawner_id = spawner_matching_entities[0] # Entity with Vegetation Layer Spawner component
|
||||
Report.result(Tests.spawner_entity_found, spawner_id.IsValid())
|
||||
|
||||
# Open Landscape Canvas and the existing graph
|
||||
general.open_pane('Landscape Canvas')
|
||||
open_graph = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id)
|
||||
Report.result(Tests.graph_opened, open_graph.IsValid())
|
||||
|
||||
# Get needed component type ids
|
||||
layer_spawner_type_id = hydra.get_component_type_id("Vegetation Layer Spawner")
|
||||
|
||||
# Find the Vegetation Layer Spawner node on the BushSpawner entity
|
||||
layer_spawner_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', spawner_id,
|
||||
layer_spawner_type_id)
|
||||
layer_spawner_component_component_id = layer_spawner_component.GetValue()
|
||||
layer_spawner_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent',
|
||||
layer_spawner_component_component_id)
|
||||
Report.result(Tests.spawner_node_found, layer_spawner_node is not None)
|
||||
|
||||
# Remove the Layer Spawner node
|
||||
graph.GraphControllerRequestBus(bus.Event, "RemoveNode", open_graph, layer_spawner_node[0])
|
||||
|
||||
# Verify node was removed
|
||||
layer_spawner_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent',
|
||||
layer_spawner_component_component_id)
|
||||
Report.result(Tests.spawner_node_removed, not layer_spawner_node)
|
||||
|
||||
# Undo the Node deletion. This is required to be executed twice to hit the node removal.
|
||||
general.undo()
|
||||
general.undo()
|
||||
|
||||
# self.log a line to the Console to verify the Editor is still active
|
||||
Report.info("Editor is still responsive")
|
||||
|
||||
|
||||
class TestUndoNodeDeleteSlice(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="UndoNodeDeleteSlice", args=["level"])
|
||||
if __name__ == "__main__":
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies Editor stability after undoing the deletion of nodes on a slice entity.
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Edit_UndoNodeDelete_SliceEntity)
|
||||
|
||||
Expected Behavior:
|
||||
Editor remains stable and free of crashes.
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Instantiate a slice with a Landscape Canvas setup
|
||||
3) Find a specific node on the graph, and delete it
|
||||
4) Restore the node with Undo
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
# Create a new empty level and instantiate LC_BushFlowerBlender.slice
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=128,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=128,
|
||||
use_terrain=False,
|
||||
)
|
||||
transform = math.Transform_CreateIdentity()
|
||||
position = math.Vector3(64.0, 64.0, 32.0)
|
||||
transform.invoke('SetPosition', position)
|
||||
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice")
|
||||
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(),
|
||||
False)
|
||||
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform)
|
||||
self.test_success = self.test_success and test_slice.IsValid()
|
||||
if test_slice.IsValid():
|
||||
self.log("Slice spawned!")
|
||||
|
||||
# Find root entity in the loaded level
|
||||
search_filter = entity.SearchFilter()
|
||||
search_filter.names = ["LandscapeCanvas"]
|
||||
|
||||
# Allow a few seconds for matching entity to be found
|
||||
self.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0,
|
||||
5.0)
|
||||
lc_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
|
||||
slice_root_id = lc_matching_entities[0] # Entity with Landscape Canvas component
|
||||
self.test_success = self.test_success and slice_root_id.IsValid()
|
||||
if slice_root_id.IsValid():
|
||||
self.log("LandscapeCanvas entity found")
|
||||
|
||||
# Find the BushSpawner entity
|
||||
search_filter.names = ["BushSpawner"]
|
||||
spawner_matching_entities = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)
|
||||
spawner_id = spawner_matching_entities[0] # Entity with Vegetation Layer Spawner component
|
||||
self.test_success = self.test_success and spawner_id.IsValid()
|
||||
if spawner_id.IsValid():
|
||||
self.log("BushSpawner entity found")
|
||||
|
||||
# Open Landscape Canvas and the existing graph
|
||||
general.open_pane('Landscape Canvas')
|
||||
open_graph = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id)
|
||||
self.test_success = self.test_success and open_graph.IsValid()
|
||||
if open_graph.IsValid():
|
||||
self.log("Graph opened")
|
||||
|
||||
# Get needed component type ids
|
||||
layer_spawner_type_id = hydra.get_component_type_id("Vegetation Layer Spawner")
|
||||
|
||||
# Find the Vegetation Layer Spawner node on the BushSpawner entity
|
||||
layer_spawner_component = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', spawner_id,
|
||||
layer_spawner_type_id)
|
||||
layer_spawner_component_component_id = layer_spawner_component.GetValue()
|
||||
layer_spawner_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent',
|
||||
layer_spawner_component_component_id)
|
||||
|
||||
self.test_success = self.test_success and layer_spawner_node
|
||||
if layer_spawner_node:
|
||||
self.log("Vegetation Layer Spawner node found on graph")
|
||||
else:
|
||||
self.log("Vegetation Layer Spawner node not found")
|
||||
|
||||
# Remove the Layer Spawner node
|
||||
graph.GraphControllerRequestBus(bus.Event, "RemoveNode", open_graph, layer_spawner_node[0])
|
||||
|
||||
# Verify node was removed
|
||||
layer_spawner_node = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'GetAllNodesMatchingEntityComponent',
|
||||
layer_spawner_component_component_id)
|
||||
|
||||
self.test_success = self.test_success and not layer_spawner_node
|
||||
if not layer_spawner_node:
|
||||
self.log("Vegetation Layer Spawner node was removed")
|
||||
else:
|
||||
self.log("Vegetation Layer Spawner node was not removed")
|
||||
|
||||
# Undo the Node deletion. This is required to be executed twice to hit the node removal.
|
||||
general.undo()
|
||||
general.undo()
|
||||
|
||||
# self.log a line to the Console to verify the Editor is still active
|
||||
self.log("Editor is still responsive")
|
||||
|
||||
|
||||
test = TestUndoNodeDeleteSlice()
|
||||
test.run()
|
||||
|
||||
+167
-152
@@ -5,190 +5,205 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
new_graph_created = (
|
||||
"Successfully created new graph",
|
||||
"Failed to create new graph"
|
||||
)
|
||||
graph_registered = (
|
||||
"Graph registered with Landscape Canvas",
|
||||
"Failed to register graph"
|
||||
)
|
||||
preview_entity_set = (
|
||||
"Perlin Noise Gradient component Preview Entity property set to Box Shape EntityId",
|
||||
"Unexpected entity set in Perlin Noise Gradient Preview Entity property"
|
||||
)
|
||||
mixer_inbound_gradient_set_a = (
|
||||
"Gradient Mixer component Inbound Gradient extendable property set to Perlin Noise Gradient EntityId",
|
||||
"Unexpected entity set in Gradient Mixer's Inbound Gradient property"
|
||||
)
|
||||
mixer_inbound_gradient_set_b = (
|
||||
"Gradient Mixer component Inbound Gradient extendable property set to FastNoise Gradient EntityId",
|
||||
"Unexpected entity set in Gradient Mixer's Inbound Gradient property"
|
||||
)
|
||||
mixer_operation_a = (
|
||||
"Layer 1 Operation is set to Initialize",
|
||||
"Layer 1 Operation is not set to Initialize as expected"
|
||||
)
|
||||
mixer_operation_b = (
|
||||
"Layer 2 Operation is set to Average",
|
||||
"Layer 2 Operation is not set to Average as expected"
|
||||
)
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
newEntityId = None
|
||||
|
||||
|
||||
class TestGradientMixerNodeConstruction(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientMixerNodeConstruction", args=["level"])
|
||||
def GradientMixer_NodeConstruction():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies a Gradient Mixer vegetation setup can be constructed through Landscape Canvas.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies a Gradient Mixer vegetation setup can be constructed through Landscape Canvas.
|
||||
Expected Behavior:
|
||||
Entities contain all required components and component references after creating nodes and setting connections
|
||||
on a Landscape Canvas graph.
|
||||
|
||||
Expected Behavior:
|
||||
Entities contain all required components and component references after creating nodes and setting connections
|
||||
on a Landscape Canvas graph.
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Add all necessary nodes to the graph and set connections to form a Gradient Mixer setup
|
||||
4) Verify all components and component references were properly set during graph construction
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Add all necessary nodes to the graph and set connections to form a Gradient Mixer setup
|
||||
4) Verify all components and component references were properly set during graph construction
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
:return: None
|
||||
"""
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
|
||||
if general.is_pane_visible('Landscape Canvas'):
|
||||
self.log('Landscape Canvas pane is open')
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId
|
||||
if newGraphId:
|
||||
self.log("New graph created")
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
self.test_success = self.test_success and success
|
||||
if success:
|
||||
self.log("Graph registered with Landscape Canvas")
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Listen for entity creation notifications so we can verify the component EntityId
|
||||
# references are set correctly when connecting slots on the nodes
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
|
||||
|
||||
positionX = 10.0
|
||||
positionY = 10.0
|
||||
offsetX = 340.0
|
||||
offsetY = 100.0
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# Add a Box Shape node to the graph
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
boxShapeNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
|
||||
'BoxShapeNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, boxShapeNode, math.Vector2(positionX, positionY))
|
||||
boxShapeEntityId = newEntityId
|
||||
# Listen for entity creation notifications so we can verify the component EntityId
|
||||
# references are set correctly when connecting slots on the nodes
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
|
||||
positionX += offsetX
|
||||
positionY += offsetY
|
||||
positionX = 10.0
|
||||
positionY = 10.0
|
||||
offsetX = 340.0
|
||||
offsetY = 100.0
|
||||
|
||||
# Add a Random Noise Gradient node to the graph
|
||||
perlinNoiseNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
|
||||
'PerlinNoiseGradientNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, perlinNoiseNode, math.Vector2(positionX, positionY))
|
||||
perlinNoiseEntityId = newEntityId
|
||||
# Add a Box Shape node to the graph
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
boxShapeNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
|
||||
'BoxShapeNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, boxShapeNode, math.Vector2(positionX, positionY))
|
||||
boxShapeEntityId = newEntityId
|
||||
|
||||
positionX += offsetX
|
||||
positionY += offsetY
|
||||
positionX += offsetX
|
||||
positionY += offsetY
|
||||
|
||||
# Add a FastNoise Gradient node to the graph
|
||||
fastNoiseNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
|
||||
'FastNoiseGradientNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, fastNoiseNode, math.Vector2(positionX, positionY))
|
||||
fastNoiseEntityId = newEntityId
|
||||
# Add a Random Noise Gradient node to the graph
|
||||
perlinNoiseNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
|
||||
'PerlinNoiseGradientNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, perlinNoiseNode, math.Vector2(positionX, positionY))
|
||||
perlinNoiseEntityId = newEntityId
|
||||
|
||||
positionX += offsetX
|
||||
positionY += offsetY
|
||||
positionX += offsetX
|
||||
positionY += offsetY
|
||||
|
||||
# Add a Gradient Mixer node to the graph
|
||||
gradientMixerNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
|
||||
'GradientMixerNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, gradientMixerNode, math.Vector2(positionX, positionY))
|
||||
gradientMixerEntityId = newEntityId
|
||||
# Add a FastNoise Gradient node to the graph
|
||||
fastNoiseNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
|
||||
'FastNoiseGradientNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, fastNoiseNode, math.Vector2(positionX, positionY))
|
||||
fastNoiseEntityId = newEntityId
|
||||
|
||||
boundsSlotId = graph.GraphModelSlotId('Bounds')
|
||||
previewBoundsSlotId = graph.GraphModelSlotId('PreviewBounds')
|
||||
inboundGradientSlotId = graph.GraphModelSlotId('InboundGradient')
|
||||
outboundGradientSlotId = graph.GraphModelSlotId('OutboundGradient')
|
||||
inboundGradientSlotId2 = graph.GraphControllerRequestBus(bus.Event, 'ExtendSlot', newGraphId, gradientMixerNode,
|
||||
'InboundGradient')
|
||||
positionX += offsetX
|
||||
positionY += offsetY
|
||||
|
||||
# Connect slots on our nodes to construct a Gradient Mixer hierarchy
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
|
||||
perlinNoiseNode, previewBoundsSlotId)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
|
||||
fastNoiseNode, previewBoundsSlotId)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
|
||||
gradientMixerNode, previewBoundsSlotId)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, perlinNoiseNode, outboundGradientSlotId,
|
||||
gradientMixerNode, inboundGradientSlotId)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, fastNoiseNode, outboundGradientSlotId,
|
||||
gradientMixerNode, inboundGradientSlotId2)
|
||||
# Add a Gradient Mixer node to the graph
|
||||
gradientMixerNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph,
|
||||
'GradientMixerNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, gradientMixerNode, math.Vector2(positionX, positionY))
|
||||
gradientMixerEntityId = newEntityId
|
||||
|
||||
# Delay to allow all the underlying component properties to be updated after the slot connections are made
|
||||
general.idle_wait(1.0)
|
||||
boundsSlotId = graph.GraphModelSlotId('Bounds')
|
||||
previewBoundsSlotId = graph.GraphModelSlotId('PreviewBounds')
|
||||
inboundGradientSlotId = graph.GraphModelSlotId('InboundGradient')
|
||||
outboundGradientSlotId = graph.GraphModelSlotId('OutboundGradient')
|
||||
inboundGradientSlotId2 = graph.GraphControllerRequestBus(bus.Event, 'ExtendSlot', newGraphId, gradientMixerNode,
|
||||
'InboundGradient')
|
||||
|
||||
# Get component info
|
||||
gradientMixerTypeId = hydra.get_component_type_id("Gradient Mixer")
|
||||
perlinNoiseTypeId = hydra.get_component_type_id("Perlin Noise Gradient")
|
||||
gradientMixerOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', gradientMixerEntityId,
|
||||
gradientMixerTypeId)
|
||||
gradientMixerComponent = gradientMixerOutcome.GetValue()
|
||||
perlinNoiseOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', perlinNoiseEntityId,
|
||||
perlinNoiseTypeId)
|
||||
perlinNoiseComponent = perlinNoiseOutcome.GetValue()
|
||||
# Connect slots on our nodes to construct a Gradient Mixer hierarchy
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
|
||||
perlinNoiseNode, previewBoundsSlotId)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
|
||||
fastNoiseNode, previewBoundsSlotId)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
|
||||
gradientMixerNode, previewBoundsSlotId)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, perlinNoiseNode, outboundGradientSlotId,
|
||||
gradientMixerNode, inboundGradientSlotId)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, fastNoiseNode, outboundGradientSlotId,
|
||||
gradientMixerNode, inboundGradientSlotId2)
|
||||
|
||||
# Verify the Preview EntityId property on our Perlin Noise Gradient component has been set to our Box Shape's EntityId
|
||||
previewEntityId = hydra.get_component_property_value(perlinNoiseComponent, 'Preview Settings|Pin Preview to Shape')
|
||||
self.test_success = self.test_success and previewEntityId and boxShapeEntityId.invoke("Equal", previewEntityId)
|
||||
if previewEntityId and boxShapeEntityId.invoke("Equal", previewEntityId):
|
||||
self.log("Perlin Noise Gradient component Preview Entity property set to Box Shape EntityId")
|
||||
# Delay to allow all the underlying component properties to be updated after the slot connections are made
|
||||
general.idle_wait(1.0)
|
||||
|
||||
# Verify the 1st Inbound Gradient EntityId property on our Gradient Mixer component has been set to our Perlin Noise
|
||||
# Gradient's EntityId
|
||||
inboundGradientEntityId = hydra.get_component_property_value(gradientMixerComponent,
|
||||
'Configuration|Layers|[0]|Gradient|Gradient Entity Id')
|
||||
self.test_success = self.test_success and inboundGradientEntityId and perlinNoiseEntityId.invoke("Equal", inboundGradientEntityId)
|
||||
if inboundGradientEntityId and perlinNoiseEntityId.invoke("Equal", inboundGradientEntityId):
|
||||
self.log("Gradient Mixer component Inbound Gradient extendable property set to Perlin Noise Gradient EntityId")
|
||||
# Get component info
|
||||
gradientMixerTypeId = hydra.get_component_type_id("Gradient Mixer")
|
||||
perlinNoiseTypeId = hydra.get_component_type_id("Perlin Noise Gradient")
|
||||
gradientMixerOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', gradientMixerEntityId,
|
||||
gradientMixerTypeId)
|
||||
gradientMixerComponent = gradientMixerOutcome.GetValue()
|
||||
perlinNoiseOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', perlinNoiseEntityId,
|
||||
perlinNoiseTypeId)
|
||||
perlinNoiseComponent = perlinNoiseOutcome.GetValue()
|
||||
|
||||
# Verify the 2nd Inbound Gradient EntityId property on our Gradient Mixer component has been set to our FastNoise
|
||||
# Gradient Modifier's EntityId
|
||||
inboundGradientEntityId2 = hydra.get_component_property_value(gradientMixerComponent,
|
||||
'Configuration|Layers|[1]|Gradient|Gradient Entity Id')
|
||||
self.test_success = self.test_success and inboundGradientEntityId2 and fastNoiseEntityId.invoke("Equal", inboundGradientEntityId2)
|
||||
if inboundGradientEntityId2 and fastNoiseEntityId.invoke("Equal", inboundGradientEntityId2):
|
||||
self.log("Gradient Mixer component Inbound Gradient extendable property set to FastNoise Gradient EntityId")
|
||||
# Verify the Preview EntityId property on our Perlin Noise Gradient component has been set to our Box Shape's EntityId
|
||||
previewEntityId = hydra.get_component_property_value(perlinNoiseComponent, 'Preview Settings|Pin Preview to Shape')
|
||||
Report.result(Tests.preview_entity_set, previewEntityId and boxShapeEntityId.invoke("Equal", previewEntityId))
|
||||
|
||||
# Verify that Gradient Mixer Layer Operations are properly set
|
||||
hydra.get_component_property_value(gradientMixerComponent, 'Configuration|Layers|[0]|Operation')
|
||||
hydra.get_component_property_value(gradientMixerComponent, 'Configuration|Layers|[1]|Operation')
|
||||
# Verify the 1st Inbound Gradient EntityId property on our Gradient Mixer component has been set to our Perlin Noise
|
||||
# Gradient's EntityId
|
||||
inboundGradientEntityId = hydra.get_component_property_value(gradientMixerComponent,
|
||||
'Configuration|Layers|[0]|Gradient|Gradient Entity Id')
|
||||
Report.result(Tests.mixer_inbound_gradient_set_a, inboundGradientEntityId and perlinNoiseEntityId.invoke("Equal", inboundGradientEntityId))
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
# Verify the 2nd Inbound Gradient EntityId property on our Gradient Mixer component has been set to our FastNoise
|
||||
# Gradient Modifier's EntityId
|
||||
inboundGradientEntityId2 = hydra.get_component_property_value(gradientMixerComponent,
|
||||
'Configuration|Layers|[1]|Gradient|Gradient Entity Id')
|
||||
Report.result(Tests.mixer_inbound_gradient_set_b, inboundGradientEntityId2 and fastNoiseEntityId.invoke("Equal", inboundGradientEntityId2))
|
||||
|
||||
# Verify that Gradient Mixer Layer Operations are properly set
|
||||
mixer_operation_a = hydra.get_component_property_value(gradientMixerComponent, 'Configuration|Layers|[0]|Operation')
|
||||
mixer_operation_b = hydra.get_component_property_value(gradientMixerComponent, 'Configuration|Layers|[1]|Operation')
|
||||
Report.result(Tests.mixer_operation_a, mixer_operation_a == 0)
|
||||
Report.result(Tests.mixer_operation_b, mixer_operation_b == 6)
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestGradientMixerNodeConstruction()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientMixer_NodeConstruction)
|
||||
|
||||
+106
-104
@@ -5,132 +5,134 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
new_graph_created = (
|
||||
"Successfully created new graph",
|
||||
"Failed to create new graph"
|
||||
)
|
||||
graph_registered = (
|
||||
"Graph registered with Landscape Canvas",
|
||||
"Failed to register graph"
|
||||
)
|
||||
component_added = (
|
||||
"New entity created with the expected component",
|
||||
"Expected component was not found on entity"
|
||||
)
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
newEntityId = None
|
||||
|
||||
|
||||
class TestGradientModifierNodeEntityCreate(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientModifierNodeEntityCreate", args=["level"])
|
||||
def GradientModifierNodes_EntityCreatedOnNodeAdd():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
|
||||
Expected Behavior:
|
||||
New entities are created when dragging Gradient Modifier nodes to graph area.
|
||||
|
||||
Expected Behavior:
|
||||
New entities are created when dragging Gradient Modifier nodes to graph area.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the Gradient Modifier nodes to the graph area, and ensure a new entity is created
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the Gradient Modifier nodes to the graph area, and ensure a new entity is created
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
:return: None
|
||||
"""
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=128,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=128,
|
||||
use_terrain=False,
|
||||
)
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
|
||||
if general.is_pane_visible('Landscape Canvas'):
|
||||
self.log('Landscape Canvas pane is open')
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId
|
||||
if newGraphId:
|
||||
self.log("New graph created")
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
self.test_success = self.test_success and success
|
||||
if success:
|
||||
self.log("Graph registered with Landscape Canvas")
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding gradient modifier nodes has the appropriate Gradient Modifier Component
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
|
||||
|
||||
# Gradient modifier mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the Entity created for the node
|
||||
gradientModifiers = {
|
||||
'DitherGradientModifierNode': 'Dither Gradient Modifier',
|
||||
'GradientMixerNode': 'Gradient Mixer',
|
||||
'InvertGradientModifierNode': 'Invert Gradient Modifier',
|
||||
'LevelsGradientModifierNode': 'Levels Gradient Modifier',
|
||||
'PosterizeGradientModifierNode': 'Posterize Gradient Modifier',
|
||||
'SmoothStepGradientModifierNode': 'Smooth-Step Gradient Modifier',
|
||||
'ThresholdGradientModifierNode': 'Threshold Gradient Modifier'
|
||||
}
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# Retrieve a mapping of the TypeIds for all the components
|
||||
# we will be checking for
|
||||
componentNames = []
|
||||
for name in gradientModifiers:
|
||||
componentNames.append(gradientModifiers[name])
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding gradient modifier nodes has the appropriate Gradient Modifier Component
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
|
||||
# Create nodes for all the gradients modifiers we support and check if the Entity created by
|
||||
# adding the node has the appropriate Component added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in gradientModifiers:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
# Gradient modifier mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the Entity created for the node
|
||||
gradientModifiers = {
|
||||
'DitherGradientModifierNode': 'Dither Gradient Modifier',
|
||||
'GradientMixerNode': 'Gradient Mixer',
|
||||
'InvertGradientModifierNode': 'Invert Gradient Modifier',
|
||||
'LevelsGradientModifierNode': 'Levels Gradient Modifier',
|
||||
'PosterizeGradientModifierNode': 'Posterize Gradient Modifier',
|
||||
'SmoothStepGradientModifierNode': 'Smooth-Step Gradient Modifier',
|
||||
'ThresholdGradientModifierNode': 'Threshold Gradient Modifier'
|
||||
}
|
||||
|
||||
gradientComponent = gradientModifiers[nodeName]
|
||||
componentTypeId = componentTypeIds[gradientComponent]
|
||||
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
|
||||
componentTypeId)
|
||||
self.test_success = self.test_success and hasComponent
|
||||
if hasComponent:
|
||||
self.log("{node} created new Entity with {component} Component".format(node=nodeName,
|
||||
component=gradientComponent))
|
||||
# Retrieve a mapping of the TypeIds for all the components
|
||||
# we will be checking for
|
||||
componentNames = []
|
||||
for name in gradientModifiers:
|
||||
componentNames.append(gradientModifiers[name])
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
|
||||
x += 40.0
|
||||
y += 40.0
|
||||
# Create nodes for all the gradients modifiers we support and check if the Entity created by
|
||||
# adding the node has the appropriate Component added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in gradientModifiers:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
gradientComponent = gradientModifiers[nodeName]
|
||||
componentTypeId = componentTypeIds[gradientComponent]
|
||||
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
|
||||
componentTypeId)
|
||||
Report.info(f"Node: {nodeName} | Component: {gradientComponent}")
|
||||
Report.result(Tests.component_added, hasComponent)
|
||||
|
||||
x += 40.0
|
||||
y += 40.0
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestGradientModifierNodeEntityCreate()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientModifierNodes_EntityCreatedOnNodeAdd)
|
||||
|
||||
+100
-97
@@ -5,126 +5,129 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
new_graph_created = (
|
||||
"Successfully created new graph",
|
||||
"Failed to create new graph"
|
||||
)
|
||||
graph_registered = (
|
||||
"Graph registered with Landscape Canvas",
|
||||
"Failed to register graph"
|
||||
)
|
||||
entity_deleted = (
|
||||
"Entity was deleted when node was removed",
|
||||
"Entity was not deleted as expected when node was removed"
|
||||
)
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
createdEntityId = None
|
||||
deletedEntityId = None
|
||||
|
||||
|
||||
class TestGradientModifierNodeEntityDelete(EditorTestHelper):
|
||||
def GradientModifierNodes_EntityRemovedOnNodeDelete():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
|
||||
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientModifierNodeEntityDelete", args=["level"])
|
||||
Expected Behavior:
|
||||
Entities are removed when Gradient Modifier nodes are deleted from a graph.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the Gradient Modifier nodes to the graph area, and ensure a new entity is created
|
||||
4) Delete the nodes, and ensure the newly created entities are removed
|
||||
|
||||
Expected Behavior:
|
||||
Entities are removed when Gradient Modifier nodes are deleted from a graph.
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the Gradient Modifier nodes to the graph area, and ensure a new entity is created
|
||||
4) Delete the nodes, and ensure the newly created entities are removed
|
||||
:return: None
|
||||
"""
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
|
||||
:return: None
|
||||
"""
|
||||
def onEntityCreated(parameters):
|
||||
global createdEntityId
|
||||
createdEntityId = parameters[0]
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
def onEntityDeleted(parameters):
|
||||
global deletedEntityId
|
||||
deletedEntityId = parameters[0]
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=128,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=128,
|
||||
use_terrain=False,
|
||||
)
|
||||
def onEntityCreated(parameters):
|
||||
global createdEntityId
|
||||
createdEntityId = parameters[0]
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
|
||||
if general.is_pane_visible('Landscape Canvas'):
|
||||
self.log('Landscape Canvas pane is open')
|
||||
def onEntityDeleted(parameters):
|
||||
global deletedEntityId
|
||||
deletedEntityId = parameters[0]
|
||||
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId
|
||||
if newGraphId:
|
||||
self.log("New graph created")
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
self.test_success = self.test_success and success
|
||||
if success:
|
||||
self.log("Graph registered with Landscape Canvas")
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding gradient nodes has the appropriate Gradient Component
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
|
||||
|
||||
# Vegetation Area mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the Entity created for the node
|
||||
gradientModifiers = [
|
||||
'DitherGradientModifierNode',
|
||||
'GradientMixerNode',
|
||||
'InvertGradientModifierNode',
|
||||
'LevelsGradientModifierNode',
|
||||
'PosterizeGradientModifierNode',
|
||||
'SmoothStepGradientModifierNode',
|
||||
'ThresholdGradientModifierNode'
|
||||
]
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# Create nodes for all the gradients we support and check if the Entity created by
|
||||
# adding the node has the appropriate Component added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in gradientModifiers:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding gradient nodes has the appropriate Gradient Component
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
|
||||
|
||||
removed = graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, node)
|
||||
# Vegetation Area mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the Entity created for the node
|
||||
gradientModifiers = [
|
||||
'DitherGradientModifierNode',
|
||||
'GradientMixerNode',
|
||||
'InvertGradientModifierNode',
|
||||
'LevelsGradientModifierNode',
|
||||
'PosterizeGradientModifierNode',
|
||||
'SmoothStepGradientModifierNode',
|
||||
'ThresholdGradientModifierNode'
|
||||
]
|
||||
|
||||
# Verify that the created Entity for this node matches the Entity that gets
|
||||
# deleted when the node is removed
|
||||
self.test_success = self.test_success and removed and createdEntityId.invoke("Equal", deletedEntityId)
|
||||
if removed and createdEntityId.invoke("Equal", deletedEntityId):
|
||||
self.log("{node} corresponding Entity was deleted when node is removed".format(node=nodeName))
|
||||
# Create nodes for all the gradients we support and check if the Entity created by
|
||||
# adding the node has the appropriate Component added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in gradientModifiers:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
removed = graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, node)
|
||||
|
||||
# Verify that the created Entity for this node matches the Entity that gets
|
||||
# deleted when the node is removed
|
||||
Report.info(f"Node: {nodeName}")
|
||||
Report.result(Tests.entity_deleted, removed and createdEntityId.invoke("Equal", deletedEntityId))
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestGradientModifierNodeEntityDelete()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientModifierNodes_EntityRemovedOnNodeDelete)
|
||||
|
||||
+114
-112
@@ -5,141 +5,143 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
new_graph_created = (
|
||||
"Successfully created new graph",
|
||||
"Failed to create new graph"
|
||||
)
|
||||
graph_registered = (
|
||||
"Graph registered with Landscape Canvas",
|
||||
"Failed to register graph"
|
||||
)
|
||||
dependencies_added = (
|
||||
"Node created new Entity with all required components",
|
||||
"Failed to create node with all required components"
|
||||
)
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
newEntityId = None
|
||||
|
||||
|
||||
class TestGradientNodeComponentDependency(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientNodeComponentDependency", args=["level"])
|
||||
def GradientNodes_DependentComponentsAdded():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities with
|
||||
proper dependent components.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities with
|
||||
proper dependent components.
|
||||
Expected Behavior:
|
||||
All expected component dependencies are met when adding a Gradient Modifier node to a graph.
|
||||
|
||||
Expected Behavior:
|
||||
All expected component dependencies are met when adding a Gradient Modifier node to a graph.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the Gradient Modifier nodes to the graph area, and ensure the proper dependent components are
|
||||
added
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the Gradient Modifier nodes to the graph area, and ensure the proper dependent components are
|
||||
added
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
:return: None
|
||||
"""
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
|
||||
if general.is_pane_visible('Landscape Canvas'):
|
||||
self.log('Landscape Canvas pane is open')
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId
|
||||
if newGraphId:
|
||||
self.log("New graph created")
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
self.test_success = self.test_success and success
|
||||
if success:
|
||||
self.log("Graph registered with Landscape Canvas")
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding these gradients nodes has the main target Gradient Component
|
||||
# as well as automatically adding all required dependency components
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
|
||||
|
||||
# Gradient mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the Entity created for the node
|
||||
gradients = {
|
||||
'FastNoiseGradientNode': 'FastNoise Gradient',
|
||||
'ImageGradientNode': 'Image Gradient',
|
||||
'PerlinNoiseGradientNode': 'Perlin Noise Gradient',
|
||||
'RandomNoiseGradientNode': 'Random Noise Gradient'
|
||||
}
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# Retrieve a mapping of the TypeIds for all the components
|
||||
# we will be checking for
|
||||
commonComponents = [
|
||||
'Gradient Transform Modifier',
|
||||
'Vegetation Reference Shape'
|
||||
]
|
||||
componentNames = []
|
||||
for name in gradients:
|
||||
componentNames.append(gradients[name])
|
||||
componentNames.extend(commonComponents)
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding these gradients nodes has the main target Gradient Component
|
||||
# as well as automatically adding all required dependency components
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
|
||||
# Create nodes for the gradients that have additional required dependencies and check if
|
||||
# the Entity created by adding the node has the appropriate Component and required
|
||||
# Gradient Transform Modifier and Vegetation Reference Shape components added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in gradients:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
# Gradient mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the Entity created for the node
|
||||
gradients = {
|
||||
'FastNoiseGradientNode': 'FastNoise Gradient',
|
||||
'ImageGradientNode': 'Image Gradient',
|
||||
'PerlinNoiseGradientNode': 'Perlin Noise Gradient',
|
||||
'RandomNoiseGradientNode': 'Random Noise Gradient'
|
||||
}
|
||||
|
||||
gradientComponent = gradients[nodeName]
|
||||
components = [gradientComponent] + commonComponents
|
||||
success = False
|
||||
for component in components:
|
||||
componentTypeId = componentTypeIds[component]
|
||||
success = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, componentTypeId)
|
||||
self.test_success = self.test_success and success
|
||||
if not success:
|
||||
break
|
||||
# Retrieve a mapping of the TypeIds for all the components
|
||||
# we will be checking for
|
||||
commonComponents = [
|
||||
'Gradient Transform Modifier',
|
||||
'Vegetation Reference Shape'
|
||||
]
|
||||
componentNames = []
|
||||
for name in gradients:
|
||||
componentNames.append(gradients[name])
|
||||
componentNames.extend(commonComponents)
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
|
||||
if success:
|
||||
self.log("{node} created new Entity with all required components".format(node=nodeName))
|
||||
# Create nodes for the gradients that have additional required dependencies and check if
|
||||
# the Entity created by adding the node has the appropriate Component and required
|
||||
# Gradient Transform Modifier and Vegetation Reference Shape components added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in gradients:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
|
||||
x += 40.0
|
||||
y += 40.0
|
||||
gradientComponent = gradients[nodeName]
|
||||
components = [gradientComponent] + commonComponents
|
||||
success = False
|
||||
for component in components:
|
||||
componentTypeId = componentTypeIds[component]
|
||||
success = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, componentTypeId)
|
||||
if not success:
|
||||
break
|
||||
Report.info(nodeName)
|
||||
Report.result(Tests.dependencies_added, success)
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
x += 40.0
|
||||
y += 40.0
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestGradientNodeComponentDependency()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientNodes_DependentComponentsAdded)
|
||||
|
||||
+106
-102
@@ -5,130 +5,134 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os, sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
new_graph_created = (
|
||||
"Successfully created new graph",
|
||||
"Failed to create new graph"
|
||||
)
|
||||
graph_registered = (
|
||||
"Graph registered with Landscape Canvas",
|
||||
"Failed to register graph"
|
||||
)
|
||||
component_added = (
|
||||
"New entity created with the expected component",
|
||||
"Expected component was not found on entity"
|
||||
)
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
newEntityId = None
|
||||
|
||||
|
||||
class TestGradientNodeEntityCreate(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientNodeEntityCreate", args=["level"])
|
||||
def GradientNodes_EntityCreatedOnNodeAdd():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities.
|
||||
Expected Behavior:
|
||||
New entities are created when dragging Gradient nodes to graph area.
|
||||
|
||||
Expected Behavior:
|
||||
New entities are created when dragging Gradient nodes to graph area.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the Gradient nodes to the graph area, and ensure a new entity is created
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the Gradient nodes to the graph area, and ensure a new entity is created
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
:return: None
|
||||
"""
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
|
||||
if general.is_pane_visible('Landscape Canvas'):
|
||||
self.log('Landscape Canvas pane is open')
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId
|
||||
if newGraphId:
|
||||
self.log("New graph created")
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
self.test_success = self.test_success and success
|
||||
if success:
|
||||
self.log("Graph registered with Landscape Canvas")
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding gradient nodes has the appropriate Gradient Component
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
|
||||
|
||||
# Gradient mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the Entity created for the node
|
||||
gradients = {
|
||||
'AltitudeGradientNode': 'Altitude Gradient',
|
||||
'ConstantGradientNode': 'Constant Gradient',
|
||||
'FastNoiseGradientNode': 'FastNoise Gradient',
|
||||
'ImageGradientNode': 'Image Gradient',
|
||||
'PerlinNoiseGradientNode': 'Perlin Noise Gradient',
|
||||
'RandomNoiseGradientNode': 'Random Noise Gradient',
|
||||
'ShapeAreaFalloffGradientNode': 'Shape Falloff Gradient',
|
||||
'SlopeGradientNode': 'Slope Gradient',
|
||||
'SurfaceMaskGradientNode': 'Surface Mask Gradient',
|
||||
}
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# Retrieve a mapping of the TypeIds for all the components
|
||||
# we will be checking for
|
||||
componentNames = []
|
||||
for name in gradients:
|
||||
componentNames.append(gradients[name])
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding gradient nodes has the appropriate Gradient Component
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
|
||||
# Create nodes for all the gradients we support and check if the Entity created by
|
||||
# adding the node has the appropriate Component added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in gradients:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
# Gradient mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the Entity created for the node
|
||||
gradients = {
|
||||
'AltitudeGradientNode': 'Altitude Gradient',
|
||||
'ConstantGradientNode': 'Constant Gradient',
|
||||
'FastNoiseGradientNode': 'FastNoise Gradient',
|
||||
'ImageGradientNode': 'Image Gradient',
|
||||
'PerlinNoiseGradientNode': 'Perlin Noise Gradient',
|
||||
'RandomNoiseGradientNode': 'Random Noise Gradient',
|
||||
'ShapeAreaFalloffGradientNode': 'Shape Falloff Gradient',
|
||||
'SlopeGradientNode': 'Slope Gradient',
|
||||
'SurfaceMaskGradientNode': 'Surface Mask Gradient',
|
||||
}
|
||||
|
||||
gradientComponent = gradients[nodeName]
|
||||
componentTypeId = componentTypeIds[gradientComponent]
|
||||
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, componentTypeId)
|
||||
self.test_success = self.test_success and hasComponent
|
||||
if hasComponent:
|
||||
self.log("{node} created new Entity with {component} Component".format(node=nodeName, component=gradientComponent))
|
||||
# Retrieve a mapping of the TypeIds for all the components
|
||||
# we will be checking for
|
||||
componentNames = []
|
||||
for name in gradients:
|
||||
componentNames.append(gradients[name])
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
|
||||
x += 40.0
|
||||
y += 40.0
|
||||
# Create nodes for all the gradients we support and check if the Entity created by
|
||||
# adding the node has the appropriate Component added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in gradients:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
gradientComponent = gradients[nodeName]
|
||||
componentTypeId = componentTypeIds[gradientComponent]
|
||||
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, componentTypeId)
|
||||
Report.info(f"Node: {nodeName} | Component: {gradientComponent}")
|
||||
Report.result(Tests.component_added, hasComponent)
|
||||
|
||||
x += 40.0
|
||||
y += 40.0
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestGradientNodeEntityCreate()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientNodes_EntityCreatedOnNodeAdd)
|
||||
|
||||
+101
-99
@@ -5,129 +5,131 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
new_graph_created = (
|
||||
"Successfully created new graph",
|
||||
"Failed to create new graph"
|
||||
)
|
||||
graph_registered = (
|
||||
"Graph registered with Landscape Canvas",
|
||||
"Failed to register graph"
|
||||
)
|
||||
entity_deleted = (
|
||||
"Entity was deleted when node was removed",
|
||||
"Entity was not deleted as expected when node was removed"
|
||||
)
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
createdEntityId = None
|
||||
deletedEntityId = None
|
||||
|
||||
|
||||
class TestGradientNodeEntityDelete(EditorTestHelper):
|
||||
def GradientNodes_EntityRemovedOnNodeDelete():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
|
||||
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GradientNodeEntityDelete", args=["level"])
|
||||
Expected Behavior:
|
||||
Entities are removed when Gradient nodes are deleted from a graph.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the Gradient nodes to the graph area, and ensure a new entity is created
|
||||
4) Delete the nodes, and ensure the newly created entities are removed
|
||||
|
||||
Expected Behavior:
|
||||
Entities are removed when Gradient nodes are deleted from a graph.
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Drag each of the Gradient nodes to the graph area, and ensure a new entity is created
|
||||
4) Delete the nodes, and ensure the newly created entities are removed
|
||||
:return: None
|
||||
"""
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
|
||||
:return: None
|
||||
"""
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
def onEntityCreated(parameters):
|
||||
global createdEntityId
|
||||
createdEntityId = parameters[0]
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
def onEntityDeleted(parameters):
|
||||
global deletedEntityId
|
||||
deletedEntityId = parameters[0]
|
||||
def onEntityCreated(parameters):
|
||||
global createdEntityId
|
||||
createdEntityId = parameters[0]
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
def onEntityDeleted(parameters):
|
||||
global deletedEntityId
|
||||
deletedEntityId = parameters[0]
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
|
||||
if general.is_pane_visible('Landscape Canvas'):
|
||||
self.log('Landscape Canvas pane is open')
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId
|
||||
if newGraphId:
|
||||
self.log("New graph created")
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
self.test_success = self.test_success and success
|
||||
if success:
|
||||
self.log("Graph registered with Landscape Canvas")
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
|
||||
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding gradient nodes has the appropriate Gradient Component
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# Gradient mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the Entity created for the node
|
||||
gradients = [
|
||||
'AltitudeGradientNode',
|
||||
'ConstantGradientNode',
|
||||
'FastNoiseGradientNode',
|
||||
'ImageGradientNode',
|
||||
'PerlinNoiseGradientNode',
|
||||
'RandomNoiseGradientNode',
|
||||
'ShapeAreaFalloffGradientNode',
|
||||
'SlopeGradientNode',
|
||||
'SurfaceMaskGradientNode',
|
||||
]
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding gradient nodes has the appropriate Gradient Component
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
|
||||
|
||||
# Create nodes for all the gradients we support and check if the Entity created by
|
||||
# adding the node has the appropriate Component added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in gradients:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
# Gradient mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the Entity created for the node
|
||||
gradients = [
|
||||
'AltitudeGradientNode',
|
||||
'ConstantGradientNode',
|
||||
'FastNoiseGradientNode',
|
||||
'ImageGradientNode',
|
||||
'PerlinNoiseGradientNode',
|
||||
'RandomNoiseGradientNode',
|
||||
'ShapeAreaFalloffGradientNode',
|
||||
'SlopeGradientNode',
|
||||
'SurfaceMaskGradientNode',
|
||||
]
|
||||
|
||||
removed = graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, node)
|
||||
# Create nodes for all the gradients we support and check if the Entity created by
|
||||
# adding the node has the appropriate Component added automatically to it
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in gradients:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
|
||||
# Verify that the created Entity for this node matches the Entity that gets
|
||||
# deleted when the node is removed
|
||||
self.test_success = self.test_success and removed and createdEntityId.invoke("Equal", deletedEntityId)
|
||||
if removed and createdEntityId.invoke("Equal", deletedEntityId):
|
||||
self.log("{node} corresponding Entity was deleted when node is removed".format(node=nodeName))
|
||||
removed = graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, node)
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
# Verify that the created Entity for this node matches the Entity that gets
|
||||
# deleted when the node is removed
|
||||
Report.info(f"Node: {nodeName}")
|
||||
Report.result(Tests.entity_deleted, removed and createdEntityId.invoke("Equal", deletedEntityId))
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestGradientNodeEntityDelete()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GradientNodes_EntityRemovedOnNodeDelete)
|
||||
|
||||
+73
-74
@@ -5,100 +5,99 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.paths
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
graph_registered = (
|
||||
"Graph registered with Landscape Canvas",
|
||||
"Failed to register graph"
|
||||
)
|
||||
graph_closed = (
|
||||
"Graph closed on entity delete",
|
||||
"Graph is still open after entity delete"
|
||||
)
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
newRootEntityId = None
|
||||
|
||||
|
||||
class TestGraphClosedOnEntityDelete(EditorTestHelper):
|
||||
def GraphClosed_OnEntityDelete():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that Landscape Canvas graphs are auto-closed when the corresponding entity is deleted.
|
||||
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GraphClosedOnEntityDelete", args=["level"])
|
||||
Expected Behavior:
|
||||
When a Landscape Canvas root entity is deleted, the corresponding graph automatically closes.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that Landscape Canvas graphs are auto-closed when the corresponding entity is deleted.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Delete the automatically created entity
|
||||
4) Verify the open graph is closed
|
||||
|
||||
Expected Behavior:
|
||||
When a Landscape Canvas root entity is deleted, the corresponding graph automatically closes.
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Delete the automatically created entity
|
||||
4) Verify the open graph is closed
|
||||
:return: None
|
||||
"""
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
:return: None
|
||||
"""
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
def onEntityCreated(parameters):
|
||||
global newRootEntityId
|
||||
newRootEntityId = parameters[0]
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=128,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=128,
|
||||
use_terrain=False,
|
||||
)
|
||||
def onEntityCreated(parameters):
|
||||
global newRootEntityId
|
||||
newRootEntityId = parameters[0]
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
|
||||
if general.is_pane_visible('Landscape Canvas'):
|
||||
self.log('Landscape Canvas pane is open')
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Listen for entity creation notifications so we can store the top-level Entity created
|
||||
# when a new graph is created, and then delete it to test if the graph is closed
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Create a new graph in Landscape Canvas and verify
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
graphIsOpen = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
self.test_success = self.test_success and graphIsOpen
|
||||
if graphIsOpen:
|
||||
self.log("Graph registered with Landscape Canvas")
|
||||
# Listen for entity creation notifications so we can store the top-level Entity created
|
||||
# when a new graph is created, and then delete it to test if the graph is closed
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
|
||||
# Delete the top-level Entity created by the new graph
|
||||
editor.ToolsApplicationRequestBus(bus.Broadcast, 'DeleteEntityById', newRootEntityId)
|
||||
# Create a new graph in Landscape Canvas and verify
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
graphIsOpen = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_registered, graphIsOpen)
|
||||
|
||||
# We need to delay here because the closing of the graph due to Entity deletion
|
||||
# is actually queued in order to workaround an undo/redo issue
|
||||
# Alternatively, we could add a notifications bus for AssetEditorRequests
|
||||
# that could trigger when graphs are opened/closed and then do the check there
|
||||
general.idle_enable(True)
|
||||
general.idle_wait(1.0)
|
||||
# Delete the top-level Entity created by the new graph
|
||||
editor.ToolsApplicationRequestBus(bus.Broadcast, 'DeleteEntityById', newRootEntityId)
|
||||
|
||||
# Verify that the corresponding graph is no longer open
|
||||
graphIsClosed = not graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
self.test_success = self.test_success and graphIsClosed
|
||||
if graphIsClosed:
|
||||
self.log("The graph is no longer open after deleting the Entity")
|
||||
# We need to delay here because the closing of the graph due to Entity deletion
|
||||
# is actually queued in order to workaround an undo/redo issue
|
||||
# Alternatively, we could add a notifications bus for AssetEditorRequests
|
||||
# that could trigger when graphs are opened/closed and then do the check there
|
||||
general.idle_enable(True)
|
||||
general.idle_wait(1.0)
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
# Verify that the corresponding graph is no longer open
|
||||
graphIsClosed = not graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_closed, graphIsClosed)
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestGraphClosedOnEntityDelete()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GraphClosed_OnEntityDelete)
|
||||
|
||||
+63
-63
@@ -5,82 +5,82 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.paths
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
new_graph_created = (
|
||||
"Successfully created new graph",
|
||||
"Failed to create new graph"
|
||||
)
|
||||
graph_registered = (
|
||||
"Graph registered with Landscape Canvas",
|
||||
"Failed to register graph"
|
||||
)
|
||||
graph_closed = (
|
||||
"Graph closed on level change",
|
||||
"Graph is still open after level change"
|
||||
)
|
||||
|
||||
|
||||
class TestGraphClosedOnLevelChange(EditorTestHelper):
|
||||
def GraphClosed_OnLevelChange():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that Landscape Canvas graphs are auto-closed when the currently open level changes.
|
||||
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GraphClosedOnLevelChange", args=["level"])
|
||||
Expected Behavior:
|
||||
When a new level is loaded in the Editor, open Landscape Canvas graphs are automatically closed.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that Landscape Canvas graphs are auto-closed when the currently open level changes.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Open a different level
|
||||
4) Verify the open graph is closed
|
||||
|
||||
Expected Behavior:
|
||||
When a new level is loaded in the Editor, open Landscape Canvas graphs are automatically closed.
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Open a different level
|
||||
4) Verify the open graph is closed
|
||||
:return: None
|
||||
"""
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
:return: None
|
||||
"""
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=128,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=128,
|
||||
use_terrain=False,
|
||||
)
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
|
||||
if general.is_pane_visible('Landscape Canvas'):
|
||||
self.log('Landscape Canvas pane is open')
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId
|
||||
if newGraphId:
|
||||
self.log("New graph created")
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
graphIsOpen = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
self.test_success = self.test_success and graphIsOpen
|
||||
if graphIsOpen:
|
||||
self.log("Graph registered with Landscape Canvas")
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Open a different level, which should close any open Landscape Canvas graphs
|
||||
general.open_level_no_prompt('WhiteBox/EmptyLevel')
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
|
||||
|
||||
# Make sure the graph we created is now closed
|
||||
graphIsOpen = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
self.test_success = self.test_success and not graphIsOpen
|
||||
if not graphIsOpen:
|
||||
self.log("Graph is no longer open in Landscape Canvas")
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# Open a different level, which should close any open Landscape Canvas graphs
|
||||
general.open_level_no_prompt('WhiteBox/EmptyLevel')
|
||||
|
||||
# Make sure the graph we created is now closed
|
||||
graphIsOpen = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_closed, not graphIsOpen)
|
||||
|
||||
|
||||
test = TestGraphClosedOnLevelChange()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GraphClosed_OnLevelChange)
|
||||
|
||||
+72
-74
@@ -5,95 +5,93 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.paths
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
new_graph_created = (
|
||||
"Successfully created new graph",
|
||||
"Failed to create new graph"
|
||||
)
|
||||
graph_open = (
|
||||
"Graph is open in Landscape Canvas",
|
||||
"Graph is not open in Landscape Canvas"
|
||||
)
|
||||
tabbed_graph_closed = (
|
||||
"Tabbed graph closed independently",
|
||||
"Closing tabbed graph resulted in unexpected graphs closing"
|
||||
)
|
||||
|
||||
|
||||
class TestGraphClosedTabbedGraph(EditorTestHelper):
|
||||
def GraphClosed_TabbedGraphClosesIndependently():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that Landscape Canvas tabbed graphs can be independently closed.
|
||||
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GraphClosedTabbedGraph", args=["level"])
|
||||
Expected Behavior:
|
||||
Closing a tabbed graph only closes the appropriate graph.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that Landscape Canvas tabbed graphs can be independently closed.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Open Landscape Canvas and create several new graphs
|
||||
3) Close one of the open graphs
|
||||
4) Ensure the graph properly closed, and other open graphs remain open
|
||||
|
||||
Expected Behavior:
|
||||
Closing a tabbed graph only closes the appropriate graph.
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create several new graphs
|
||||
3) Close one of the open graphs
|
||||
4) Ensure the graph properly closed, and other open graphs remain open
|
||||
:return: None
|
||||
"""
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
:return: None
|
||||
"""
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=128,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=128,
|
||||
use_terrain=False,
|
||||
)
|
||||
editor_id = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
|
||||
if general.is_pane_visible('Landscape Canvas'):
|
||||
self.log('Landscape Canvas pane is open')
|
||||
def create_new_graph():
|
||||
new_graph_id = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editor_id)
|
||||
return new_graph_id
|
||||
|
||||
# Create 3 new graphs in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId
|
||||
if newGraphId:
|
||||
self.log("New graph created")
|
||||
def is_graph_open(graph_id):
|
||||
graph_open = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editor_id, graph_id)
|
||||
return graph_open
|
||||
|
||||
newGraphId2 = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId2
|
||||
if newGraphId2:
|
||||
self.log("2nd new graph created")
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
newGraphId3 = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId3
|
||||
if newGraphId3:
|
||||
self.log("3rd new graph created")
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Make sure the graphs we created are open in Landscape Canvas
|
||||
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
success2 = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId2)
|
||||
success3 = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId3)
|
||||
self.test_success = self.test_success and success and success2 and success3
|
||||
if success and success2 and success3:
|
||||
self.log("Graphs registered with Landscape Canvas")
|
||||
# Create 3 new graphs in Landscape Canvas and make sure the graphs we created are open in Landscape Canvas
|
||||
graph1 = create_new_graph()
|
||||
Report.result(Tests.new_graph_created, graph1 is not None)
|
||||
Report.result(Tests.graph_open, is_graph_open(graph1))
|
||||
|
||||
# Close a single graph and verify it was properly closed and other graphs remain open
|
||||
success4 = graph.AssetEditorRequestBus(bus.Event, 'CloseGraph', editorId, newGraphId2)
|
||||
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
success2 = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId2)
|
||||
success3 = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId3)
|
||||
self.test_success = self.test_success and success and success3 and success4 and not success2
|
||||
if success and success3 and success4 and not success2:
|
||||
self.log("Graph 2 was successfully closed")
|
||||
graph2 = create_new_graph()
|
||||
Report.result(Tests.new_graph_created, graph2 is not None)
|
||||
Report.result(Tests.graph_open, is_graph_open(graph2))
|
||||
|
||||
graph3 = create_new_graph()
|
||||
Report.result(Tests.new_graph_created, graph3 is not None)
|
||||
Report.result(Tests.graph_open, is_graph_open(graph3))
|
||||
|
||||
# Close a single graph and verify it was properly closed and other graphs remain open
|
||||
graph.AssetEditorRequestBus(bus.Event, 'CloseGraph', editor_id, graph2)
|
||||
Report.result(Tests.tabbed_graph_closed, not is_graph_open(graph2) and is_graph_open(graph1) and
|
||||
is_graph_open(graph3))
|
||||
|
||||
|
||||
test = TestGraphClosedTabbedGraph()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GraphClosed_TabbedGraphClosesIndependently)
|
||||
|
||||
+125
-129
@@ -5,155 +5,151 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.math as math
|
||||
import azlmbr.slice as slice
|
||||
import azlmbr.paths
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import automatedtesting_shared.landscape_canvas_utils as lc
|
||||
class Tests:
|
||||
slice_instantiated = (
|
||||
"Slice instantiated successfully",
|
||||
"Failed to instantiate slice"
|
||||
)
|
||||
existing_graph_opened = (
|
||||
"Opened existing graph from slice",
|
||||
"Failed to open existing graph"
|
||||
)
|
||||
node_removed = (
|
||||
"Rotation Modifier node was removed",
|
||||
"Failed to remove Rotation Modifier node"
|
||||
)
|
||||
component_removed = (
|
||||
"Rotation Modifier component was removed from entity",
|
||||
"Rotation Modifier component is still present on entity"
|
||||
)
|
||||
entity_deleted = (
|
||||
"BushSpawner entity was deleted",
|
||||
"Failed to delete BushSpawner entity"
|
||||
)
|
||||
entity_reference_updated = (
|
||||
"Gradient Entity Id reference was properly updated",
|
||||
"Gradient Entity Id reference was not updated properly"
|
||||
)
|
||||
|
||||
|
||||
class TestGraphUpdatesUpdateComponents(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="GraphUpdatesUpdateComponents", args=["level"])
|
||||
def GraphUpdates_UpdateComponent():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that components are properly updated as nodes are added/removed/updated.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that components are properly updated as nodes are added/removed/updated.
|
||||
Expected Behavior:
|
||||
Landscape Canvas node CRUD properly updates component entities.
|
||||
|
||||
Expected Behavior:
|
||||
Landscape Canvas node CRUD properly updates component entities.
|
||||
Test Steps:
|
||||
1. Open Level.
|
||||
2. Open the graph on LC_BushFlowerBlender.slice
|
||||
3. Find the Rotation Modifier node on the BushSpawner entity
|
||||
4. Delete the Rotation Modifier node
|
||||
5. Ensure the Vegetation Rotation Modifier component is removed from the BushSpawner entity
|
||||
6. Delete the Vegetation Layer Spawner node from the graph
|
||||
7. Ensure BushSpawner entity is deleted
|
||||
8. Change connection from second Rotation Modifier node to a different Gradient
|
||||
9. Ensure Gradient reference on component is updated
|
||||
|
||||
Test Steps:
|
||||
1. Open Level.
|
||||
2. Open the graph on LC_BushFlowerBlender.slice
|
||||
3. Find the Rotation Modifier node on the BushSpawner entity
|
||||
4. Delete the Rotation Modifier node
|
||||
5. Ensure the Vegetation Rotation Modifier component is removed from the BushSpawner entity
|
||||
6. Delete the Vegetation Layer Spawner node from the graph
|
||||
7. Ensure BushSpawner entity is deleted
|
||||
8. Change connection from second Rotation Modifier node to a different Gradient
|
||||
9. Ensure Gradient reference on component is updated
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
:return: None
|
||||
"""
|
||||
# Create a new empty level and instantiate LC_BushFlowerBlender.slice
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=128,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=128,
|
||||
use_terrain=False,
|
||||
)
|
||||
transform = math.Transform_CreateIdentity()
|
||||
position = math.Vector3(64.0, 64.0, 32.0)
|
||||
transform.invoke('SetPosition', position)
|
||||
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice")
|
||||
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(),
|
||||
False)
|
||||
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform)
|
||||
self.test_success = self.test_success and test_slice.IsValid()
|
||||
if test_slice.IsValid():
|
||||
self.log("Slice spawned!")
|
||||
import os
|
||||
|
||||
# Search for root entity to ensure slice is loaded
|
||||
search_filter = entity.SearchFilter()
|
||||
search_filter.names = ["LandscapeCanvas"]
|
||||
self.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0)
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.math as math
|
||||
import azlmbr.slice as slice
|
||||
|
||||
# Find needed entities in the loaded level
|
||||
slice_root_id = hydra.find_entity_by_name('LandscapeCanvas')
|
||||
bush_spawner_id = hydra.find_entity_by_name('BushSpawner')
|
||||
flower_spawner_id = hydra.find_entity_by_name('FlowerSpawner')
|
||||
inverted_perlin_noise_id = hydra.find_entity_by_name('Invert')
|
||||
import automatedtesting_shared.landscape_canvas_utils as lc
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Open Landscape Canvas and the existing graph
|
||||
general.open_pane('Landscape Canvas')
|
||||
open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id)
|
||||
self.test_success = self.test_success and open_graph_id.IsValid()
|
||||
if open_graph_id.IsValid():
|
||||
self.log('Graph opened')
|
||||
# Open a simple level and instantiate LC_BushFlowerBlender.slice
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
transform = math.Transform_CreateIdentity()
|
||||
position = math.Vector3(64.0, 64.0, 32.0)
|
||||
transform.invoke('SetPosition', position)
|
||||
test_slice_path = os.path.join("Slices", "LC_BushFlowerBlender.slice")
|
||||
test_slice_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", test_slice_path, math.Uuid(),
|
||||
False)
|
||||
test_slice = slice.SliceRequestBus(bus.Broadcast, 'InstantiateSliceFromAssetId', test_slice_id, transform)
|
||||
Report.critical_result(Tests.slice_instantiated, test_slice.IsValid())
|
||||
|
||||
# Find the Rotation Modifier node on the BushSpawner entity
|
||||
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', bush_spawner_id)
|
||||
# Search for root entity to ensure slice is loaded
|
||||
search_filter = entity.SearchFilter()
|
||||
search_filter.names = ["LandscapeCanvas"]
|
||||
helper.wait_for_condition(lambda: len(entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter)) > 0, 5.0)
|
||||
|
||||
# Remove the Rotation Modifier node
|
||||
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, rotation_modifier_node[0])
|
||||
# Find needed entities in the loaded level
|
||||
slice_root_id = hydra.find_entity_by_name('LandscapeCanvas')
|
||||
bush_spawner_id = hydra.find_entity_by_name('BushSpawner')
|
||||
flower_spawner_id = hydra.find_entity_by_name('FlowerSpawner')
|
||||
inverted_perlin_noise_id = hydra.find_entity_by_name('Invert')
|
||||
|
||||
# Verify node was removed
|
||||
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', bush_spawner_id)
|
||||
self.test_success = self.test_success and not rotation_modifier_node
|
||||
if not rotation_modifier_node:
|
||||
self.log('Rotation Modifier node was removed')
|
||||
else:
|
||||
self.log('Rotation Modifier node was not removed')
|
||||
# Open Landscape Canvas and the existing graph
|
||||
general.open_pane('Landscape Canvas')
|
||||
open_graph_id = landscapecanvas.LandscapeCanvasRequestBus(bus.Broadcast, 'OnGraphEntity', slice_root_id)
|
||||
Report.critical_result(Tests.existing_graph_opened, open_graph_id.IsValid())
|
||||
|
||||
# Verify the component was removed from the BushSpawner entity
|
||||
has_rotation_modifier = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', bush_spawner_id,
|
||||
hydra.get_component_type_id('Vegetation Rotation Modifier'))
|
||||
self.test_success = self.test_success and not has_rotation_modifier
|
||||
if not has_rotation_modifier:
|
||||
self.log('Rotation Modifier component was removed from entity')
|
||||
else:
|
||||
self.log('Rotation Modifier component is still present on entity')
|
||||
# Find the Rotation Modifier node on the BushSpawner entity
|
||||
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', bush_spawner_id)
|
||||
|
||||
# Find the Vegetation Layer Spawner node on the BushSpawner entity
|
||||
layer_spawner_node = lc.find_nodes_matching_entity_component('Vegetation Layer Spawner', bush_spawner_id)
|
||||
# Remove the Rotation Modifier node
|
||||
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, rotation_modifier_node[0])
|
||||
|
||||
# Remove the Vegetation Layer Spawner node and verify the corresponding entity is deleted
|
||||
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, layer_spawner_node[0])
|
||||
bush_spawner_id = hydra.find_entity_by_name('BushSpawner')
|
||||
self.test_success = self.test_success and not bush_spawner_id
|
||||
if not bush_spawner_id:
|
||||
self.log('BushSpawner entity was deleted')
|
||||
else:
|
||||
self.log('Failed to delete BushSpawner entity')
|
||||
# Verify node was removed
|
||||
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', bush_spawner_id)
|
||||
Report.result(Tests.node_removed, not rotation_modifier_node)
|
||||
|
||||
# Connect the FlowerSpawner's Rotation Modifier node to the Invert Gradient Modifier node
|
||||
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', flower_spawner_id)
|
||||
invert_node = lc.find_nodes_matching_entity_component('Invert Gradient Modifier', inverted_perlin_noise_id)
|
||||
# Verify the component was removed from the BushSpawner entity
|
||||
has_rotation_modifier = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', bush_spawner_id,
|
||||
hydra.get_component_type_id('Vegetation Rotation Modifier'))
|
||||
Report.result(Tests.component_removed, not has_rotation_modifier)
|
||||
|
||||
inbound_gradient_z_slot = graph.GraphModelSlotId('InboundGradientZ')
|
||||
outbound_gradient_slot = graph.GraphModelSlotId('OutboundGradient')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', open_graph_id, invert_node[0],
|
||||
outbound_gradient_slot, rotation_modifier_node[0], inbound_gradient_z_slot)
|
||||
# Find the Vegetation Layer Spawner node on the BushSpawner entity
|
||||
layer_spawner_node = lc.find_nodes_matching_entity_component('Vegetation Layer Spawner', bush_spawner_id)
|
||||
|
||||
general.idle_wait(1.0) # Add a small wait to ensure component property has time to update
|
||||
# Remove the Vegetation Layer Spawner node and verify the corresponding entity is deleted
|
||||
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', open_graph_id, layer_spawner_node[0])
|
||||
bush_spawner_id = hydra.find_entity_by_name('BushSpawner')
|
||||
Report.result(Tests.entity_deleted, not bush_spawner_id)
|
||||
|
||||
# Verify the Gradient Entity Id reference on the Rotation Modifier component was properly set
|
||||
rotation_type_id = hydra.get_component_type_id('Vegetation Rotation Modifier')
|
||||
rotation_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', flower_spawner_id,
|
||||
rotation_type_id)
|
||||
rotation_component = rotation_outcome.GetValue()
|
||||
gradient_reference = hydra.get_component_property_value(rotation_component,
|
||||
'Configuration|Rotation Z|Gradient|Gradient Entity Id')
|
||||
gradient_reference_success = gradient_reference == inverted_perlin_noise_id
|
||||
self.test_success = self.test_success and gradient_reference_success
|
||||
if gradient_reference_success:
|
||||
self.log('Gradient Entity Id reference was properly updated')
|
||||
else:
|
||||
self.log(f'Gradient Entity Id was not updated properly: Expected {inverted_perlin_noise_id.ToString()} -- Got '
|
||||
f'{gradient_reference.ToString()}.')
|
||||
# Connect the FlowerSpawner's Rotation Modifier node to the Invert Gradient Modifier node
|
||||
rotation_modifier_node = lc.find_nodes_matching_entity_component('Vegetation Rotation Modifier', flower_spawner_id)
|
||||
invert_node = lc.find_nodes_matching_entity_component('Invert Gradient Modifier', inverted_perlin_noise_id)
|
||||
|
||||
inbound_gradient_z_slot = graph.GraphModelSlotId('InboundGradientZ')
|
||||
outbound_gradient_slot = graph.GraphModelSlotId('OutboundGradient')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', open_graph_id, invert_node[0],
|
||||
outbound_gradient_slot, rotation_modifier_node[0], inbound_gradient_z_slot)
|
||||
|
||||
general.idle_wait(1.0) # Add a small wait to ensure component property has time to update
|
||||
|
||||
# Verify the Gradient Entity Id reference on the Rotation Modifier component was properly set
|
||||
rotation_type_id = hydra.get_component_type_id('Vegetation Rotation Modifier')
|
||||
rotation_outcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', flower_spawner_id,
|
||||
rotation_type_id)
|
||||
rotation_component = rotation_outcome.GetValue()
|
||||
gradient_reference = hydra.get_component_property_value(rotation_component,
|
||||
'Configuration|Rotation Z|Gradient|Gradient Entity Id')
|
||||
Report.result(Tests.entity_reference_updated, gradient_reference == inverted_perlin_noise_id)
|
||||
|
||||
|
||||
test = TestGraphUpdatesUpdateComponents()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(GraphUpdates_UpdateComponent)
|
||||
|
||||
-87
@@ -1,87 +0,0 @@
|
||||
"""
|
||||
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 os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.paths
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
|
||||
class TestLandscapeCanvasComponentAddedRemoved(EditorTestHelper):
|
||||
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="LandscapeCanvasComponentAddedRemoved", args=["level"])
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas component can be added to/removed from an entity.
|
||||
|
||||
Expected Behavior:
|
||||
Closing a tabbed graph only closes the appropriate graph.
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Create a new entity
|
||||
3) Add a Landscape Canvas component to the entity
|
||||
4) Remove the Landscape Canvas component from the entity
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=128,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=128,
|
||||
use_terrain=False,
|
||||
)
|
||||
|
||||
# Create an Entity at the root of the level
|
||||
newEntityId = editor.ToolsApplicationRequestBus(bus.Broadcast, 'CreateNewEntity', entity.EntityId())
|
||||
|
||||
# Find the component TypeId for our Landscape Canvas component
|
||||
landscape_canvas_type_id = hydra.get_component_type_id("Landscape Canvas")
|
||||
|
||||
# Add the Landscape Canvas Component to our Entity
|
||||
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', newEntityId, [landscape_canvas_type_id])
|
||||
components = componentOutcome.GetValue()
|
||||
landscapeCanvasComponent = components[0]
|
||||
|
||||
# Validate the Landscape Canvas Component exists
|
||||
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, landscape_canvas_type_id)
|
||||
self.test_success = self.test_success and hasComponent
|
||||
if hasComponent:
|
||||
self.log("Landscape Canvas Component added to Entity")
|
||||
|
||||
# Remove the Landscape Canvas Component
|
||||
editor.EditorComponentAPIBus(bus.Broadcast, 'RemoveComponents', [landscapeCanvasComponent])
|
||||
|
||||
# Validate the Landscape Canvas Component is no longer on our Entity
|
||||
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId, landscape_canvas_type_id)
|
||||
self.test_success = self.test_success and not hasComponent
|
||||
if not hasComponent:
|
||||
self.log("Landscape Canvas Component removed from Entity")
|
||||
|
||||
|
||||
test = TestLandscapeCanvasComponentAddedRemoved()
|
||||
test.run()
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
"""
|
||||
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 os
|
||||
import sys
|
||||
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.asset as asset
|
||||
import azlmbr.slice as slice
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
|
||||
class TestLandscapeCanvasSliceCreateInstantiate(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="LandscapeCanvas_SliceCreateInstantiate", args=["level"])
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
A slice containing the LandscapeCanvas component can be created/instantiated.
|
||||
|
||||
Expected Result:
|
||||
Slice is created/processed/instantiated successfully and free of errors/warnings.
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Create a new entity with a Landscape Canvas component
|
||||
3) Create a slice of the new entity
|
||||
4) Instantiate a new copy of the slice
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
def path_is_valid_asset(asset_path):
|
||||
asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False)
|
||||
return asset_id.invoke("IsValid")
|
||||
|
||||
# Create empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
|
||||
# Create entity with LandScape Canvas component
|
||||
position = math.Vector3(512.0, 512.0, 32.0)
|
||||
landscape_canvas = hydra.Entity("landscape_canvas_entity")
|
||||
landscape_canvas.create_entity(position, ["Landscape Canvas"])
|
||||
|
||||
# Create slice from the created entity
|
||||
slice_path = os.path.join("slices", "TestSlice.slice")
|
||||
slice.SliceRequestBus(bus.Broadcast, "CreateNewSlice", landscape_canvas.id, slice_path)
|
||||
|
||||
# Verify if slice is created
|
||||
self.wait_for_condition(lambda: path_is_valid_asset(slice_path), 5.0)
|
||||
self.log(f"Slice has been created successfully: {path_is_valid_asset(slice_path)}")
|
||||
|
||||
# Instantiate slice
|
||||
transform = math.Transform_CreateIdentity()
|
||||
asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", slice_path, math.Uuid(), False)
|
||||
test_slice = slice.SliceRequestBus(bus.Broadcast, "InstantiateSliceFromAssetId", asset_id, transform)
|
||||
self.wait_for_condition(lambda: test_slice.IsValid(), 3.0)
|
||||
self.log(f"Slice instantiated: {test_slice.IsValid()}")
|
||||
|
||||
|
||||
test = TestLandscapeCanvasSliceCreateInstantiate()
|
||||
test.run()
|
||||
+124
-121
@@ -5,157 +5,160 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
new_graph_created = (
|
||||
"Successfully created new graph",
|
||||
"Failed to create new graph"
|
||||
)
|
||||
graph_registered = (
|
||||
"Graph registered with Landscape Canvas",
|
||||
"Failed to register graph"
|
||||
)
|
||||
blender_first_layer_set = (
|
||||
"Spawner entity set as the first layer of the Vegetation Layer Blender component",
|
||||
"Unexpected entity set as the first layer of the Vegetation Layer Blender component"
|
||||
)
|
||||
blender_second_layer_set = (
|
||||
"Blocker entity set as the second layer of the Vegetation Layer Blender component",
|
||||
"Unexpected entity set as the second layer of the Vegetation Layer Blender component"
|
||||
)
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
newEntityId = None
|
||||
|
||||
|
||||
class TestLayerBlenderNodeConstruction(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="LayerBlenderNodeConstruction", args=["level"])
|
||||
def LayerBlender_NodeConstruction():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies a Layer Blender vegetation setup can be constructed through Landscape Canvas.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies a Layer Blender vegetation setup can be constructed through Landscape Canvas.
|
||||
Expected Behavior:
|
||||
Entities contain all required components and component references after creating nodes and setting connections
|
||||
on a Landscape Canvas graph.
|
||||
|
||||
Expected Behavior:
|
||||
Entities contain all required components and component references after creating nodes and setting connections
|
||||
on a Landscape Canvas graph.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Add all necessary nodes to the graph and set connections to form a Layer Blender setup
|
||||
4) Verify all components and component references were properly set during graph construction
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Add all necessary nodes to the graph and set connections to form a Layer Blender setup
|
||||
4) Verify all components and component references were properly set during graph construction
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
:return: None
|
||||
"""
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=1024,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=4096,
|
||||
use_terrain=False,
|
||||
)
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
|
||||
if general.is_pane_visible('Landscape Canvas'):
|
||||
self.log('Landscape Canvas pane is open')
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId
|
||||
if newGraphId:
|
||||
self.log("New graph created")
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
self.test_success = self.test_success and success
|
||||
if success:
|
||||
self.log("Graph registered with Landscape Canvas")
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Listen for entity creation notifications so we can verify the component EntityId
|
||||
# references are set correctly when connecting slots on the nodes
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
|
||||
|
||||
positionX = 10.0
|
||||
positionY = 10.0
|
||||
offsetX = 340.0
|
||||
offsetY = 100.0
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# Add a Vegetation Layer Spawner node to the graph
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
layerSpawnerNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, 'SpawnerAreaNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, layerSpawnerNode, math.Vector2(positionX, positionY))
|
||||
layerSpawnerEntityId = newEntityId
|
||||
# Listen for entity creation notifications so we can verify the component EntityId
|
||||
# references are set correctly when connecting slots on the nodes
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
|
||||
positionX += offsetX
|
||||
positionY += offsetY
|
||||
positionX = 10.0
|
||||
positionY = 10.0
|
||||
offsetX = 340.0
|
||||
offsetY = 100.0
|
||||
|
||||
# Add a Vegetation Layer Blocker node to the graph
|
||||
layerBlockerNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, 'BlockerAreaNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, layerBlockerNode, math.Vector2(positionX, positionY))
|
||||
layerBlockerEntityId = newEntityId
|
||||
# Add a Vegetation Layer Spawner node to the graph
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
layerSpawnerNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, 'SpawnerAreaNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, layerSpawnerNode, math.Vector2(positionX, positionY))
|
||||
layerSpawnerEntityId = newEntityId
|
||||
|
||||
positionX += offsetX
|
||||
positionY += offsetY
|
||||
positionX += offsetX
|
||||
positionY += offsetY
|
||||
|
||||
# Add a Vegetation Layer Blender node to the graph
|
||||
layerBlenderNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, 'AreaBlenderNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, layerBlenderNode, math.Vector2(positionX, positionY))
|
||||
layerBlenderNodeEntityId = newEntityId
|
||||
# Add a Vegetation Layer Blocker node to the graph
|
||||
layerBlockerNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, 'BlockerAreaNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, layerBlockerNode, math.Vector2(positionX, positionY))
|
||||
layerBlockerEntityId = newEntityId
|
||||
|
||||
positionX += offsetX
|
||||
positionY += offsetY
|
||||
positionX += offsetX
|
||||
positionY += offsetY
|
||||
|
||||
outboundAreaSlotId = graph.GraphModelSlotId('OutboundArea')
|
||||
inboundAreaSlotId = graph.GraphModelSlotId('InboundArea')
|
||||
inboundAreaSlotId2 = graph.GraphControllerRequestBus(bus.Event, 'ExtendSlot', newGraphId, layerBlenderNode,
|
||||
'InboundArea')
|
||||
# Add a Vegetation Layer Blender node to the graph
|
||||
layerBlenderNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, 'AreaBlenderNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, layerBlenderNode, math.Vector2(positionX, positionY))
|
||||
layerBlenderNodeEntityId = newEntityId
|
||||
|
||||
# Connect slots on our nodes to construct a Vegetation Layer Blender hierarchy
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, layerSpawnerNode, outboundAreaSlotId,
|
||||
layerBlenderNode, inboundAreaSlotId)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, layerBlockerNode, outboundAreaSlotId,
|
||||
layerBlenderNode, inboundAreaSlotId2)
|
||||
positionX += offsetX
|
||||
positionY += offsetY
|
||||
|
||||
# Delay to allow all the underlying component properties to be updated after the slot connections are made
|
||||
general.idle_wait(1.0)
|
||||
outboundAreaSlotId = graph.GraphModelSlotId('OutboundArea')
|
||||
inboundAreaSlotId = graph.GraphModelSlotId('InboundArea')
|
||||
inboundAreaSlotId2 = graph.GraphControllerRequestBus(bus.Event, 'ExtendSlot', newGraphId, layerBlenderNode,
|
||||
'InboundArea')
|
||||
|
||||
# Get component info
|
||||
layerBlenderTypeId = hydra.get_component_type_id("Vegetation Layer Blender")
|
||||
vegetationLayerBlenderOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType',
|
||||
layerBlenderNodeEntityId, layerBlenderTypeId)
|
||||
layerBlenderComponent = vegetationLayerBlenderOutcome.GetValue()
|
||||
# Connect slots on our nodes to construct a Vegetation Layer Blender hierarchy
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, layerSpawnerNode, outboundAreaSlotId,
|
||||
layerBlenderNode, inboundAreaSlotId)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, layerBlockerNode, outboundAreaSlotId,
|
||||
layerBlenderNode, inboundAreaSlotId2)
|
||||
|
||||
# Verify the Vegetation Areas properties on our Vegetation Layer Blender component have been set to our area EntityIds
|
||||
area1EntityId = hydra.get_component_property_value(layerBlenderComponent, 'Configuration|Vegetation Areas|[0]')
|
||||
self.test_success = self.test_success and area1EntityId and layerSpawnerEntityId.invoke("Equal", area1EntityId)
|
||||
if area1EntityId and layerSpawnerEntityId.invoke("Equal", area1EntityId):
|
||||
self.log("Vegetation Layer Blender component Vegetation Areas[0] property set to Vegetation Layer Spawner EntityId")
|
||||
# Delay to allow all the underlying component properties to be updated after the slot connections are made
|
||||
general.idle_wait(1.0)
|
||||
|
||||
area2EntityId = hydra.get_component_property_value(layerBlenderComponent, 'Configuration|Vegetation Areas|[1]')
|
||||
self.test_success = self.test_success and area2EntityId and layerBlockerEntityId.invoke("Equal", area2EntityId)
|
||||
if area2EntityId and layerBlockerEntityId.invoke("Equal", area2EntityId):
|
||||
self.log("Vegetation Layer Blender component Vegetation Areas[1] property set to Vegetation Layer Blocker EntityId")
|
||||
# Get component info
|
||||
layerBlenderTypeId = hydra.get_component_type_id("Vegetation Layer Blender")
|
||||
vegetationLayerBlenderOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType',
|
||||
layerBlenderNodeEntityId, layerBlenderTypeId)
|
||||
layerBlenderComponent = vegetationLayerBlenderOutcome.GetValue()
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
# Verify the Vegetation Areas properties on our Vegetation Layer Blender component have been set to our area EntityIds
|
||||
area1EntityId = hydra.get_component_property_value(layerBlenderComponent, 'Configuration|Vegetation Areas|[0]')
|
||||
Report.result(Tests.blender_first_layer_set, area1EntityId and layerSpawnerEntityId.invoke("Equal", area1EntityId))
|
||||
|
||||
area2EntityId = hydra.get_component_property_value(layerBlenderComponent, 'Configuration|Vegetation Areas|[1]')
|
||||
Report.result(Tests.blender_second_layer_set, area2EntityId and layerBlockerEntityId.invoke("Equal", area2EntityId))
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestLayerBlenderNodeConstruction()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(LayerBlender_NodeConstruction)
|
||||
|
||||
+138
-132
@@ -5,164 +5,170 @@ For complete copyright and license terms please see the LICENSE at the root of t
|
||||
SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
new_graph_created = (
|
||||
"Successfully created new graph",
|
||||
"Failed to create new graph"
|
||||
)
|
||||
graph_registered = (
|
||||
"Graph registered with Landscape Canvas",
|
||||
"Failed to register graph"
|
||||
)
|
||||
component_added = (
|
||||
"Expected component is present on entity",
|
||||
"Expected component was not found on entity"
|
||||
)
|
||||
component_removed = (
|
||||
"Expected component was removed from entity",
|
||||
"Component is unexpectedly still present on entity"
|
||||
)
|
||||
|
||||
sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests'))
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.editor_test_helper import EditorTestHelper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
newEntityId = None
|
||||
|
||||
|
||||
class TestLayerExtenderNodeComponentEntitySync(EditorTestHelper):
|
||||
def LayerExtenderNodes_ComponentEntitySync():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that all wrapped nodes can be successfully added to/removed from parent nodes.
|
||||
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="LayerExtenderNodeComponentEntitySync", args=["level"])
|
||||
Expected Behavior:
|
||||
All wrapped extender nodes can be added to/removed from appropriate parent nodes.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that all wrapped nodes can be successfully added to/removed from parent nodes.
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Add Area Blender and Layer Spawner nodes to the graph, and add/remove each extender node to/from each
|
||||
|
||||
Expected Behavior:
|
||||
All wrapped extender nodes can be added to/removed from appropriate parent nodes.
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Add Area Blender and Layer Spawner nodes to the graph, and add/remove each extender node to/from each
|
||||
:return: None
|
||||
"""
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.landscapecanvas as landscapecanvas
|
||||
import azlmbr.legacy.general as general
|
||||
import azlmbr.math as math
|
||||
import azlmbr.paths
|
||||
|
||||
:return: None
|
||||
"""
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
# Create a new empty level
|
||||
self.test_success = self.create_level(
|
||||
self.args["level"],
|
||||
heightmap_resolution=128,
|
||||
heightmap_meters_per_pixel=1,
|
||||
terrain_texture_resolution=128,
|
||||
use_terrain=False,
|
||||
)
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
self.test_success = self.test_success and general.is_pane_visible('Landscape Canvas')
|
||||
if general.is_pane_visible('Landscape Canvas'):
|
||||
self.log('Landscape Canvas pane is open')
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
self.test_success = self.test_success and newGraphId
|
||||
if newGraphId:
|
||||
self.log("New graph created")
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
success = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
self.test_success = self.test_success and success
|
||||
if success:
|
||||
self.log("Graph registered with Landscape Canvas")
|
||||
# Create a new graph in Landscape Canvas
|
||||
newGraphId = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
Report.critical_result(Tests.new_graph_created, newGraphId is not None)
|
||||
|
||||
# Listen for entity creation notifications so we can check if the
|
||||
# proper components are added when we add nodes
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# Extender mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the layer Entity for that wrapped node
|
||||
extenders = {
|
||||
'AltitudeFilterNode': 'Vegetation Altitude Filter',
|
||||
'DistanceBetweenFilterNode': 'Vegetation Distance Between Filter',
|
||||
'DistributionFilterNode': 'Vegetation Distribution Filter',
|
||||
'ShapeIntersectionFilterNode': 'Vegetation Shape Intersection Filter',
|
||||
'SlopeFilterNode': 'Vegetation Slope Filter',
|
||||
'SurfaceMaskDepthFilterNode': 'Vegetation Surface Mask Depth Filter',
|
||||
'SurfaceMaskFilterNode': 'Vegetation Surface Mask Filter',
|
||||
'PositionModifierNode': 'Vegetation Position Modifier',
|
||||
'RotationModifierNode': 'Vegetation Rotation Modifier',
|
||||
'ScaleModifierNode': 'Vegetation Scale Modifier',
|
||||
'SlopeAlignmentModifierNode': 'Vegetation Slope Alignment Modifier',
|
||||
'AssetWeightSelectorNode': 'Vegetation Asset Weight Selector'
|
||||
}
|
||||
# Listen for entity creation notifications so we can check if the
|
||||
# proper components are added when we add nodes
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
|
||||
# Retrieve a mapping of the TypeIds for all the components
|
||||
# we will be checking for
|
||||
componentNames = []
|
||||
for name in extenders:
|
||||
componentNames.append(extenders[name])
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
# Extender mapping with the key being the node name and the value is the
|
||||
# expected Component that should be added to the layer Entity for that wrapped node
|
||||
extenders = {
|
||||
'AltitudeFilterNode': 'Vegetation Altitude Filter',
|
||||
'DistanceBetweenFilterNode': 'Vegetation Distance Between Filter',
|
||||
'DistributionFilterNode': 'Vegetation Distribution Filter',
|
||||
'ShapeIntersectionFilterNode': 'Vegetation Shape Intersection Filter',
|
||||
'SlopeFilterNode': 'Vegetation Slope Filter',
|
||||
'SurfaceMaskDepthFilterNode': 'Vegetation Surface Mask Depth Filter',
|
||||
'SurfaceMaskFilterNode': 'Vegetation Surface Mask Filter',
|
||||
'PositionModifierNode': 'Vegetation Position Modifier',
|
||||
'RotationModifierNode': 'Vegetation Rotation Modifier',
|
||||
'ScaleModifierNode': 'Vegetation Scale Modifier',
|
||||
'SlopeAlignmentModifierNode': 'Vegetation Slope Alignment Modifier',
|
||||
'AssetWeightSelectorNode': 'Vegetation Asset Weight Selector'
|
||||
}
|
||||
|
||||
areas = [
|
||||
'AreaBlenderNode',
|
||||
'SpawnerAreaNode'
|
||||
]
|
||||
# Retrieve a mapping of the TypeIds for all the components
|
||||
# we will be checking for
|
||||
componentNames = []
|
||||
for name in extenders:
|
||||
componentNames.append(extenders[name])
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
|
||||
# Add/remove all our supported extender nodes to the Layer Areas and check if the appropriate
|
||||
# Components are added/removed to the wrapper node's Entity
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for areaName in areas:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
areaNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, areaName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, areaNode, nodePosition)
|
||||
areas = [
|
||||
'AreaBlenderNode',
|
||||
'SpawnerAreaNode'
|
||||
]
|
||||
|
||||
success = True
|
||||
for extenderName in extenders:
|
||||
# Add the wrapped node for the extender
|
||||
extenderNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast,
|
||||
'CreateNodeForTypeName', newGraph,
|
||||
extenderName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, extenderNode, nodePosition)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'WrapNode', newGraphId, areaNode, extenderNode)
|
||||
# Add/remove all our supported extender nodes to the Layer Areas and check if the appropriate
|
||||
# Components are added/removed to the wrapper node's Entity
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for areaName in areas:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
areaNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, areaName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, areaNode, nodePosition)
|
||||
|
||||
# Check that the appropriate Component was added when the extender node was added
|
||||
extenderComponent = extenders[extenderName]
|
||||
componentTypeId = componentTypeIds[extenderComponent]
|
||||
success = success and editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
|
||||
success = True
|
||||
for extenderName in extenders:
|
||||
# Add the wrapped node for the extender
|
||||
extenderNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast,
|
||||
'CreateNodeForTypeName', newGraph,
|
||||
extenderName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, extenderNode, nodePosition)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'WrapNode', newGraphId, areaNode, extenderNode)
|
||||
|
||||
# Check that the appropriate Component was added when the extender node was added
|
||||
extenderComponent = extenders[extenderName]
|
||||
componentTypeId = componentTypeIds[extenderComponent]
|
||||
success = success and editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
|
||||
componentTypeId)
|
||||
Report.info(f"Component: {extenderComponent}")
|
||||
Report.result(Tests.component_added, success)
|
||||
if not success:
|
||||
break
|
||||
|
||||
# Check that the appropriate Component was removed when the extender node was removed
|
||||
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, extenderNode)
|
||||
success = success and not editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
|
||||
componentTypeId)
|
||||
self.test_success = self.test_success and success
|
||||
if not success:
|
||||
self.log("{node} failed to add {component} Component".format(node=areaName,
|
||||
component=extenderComponent))
|
||||
break
|
||||
Report.info(f"Component: {extenderComponent}")
|
||||
Report.result(Tests.component_removed, success)
|
||||
if not success:
|
||||
break
|
||||
|
||||
# Check that the appropriate Component was removed when the extender node was removed
|
||||
graph.GraphControllerRequestBus(bus.Event, 'RemoveNode', newGraphId, extenderNode)
|
||||
success = success and not editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
|
||||
componentTypeId)
|
||||
self.test_success = self.test_success and success
|
||||
if not success:
|
||||
self.log("{node} failed to remove {component} Component".format(node=areaName,
|
||||
component=extenderComponent))
|
||||
break
|
||||
if success:
|
||||
Report.info(f"{areaName} successfully added and removed all filters/modifiers/selectors")
|
||||
|
||||
if success:
|
||||
self.log("{node} successfully added and removed all filters/modifiers/selectors".format(node=areaName))
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestLayerExtenderNodeComponentEntitySync()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(LayerExtenderNodes_ComponentEntitySync)
|
||||
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
|
||||
class Tests:
|
||||
lc_tool_opened = (
|
||||
"Landscape Canvas tool opened",
|
||||
"Failed to open Landscape Canvas tool"
|
||||
)
|
||||
new_graph_created = (
|
||||
"Successfully created new graph",
|
||||
"Failed to create new graph"
|
||||
)
|
||||
graph_registered = (
|
||||
"Graph registered with Landscape Canvas",
|
||||
"Failed to register graph"
|
||||
)
|
||||
lc_component_added = (
|
||||
"Root entity created with the Landscape Canvas component",
|
||||
"Landscape Canvas component was not found on the root entity"
|
||||
)
|
||||
lc_tool_closed = (
|
||||
"Landscape Canvas tool closed",
|
||||
"Failed to close Landscape Canvas tool"
|
||||
)
|
||||
|
||||
|
||||
new_root_entity_id = None
|
||||
|
||||
|
||||
def NewGraph_CreatedSuccessfully():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that new graphs can be created in Landscape Canvas.
|
||||
|
||||
Expected Behavior:
|
||||
New graphs can be created, and proper entity is created to hold graph data with a Landscape Canvas component.
|
||||
|
||||
Test Steps:
|
||||
1) Open a simple level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Ensures the root entity created contains a Landscape Canvas component
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.editor as editor
|
||||
import azlmbr.editor.graph as graph
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
def on_entity_created(parameters):
|
||||
global new_root_entity_id
|
||||
new_root_entity_id = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# with the new graph has our Landscape Canvas component automatically added
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback("OnEditorEntityCreated", on_entity_created)
|
||||
|
||||
# Open Landscape Canvas tool and verify
|
||||
general.open_pane('Landscape Canvas')
|
||||
Report.critical_result(Tests.lc_tool_opened, general.is_pane_visible('Landscape Canvas'))
|
||||
|
||||
# Create a new graph in Landscape Canvas
|
||||
new_graph_id = graph.AssetEditorRequestBus(bus.Event, 'CreateNewGraph', editorId)
|
||||
Report.critical_result(Tests.new_graph_created, new_graph_id is not None)
|
||||
|
||||
# Make sure the graph we created is in Landscape Canvas
|
||||
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, new_graph_id)
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# Check if the entity created when we create a new graph has the
|
||||
# Landscape Canvas component already added to it
|
||||
landscape_canvas_type_id = hydra.get_component_type_id("Landscape Canvas")
|
||||
success = editor.EditorComponentAPIBus(bus.Broadcast, "HasComponentOfType", new_root_entity_id,
|
||||
landscape_canvas_type_id)
|
||||
Report.result(Tests.lc_component_added, success)
|
||||
|
||||
# Close Landscape Canvas tool and verify
|
||||
general.close_pane("Landscape Canvas")
|
||||
Report.result(Tests.lc_tool_closed, not general.is_pane_visible("Landscape Canvas"))
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(NewGraph_CreatedSuccessfully)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user