Merge branch 'development' into cmake/linux_fix_warn_unused
Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>
This commit is contained in:
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -130,8 +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"
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/test_LandscapeCanvas_Main.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -144,8 +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"
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas/test_LandscapeCanvas_Periodic.py
|
||||
RUNTIME_DEPENDENCIES
|
||||
AZ::AssetProcessor
|
||||
Legacy::Editor
|
||||
@@ -159,7 +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
|
||||
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)
|
||||
+108
-105
@@ -5,133 +5,136 @@ 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 TestShapeNodeEntityCreate(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="ShapeNodeEntityCreate", args=["level"])
|
||||
def ShapeNodes_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 shape nodes to graph area.
|
||||
|
||||
Expected Behavior:
|
||||
New entities are created when dragging shape 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 shape 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 shape 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
|
||||
|
||||
# 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")
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# Listen for entity creation notifications so we can check if the entity created
|
||||
# from adding shape nodes has the appropriate Shape 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'))
|
||||
|
||||
# Shape 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
|
||||
shapes = {
|
||||
'BoxShapeNode': 'Box Shape',
|
||||
'CapsuleShapeNode': 'Capsule Shape',
|
||||
'CompoundShapeNode': 'Compound Shape',
|
||||
'CylinderShapeNode': 'Cylinder Shape',
|
||||
'PolygonPrismShapeNode': 'Polygon Prism Shape',
|
||||
'SphereShapeNode': 'Sphere Shape',
|
||||
'TubeShapeNode': 'Tube Shape',
|
||||
'DiskShapeNode': 'Disk Shape'
|
||||
}
|
||||
# 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 shapes:
|
||||
componentNames.append(shapes[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 shapes 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 shapes:
|
||||
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 shape nodes has the appropriate Shape Component
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
|
||||
shapeComponent = shapes[nodeName]
|
||||
componentTypeId = componentTypeIds[shapeComponent]
|
||||
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=shapeComponent))
|
||||
# Shape 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
|
||||
shapes = {
|
||||
'BoxShapeNode': 'Box Shape',
|
||||
'CapsuleShapeNode': 'Capsule Shape',
|
||||
'CompoundShapeNode': 'Compound Shape',
|
||||
'CylinderShapeNode': 'Cylinder Shape',
|
||||
'PolygonPrismShapeNode': 'Polygon Prism Shape',
|
||||
'SphereShapeNode': 'Sphere Shape',
|
||||
'TubeShapeNode': 'Tube Shape',
|
||||
'DiskShapeNode': 'Disk Shape'
|
||||
}
|
||||
|
||||
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 shapes:
|
||||
componentNames.append(shapes[name])
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
# Create nodes for all the shapes 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 shapes:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
|
||||
shapeComponent = shapes[nodeName]
|
||||
componentTypeId = componentTypeIds[shapeComponent]
|
||||
hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', newEntityId,
|
||||
componentTypeId)
|
||||
Report.info(f"Node: {nodeName} | Component: {shapeComponent}")
|
||||
Report.result(Tests.component_added, hasComponent)
|
||||
|
||||
x += 40.0
|
||||
y += 40.0
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestShapeNodeEntityCreate()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(ShapeNodes_EntityCreatedOnNodeAdd)
|
||||
|
||||
+109
-107
@@ -5,127 +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 TestShapeNodeEntityDelete(EditorTestHelper):
|
||||
def ShapeNodes_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="ShapeNodeEntityDelete", args=["level"])
|
||||
Expected Behavior:
|
||||
Entities are removed when shape 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 shape 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 shape 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 shape 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]
|
||||
|
||||
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,
|
||||
)
|
||||
|
||||
# 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')
|
||||
|
||||
# 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")
|
||||
|
||||
# Listen for entity creation/deletion notifications so we can verify the
|
||||
# Entity created when adding a new also gets deleted when the node is deleted
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
|
||||
|
||||
# All of the shape nodes that we support
|
||||
shapes = [
|
||||
'BoxShapeNode',
|
||||
'CapsuleShapeNode',
|
||||
'CompoundShapeNode',
|
||||
'CylinderShapeNode',
|
||||
'PolygonPrismShapeNode',
|
||||
'SphereShapeNode',
|
||||
'TubeShapeNode',
|
||||
'DiskShapeNode'
|
||||
]
|
||||
|
||||
# Create nodes for all the shapes we support and check if the Entity is created
|
||||
# and then deleted when the node is removed
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in shapes:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
|
||||
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
|
||||
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))
|
||||
|
||||
# Stop listening for entity creation/deletion notifications
|
||||
handler.disconnect()
|
||||
def onEntityCreated(parameters):
|
||||
global createdEntityId
|
||||
createdEntityId = parameters[0]
|
||||
|
||||
def onEntityDeleted(parameters):
|
||||
global deletedEntityId
|
||||
deletedEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# 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
|
||||
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 in Landscape Canvas
|
||||
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# Listen for entity creation/deletion notifications so we can verify the
|
||||
# Entity created when adding a new also gets deleted when the node is deleted
|
||||
handler = editor.EditorEntityContextNotificationBusHandler()
|
||||
handler.connect()
|
||||
handler.add_callback('OnEditorEntityCreated', onEntityCreated)
|
||||
handler.add_callback('OnEditorEntityDeleted', onEntityDeleted)
|
||||
|
||||
# All of the shape nodes that we support
|
||||
shapes = [
|
||||
'BoxShapeNode',
|
||||
'CapsuleShapeNode',
|
||||
'CompoundShapeNode',
|
||||
'CylinderShapeNode',
|
||||
'PolygonPrismShapeNode',
|
||||
'SphereShapeNode',
|
||||
'TubeShapeNode',
|
||||
'DiskShapeNode'
|
||||
]
|
||||
|
||||
# Create nodes for all the shapes we support and check if the Entity is created
|
||||
# and then deleted when the node is removed
|
||||
newGraph = graph.GraphManagerRequestBus(bus.Broadcast, 'GetGraph', newGraphId)
|
||||
x = 10.0
|
||||
y = 10.0
|
||||
for nodeName in shapes:
|
||||
nodePosition = math.Vector2(x, y)
|
||||
node = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName', newGraph, nodeName)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, node, nodePosition)
|
||||
|
||||
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/deletion notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
test = TestShapeNodeEntityDelete()
|
||||
test.run()
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(ShapeNodes_EntityRemovedOnNodeDelete)
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
"""
|
||||
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:
|
||||
slice_created = (
|
||||
"Slice created successfully",
|
||||
"Failed to create slice"
|
||||
)
|
||||
slice_instantiated = (
|
||||
"Slice instantiated successfully",
|
||||
"Failed to instantiate slice"
|
||||
)
|
||||
|
||||
|
||||
def Slice_CreateInstantiate():
|
||||
"""
|
||||
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) Open a simple 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
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import azlmbr.math as math
|
||||
import azlmbr.bus as bus
|
||||
import azlmbr.asset as asset
|
||||
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
|
||||
|
||||
def path_is_valid_asset(asset_path):
|
||||
asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False)
|
||||
return asset_id.invoke("IsValid")
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# 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
|
||||
helper.wait_for_condition(lambda: path_is_valid_asset(slice_path), 5.0)
|
||||
Report.result(Tests.slice_created, 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)
|
||||
helper.wait_for_condition(lambda: test_slice.IsValid(), 5.0)
|
||||
Report.result(Tests.slice_instantiated, test_slice.IsValid())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(Slice_CreateInstantiate)
|
||||
+200
-193
@@ -5,210 +5,217 @@ 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"
|
||||
)
|
||||
preview_entity_set = (
|
||||
"Random Noise Gradient component Preview Entity property set to Box Shape EntityId",
|
||||
"Unexpected entity set in Random Noise Gradient Preview Entity property"
|
||||
)
|
||||
dither_inbound_gradient_set = (
|
||||
"Dither Gradient Modifier component Inbound Gradient property set to Random Noise Gradient EntityId",
|
||||
"Unexpected entity set in Dither Gradient's Inbound Gradient property"
|
||||
)
|
||||
mixer_inbound_gradient_set = (
|
||||
"Gradient Mixer component Inbound Gradient extendable property set to Dither Gradient Modifier EntityId",
|
||||
"Unexpected entity set in Gradient Mixer's Inbound Gradient property"
|
||||
)
|
||||
|
||||
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 TestSlotConnectionsUpdateComponents(EditorTestHelper):
|
||||
def __init__(self):
|
||||
EditorTestHelper.__init__(self, log_prefix="SlotConnectionsUpdateComponents", args=["level"])
|
||||
def SlotConnections_UpdateComponentReferences():
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas slot connections properly update component references.
|
||||
|
||||
def run_test(self):
|
||||
"""
|
||||
Summary:
|
||||
This test verifies that the Landscape Canvas slot connections properly update component references.
|
||||
Expected Behavior:
|
||||
A reference created through slot connections in Landscape Canvas is reflected in the Entity Inspector.
|
||||
|
||||
Expected Behavior:
|
||||
A reference created through slot connections in Landscape Canvas is reflected in the Entity Inspector.
|
||||
Test Steps:
|
||||
1) Open an existing level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Several nodes are added to a graph, and connections are set between the nodes
|
||||
4) Component references are verified via Entity Inspector
|
||||
|
||||
Test Steps:
|
||||
1) Create a new level
|
||||
2) Open Landscape Canvas and create a new graph
|
||||
3) Several nodes are added to a graph, and connections are set between the nodes
|
||||
4) Component references are verified via Entity Inspector
|
||||
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
|
||||
"""
|
||||
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
|
||||
|
||||
# Retrieve the proper component TypeIds per component name
|
||||
componentNames = [
|
||||
'Random Noise Gradient',
|
||||
'Dither Gradient Modifier',
|
||||
'Gradient Mixer'
|
||||
]
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
|
||||
# Helper method for retrieving an EntityId from a specific property on a component
|
||||
def getEntityIdFromComponentProperty(targetEntityId, componentTypeName, propertyPath):
|
||||
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', targetEntityId,
|
||||
componentTypeIds[componentTypeName])
|
||||
if not componentOutcome.IsSuccess():
|
||||
return None
|
||||
|
||||
component = componentOutcome.GetValue()
|
||||
propertyOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component,
|
||||
propertyPath)
|
||||
if not propertyOutcome.IsSuccess():
|
||||
return None
|
||||
|
||||
return propertyOutcome.GetValue()
|
||||
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# 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,
|
||||
)
|
||||
|
||||
# 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')
|
||||
|
||||
# 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")
|
||||
|
||||
# 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 = 10.0
|
||||
positionY = 10.0
|
||||
offsetX = 340.0
|
||||
offsetY = 100.0
|
||||
|
||||
# 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
|
||||
|
||||
# Add a random noise gradient node to the graph
|
||||
randomNoiseNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, 'RandomNoiseGradientNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, randomNoiseNode, math.Vector2(positionX,
|
||||
positionY))
|
||||
randomNoiseEntityId = newEntityId
|
||||
|
||||
positionX += offsetX
|
||||
positionY += offsetY
|
||||
|
||||
# Add a dither gradient modifier node to the graph
|
||||
ditherNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, 'DitherGradientModifierNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, ditherNode, math.Vector2(positionX,
|
||||
positionY))
|
||||
ditherEntityId = newEntityId
|
||||
|
||||
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
|
||||
|
||||
boundsSlotId = graph.GraphModelSlotId('Bounds')
|
||||
previewBoundsSlotId = graph.GraphModelSlotId('PreviewBounds')
|
||||
inboundGradientSlotId = graph.GraphModelSlotId('InboundGradient')
|
||||
outboundGradientSlotId = graph.GraphModelSlotId('OutboundGradient')
|
||||
|
||||
# Connect slots on our nodes to test all slot types like so:
|
||||
# Shape -> Gradient -> Gradient Modifier -> Gradient Mixer
|
||||
#
|
||||
# Which tests the following slot types:
|
||||
# * Shape -> Preview Bounds
|
||||
# * Gradient Output -> Gradient Modifier
|
||||
# * Gradient Output -> Gradient Mixer (extendable slots)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
|
||||
randomNoiseNode, previewBoundsSlotId)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, randomNoiseNode,
|
||||
outboundGradientSlotId, ditherNode, inboundGradientSlotId)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, ditherNode,
|
||||
outboundGradientSlotId, gradientMixerNode, inboundGradientSlotId)
|
||||
|
||||
# Delay to allow all the underlying component properties to be updated after the slot connections are made
|
||||
general.idle_wait(1.0)
|
||||
|
||||
# Verify the Preview EntityId property on our Random Noise Gradient component has been set to our Box Shape's
|
||||
# EntityId
|
||||
previewEntityId = getEntityIdFromComponentProperty(randomNoiseEntityId, 'Random Noise Gradient',
|
||||
'Preview Settings|Pin Preview to Shape')
|
||||
random_gradient_success = previewEntityId and boxShapeEntityId.invoke("Equal", previewEntityId)
|
||||
self.test_success = self.test_success and random_gradient_success
|
||||
if random_gradient_success:
|
||||
self.log("Random Noise Gradient component Preview Entity property set to Box Shape EntityId")
|
||||
|
||||
# Verify the Inbound Gradient EntityId property on our Dither Gradient Modifier component has been set to our
|
||||
# Random Noise Gradient's EntityId
|
||||
inboundGradientEntityId = getEntityIdFromComponentProperty(ditherEntityId, 'Dither Gradient Modifier',
|
||||
'Configuration|Gradient|Gradient Entity Id')
|
||||
dither_gradient_success = inboundGradientEntityId and randomNoiseEntityId.invoke("Equal",
|
||||
inboundGradientEntityId)
|
||||
self.test_success = self.test_success and dither_gradient_success
|
||||
if dither_gradient_success:
|
||||
self.log("Dither Gradient Modifier component Inbound Gradient property set to Random Noise Gradient "
|
||||
"EntityId")
|
||||
|
||||
# Verify the Inbound Gradient Mixer EntityId property on our Gradient Mixer component has been set to our
|
||||
# Dither Gradient Modifier's EntityId
|
||||
inboundGradientMixerEntityId = getEntityIdFromComponentProperty(gradientMixerEntityId, 'Gradient Mixer',
|
||||
'Configuration|Layers|[0]|Gradient|Gradient Entity Id')
|
||||
gradient_mixer_success = inboundGradientMixerEntityId and ditherEntityId.invoke("Equal",
|
||||
inboundGradientMixerEntityId)
|
||||
self.test_success = self.test_success and gradient_mixer_success
|
||||
if gradient_mixer_success:
|
||||
self.log("Gradient Mixer component Inbound Gradient extendable property set to Dither Gradient Modifier "
|
||||
"EntityId")
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
editorId = azlmbr.globals.property.LANDSCAPE_CANVAS_EDITOR_ID
|
||||
|
||||
|
||||
test = TestSlotConnectionsUpdateComponents()
|
||||
test.run()
|
||||
# Retrieve the proper component TypeIds per component name
|
||||
componentNames = [
|
||||
'Random Noise Gradient',
|
||||
'Dither Gradient Modifier',
|
||||
'Gradient Mixer'
|
||||
]
|
||||
componentTypeIds = hydra.get_component_type_id_map(componentNames)
|
||||
|
||||
# Helper method for retrieving an EntityId from a specific property on a component
|
||||
def getEntityIdFromComponentProperty(targetEntityId, componentTypeName, propertyPath):
|
||||
componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentOfType', targetEntityId,
|
||||
componentTypeIds[componentTypeName])
|
||||
|
||||
if not componentOutcome.IsSuccess():
|
||||
return None
|
||||
|
||||
component = componentOutcome.GetValue()
|
||||
propertyOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'GetComponentProperty', component,
|
||||
propertyPath)
|
||||
if not propertyOutcome.IsSuccess():
|
||||
return None
|
||||
|
||||
return propertyOutcome.GetValue()
|
||||
|
||||
def onEntityCreated(parameters):
|
||||
global newEntityId
|
||||
newEntityId = parameters[0]
|
||||
|
||||
# Open an existing simple level
|
||||
helper.init_idle()
|
||||
helper.open_level("Physics", "Base")
|
||||
|
||||
# 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
|
||||
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 in Landscape Canvas
|
||||
graph_registered = graph.AssetEditorRequestBus(bus.Event, 'ContainsGraph', editorId, newGraphId)
|
||||
Report.result(Tests.graph_registered, graph_registered)
|
||||
|
||||
# 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 = 10.0
|
||||
positionY = 10.0
|
||||
offsetX = 340.0
|
||||
offsetY = 100.0
|
||||
|
||||
# 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
|
||||
|
||||
# Add a random noise gradient node to the graph
|
||||
randomNoiseNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, 'RandomNoiseGradientNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, randomNoiseNode, math.Vector2(positionX,
|
||||
positionY))
|
||||
randomNoiseEntityId = newEntityId
|
||||
|
||||
positionX += offsetX
|
||||
positionY += offsetY
|
||||
|
||||
# Add a dither gradient modifier node to the graph
|
||||
ditherNode = landscapecanvas.LandscapeCanvasNodeFactoryRequestBus(bus.Broadcast, 'CreateNodeForTypeName',
|
||||
newGraph, 'DitherGradientModifierNode')
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddNode', newGraphId, ditherNode, math.Vector2(positionX,
|
||||
positionY))
|
||||
ditherEntityId = newEntityId
|
||||
|
||||
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
|
||||
|
||||
boundsSlotId = graph.GraphModelSlotId('Bounds')
|
||||
previewBoundsSlotId = graph.GraphModelSlotId('PreviewBounds')
|
||||
inboundGradientSlotId = graph.GraphModelSlotId('InboundGradient')
|
||||
outboundGradientSlotId = graph.GraphModelSlotId('OutboundGradient')
|
||||
|
||||
# Connect slots on our nodes to test all slot types like so:
|
||||
# Shape -> Gradient -> Gradient Modifier -> Gradient Mixer
|
||||
#
|
||||
# Which tests the following slot types:
|
||||
# * Shape -> Preview Bounds
|
||||
# * Gradient Output -> Gradient Modifier
|
||||
# * Gradient Output -> Gradient Mixer (extendable slots)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, boxShapeNode, boundsSlotId,
|
||||
randomNoiseNode, previewBoundsSlotId)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, randomNoiseNode,
|
||||
outboundGradientSlotId, ditherNode, inboundGradientSlotId)
|
||||
graph.GraphControllerRequestBus(bus.Event, 'AddConnectionBySlotId', newGraphId, ditherNode,
|
||||
outboundGradientSlotId, gradientMixerNode, inboundGradientSlotId)
|
||||
|
||||
# Delay to allow all the underlying component properties to be updated after the slot connections are made
|
||||
general.idle_wait(1.0)
|
||||
|
||||
|
||||
# Verify the Preview EntityId property on our Random Noise Gradient component has been set to our Box Shape's
|
||||
# EntityId
|
||||
previewEntityId = getEntityIdFromComponentProperty(randomNoiseEntityId, 'Random Noise Gradient',
|
||||
'Preview Settings|Pin Preview to Shape')
|
||||
random_gradient_success = previewEntityId and boxShapeEntityId.invoke("Equal", previewEntityId)
|
||||
Report.result(Tests.preview_entity_set, random_gradient_success)
|
||||
|
||||
# Verify the Inbound Gradient EntityId property on our Dither Gradient Modifier component has been set to our
|
||||
# Random Noise Gradient's EntityId
|
||||
inboundGradientEntityId = getEntityIdFromComponentProperty(ditherEntityId, 'Dither Gradient Modifier',
|
||||
'Configuration|Gradient|Gradient Entity Id')
|
||||
dither_gradient_success = inboundGradientEntityId and randomNoiseEntityId.invoke("Equal",
|
||||
inboundGradientEntityId)
|
||||
Report.result(Tests.dither_inbound_gradient_set, dither_gradient_success)
|
||||
|
||||
# Verify the Inbound Gradient Mixer EntityId property on our Gradient Mixer component has been set to our
|
||||
# Dither Gradient Modifier's EntityId
|
||||
inboundGradientMixerEntityId = getEntityIdFromComponentProperty(gradientMixerEntityId, 'Gradient Mixer',
|
||||
'Configuration|Layers|[0]|Gradient|Gradient Entity Id')
|
||||
gradient_mixer_success = inboundGradientMixerEntityId and ditherEntityId.invoke("Equal",
|
||||
inboundGradientMixerEntityId)
|
||||
Report.result(Tests.mixer_inbound_gradient_set, gradient_mixer_success)
|
||||
|
||||
# Stop listening for entity creation notifications
|
||||
handler.disconnect()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test(SlotConnections_UpdateComponentReferences)
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
"""
|
||||
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
|
||||
|
||||
import ly_test_tools.environment.file_system as file_system
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared')
|
||||
from base import TestAutomationBase
|
||||
|
||||
|
||||
@pytest.mark.SUITE_main
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(TestAutomationBase):
|
||||
|
||||
def test_LandscapeCanvas_SlotConnections_UpdateComponentReferences(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_GradientMixer_NodeConstruction(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientMixer_NodeConstruction as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
"""
|
||||
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_LandscapeCanvas_SlotConnections_UpdateComponentReferences(EditorSharedTest):
|
||||
from .EditorScripts import SlotConnections_UpdateComponentReferences as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientMixer_NodeConstruction(EditorSharedTest):
|
||||
from .EditorScripts import GradientMixer_NodeConstruction as test_module
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
"""
|
||||
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
|
||||
|
||||
import ly_test_tools.environment.file_system as file_system
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../automatedtesting_shared')
|
||||
from base import TestAutomationBase
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def remove_test_slice(request, workspace, project):
|
||||
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice.slice")], True, True)
|
||||
|
||||
def teardown():
|
||||
file_system.delete([os.path.join(workspace.paths.engine_root(), project, "slices", "TestSlice.slice")], True,
|
||||
True)
|
||||
|
||||
request.addfinalizer(teardown)
|
||||
|
||||
|
||||
@pytest.mark.SUITE_periodic
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(TestAutomationBase):
|
||||
|
||||
def test_LandscapeCanvas_AreaNodes_DependentComponentsAdded(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import AreaNodes_DependentComponentsAdded as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import AreaNodes_EntityCreatedOnNodeAdd as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import AreaNodes_EntityRemovedOnNodeDelete as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import LayerExtenderNodes_ComponentEntitySync as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_Edit_DisabledNodeDuplication(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import Edit_DisabledNodeDuplication as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_Edit_UndoNodeDelete_SliceEntity(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import Edit_UndoNodeDelete_SliceEntity as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_NewGraph_CreatedSuccessfully(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import NewGraph_CreatedSuccessfully as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_Component_AddedRemoved(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import Component_AddedRemoved as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_GraphClosed_OnLevelChange(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GraphClosed_OnLevelChange as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201")
|
||||
def test_LandscapeCanvas_GraphClosed_OnEntityDelete(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GraphClosed_OnEntityDelete as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GraphClosed_TabbedGraph as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_Slice_CreateInstantiate(self, request, workspace, editor, remove_test_slice, launcher_platform):
|
||||
from .EditorScripts import Slice_CreateInstantiate as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_GradientModifierNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientModifierNodes_EntityCreatedOnNodeAdd as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_GradientModifierNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientModifierNodes_EntityRemovedOnNodeDelete as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_GradientNodes_DependentComponentsAdded(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientNodes_DependentComponentsAdded as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_GradientNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientNodes_EntityCreatedOnNodeAdd as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_GradientNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GradientNodes_EntityRemovedOnNodeDelete as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_GraphUpdates_UpdateComponents(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import GraphUpdates_UpdateComponents as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_ComponentUpdates_UpdateGraph(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import ComponentUpdates_UpdateGraph as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_LayerBlender_NodeConstruction(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import LayerBlender_NodeConstruction as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_ShapeNodes_EntityCreatedOnNodeAdd(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import ShapeNodes_EntityCreatedOnNodeAdd as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_LandscapeCanvas_ShapeNodes_EntityRemovedOnNodeDelete(self, request, workspace, editor, launcher_platform):
|
||||
from .EditorScripts import ShapeNodes_EntityRemovedOnNodeDelete as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
"""
|
||||
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 ly_test_tools.environment.file_system as file_system
|
||||
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_LandscapeCanvas_AreaNodes_DependentComponentsAdded(EditorSharedTest):
|
||||
from .EditorScripts import AreaNodes_DependentComponentsAdded as test_module
|
||||
|
||||
class test_LandscapeCanvas_AreaNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
|
||||
from .EditorScripts import AreaNodes_EntityCreatedOnNodeAdd as test_module
|
||||
|
||||
class test_LandscapeCanvas_AreaNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
|
||||
from .EditorScripts import AreaNodes_EntityRemovedOnNodeDelete as test_module
|
||||
|
||||
class test_LandscapeCanvas_LayerExtenderNodes_ComponentEntitySync(EditorSharedTest):
|
||||
from .EditorScripts import LayerExtenderNodes_ComponentEntitySync as test_module
|
||||
|
||||
class test_LandscapeCanvas_Edit_DisabledNodeDuplication(EditorSharedTest):
|
||||
from .EditorScripts import Edit_DisabledNodeDuplication as test_module
|
||||
|
||||
class test_LandscapeCanvas_Edit_UndoNodeDelete_SliceEntity(EditorSharedTest):
|
||||
from .EditorScripts import Edit_UndoNodeDelete_SliceEntity as test_module
|
||||
|
||||
class test_LandscapeCanvas_NewGraph_CreatedSuccessfully(EditorSharedTest):
|
||||
from .EditorScripts import NewGraph_CreatedSuccessfully as test_module
|
||||
|
||||
class test_LandscapeCanvas_Component_AddedRemoved(EditorSharedTest):
|
||||
from .EditorScripts import Component_AddedRemoved as test_module
|
||||
|
||||
class test_LandscapeCanvas_GraphClosed_OnLevelChange(EditorSharedTest):
|
||||
from .EditorScripts import GraphClosed_OnLevelChange as test_module
|
||||
|
||||
@pytest.mark.xfail(reason="https://github.com/o3de/o3de/issues/2201")
|
||||
class test_LandscapeCanvas_GraphClosed_OnEntityDelete(EditorSharedTest):
|
||||
from .EditorScripts import GraphClosed_OnEntityDelete as test_module
|
||||
|
||||
class test_LandscapeCanvas_GraphClosed_TabbedGraphClosesIndependently(EditorSharedTest):
|
||||
from .EditorScripts import GraphClosed_TabbedGraph as test_module
|
||||
|
||||
class test_LandscapeCanvas_Slice_CreateInstantiate(EditorSingleTest):
|
||||
# Custom teardown to remove slice asset created during test
|
||||
def teardown(self, request, workspace, editor, editor_test_results, launcher_platform):
|
||||
file_system.delete([os.path.join(workspace.paths.engine_root(), "AutomatedTesting", "slices",
|
||||
"TestSlice.slice")], True, True)
|
||||
from .EditorScripts import Slice_CreateInstantiate as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientModifierNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
|
||||
from .EditorScripts import GradientModifierNodes_EntityCreatedOnNodeAdd as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientModifierNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
|
||||
from .EditorScripts import GradientModifierNodes_EntityRemovedOnNodeDelete as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientNodes_DependentComponentsAdded(EditorSharedTest):
|
||||
from .EditorScripts import GradientNodes_DependentComponentsAdded as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
|
||||
from .EditorScripts import GradientNodes_EntityCreatedOnNodeAdd as test_module
|
||||
|
||||
class test_LandscapeCanvas_GradientNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
|
||||
from .EditorScripts import GradientNodes_EntityRemovedOnNodeDelete as test_module
|
||||
|
||||
class test_LandscapeCanvas_GraphUpdates_UpdateComponents(EditorSharedTest):
|
||||
from .EditorScripts import GraphUpdates_UpdateComponents as test_module
|
||||
|
||||
class test_LandscapeCanvas_ComponentUpdates_UpdateGraph(EditorSharedTest):
|
||||
from .EditorScripts import ComponentUpdates_UpdateGraph as test_module
|
||||
|
||||
class test_LandscapeCanvas_LayerBlender_NodeConstruction(EditorSharedTest):
|
||||
from .EditorScripts import LayerBlender_NodeConstruction as test_module
|
||||
|
||||
class test_LandscapeCanvas_ShapeNodes_EntityCreatedOnNodeAdd(EditorSharedTest):
|
||||
from .EditorScripts import ShapeNodes_EntityCreatedOnNodeAdd as test_module
|
||||
|
||||
class test_LandscapeCanvas_ShapeNodes_EntityRemovedOnNodeDelete(EditorSharedTest):
|
||||
from .EditorScripts import ShapeNodes_EntityRemovedOnNodeDelete as test_module
|
||||
@@ -675,14 +675,14 @@ void AzAssetBrowserRequestHandler::OpenAssetInAssociatedEditor(const AZ::Data::A
|
||||
firstValidOpener = &openerDetails;
|
||||
}
|
||||
// bind a callback such that when the menu item is clicked, it sets that as the opener to use.
|
||||
menu.addAction(openerDetails.m_iconToUse, QObject::tr(openerDetails.m_displayText.c_str()), mainWindow, AZStd::bind(switchToOpener, &openerDetails));
|
||||
menu.addAction(openerDetails.m_iconToUse, QObject::tr(openerDetails.m_displayText.c_str()), mainWindow, [switchToOpener, details = &openerDetails] { return switchToOpener(details); });
|
||||
}
|
||||
}
|
||||
|
||||
if (numValidOpeners > 1) // more than one option was added
|
||||
{
|
||||
menu.addSeparator();
|
||||
menu.addAction(QObject::tr("Cancel"), AZStd::bind(switchToOpener, nullptr)); // just something to click on to avoid doing anything.
|
||||
menu.addAction(QObject::tr("Cancel"), [switchToOpener] { return switchToOpener(nullptr); }); // just something to click on to avoid doing anything.
|
||||
menu.exec(QCursor::pos());
|
||||
}
|
||||
else if (numValidOpeners == 1)
|
||||
|
||||
@@ -145,7 +145,7 @@ bool UserPopupWidgetHandler::ReadValuesIntoGUI(size_t index, UserPropertyEditor*
|
||||
QWidget* FloatCurveHandler::CreateGUI(QWidget *pParent)
|
||||
{
|
||||
CSplineCtrl *cSpline = new CSplineCtrl(pParent);
|
||||
cSpline->SetUpdateCallback(AZStd::bind(&FloatCurveHandler::OnSplineChange, this, AZStd::placeholders::_1));
|
||||
cSpline->SetUpdateCallback([this](CSplineCtrl* spl) { OnSplineChange(spl); });
|
||||
cSpline->SetTimeRange(0, 1);
|
||||
cSpline->SetValueRange(0, 1);
|
||||
cSpline->SetGrid(12, 12);
|
||||
|
||||
@@ -172,8 +172,8 @@ ReflectedPropertyItem::ReflectedPropertyItem(ReflectedPropertyControl *control,
|
||||
if (parent)
|
||||
parent->AddChild(this);
|
||||
|
||||
m_onSetCallback = AZStd::bind(&ReflectedPropertyItem::OnVariableChange, this, AZStd::placeholders::_1);
|
||||
m_onSetEnumCallback = AZStd::bind(&ReflectedPropertyItem::OnVariableEnumChange, this, AZStd::placeholders::_1);
|
||||
m_onSetCallback = [this](IVariable* var) { OnVariableChange(var); };
|
||||
m_onSetEnumCallback = [this](IVariable* var) { OnVariableEnumChange(var); };
|
||||
}
|
||||
|
||||
ReflectedPropertyItem::~ReflectedPropertyItem()
|
||||
|
||||
@@ -2634,7 +2634,6 @@ void EditorViewportWidget::ShowCursor()
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void EditorViewportWidget::PushDisableRendering()
|
||||
{
|
||||
assert(m_disableRenderingCount >= 0);
|
||||
++m_disableRenderingCount;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace UnitTest
|
||||
m_inputChannelMapper = AZStd::make_unique<AzToolsFramework::QtEventToAzInputMapper>(m_rootWidget.get(), TestViewportId);
|
||||
}
|
||||
|
||||
void TearDown()
|
||||
void TearDown() override
|
||||
{
|
||||
m_inputChannelMapper.reset();
|
||||
|
||||
|
||||
@@ -24,10 +24,10 @@ namespace UnitTest
|
||||
void Disconnect();
|
||||
|
||||
// EditorInteractionSystemViewportSelectionRequestBus overrides ...
|
||||
void SetHandler(const AzToolsFramework::ViewportSelectionRequestsBuilderFn& interactionRequestsBuilder);
|
||||
void SetDefaultHandler();
|
||||
bool InternalHandleMouseViewportInteraction(const MouseInteractionEvent& mouseInteraction);
|
||||
bool InternalHandleMouseManipulatorInteraction(const MouseInteractionEvent& mouseInteraction);
|
||||
void SetHandler(const AzToolsFramework::ViewportSelectionRequestsBuilderFn& interactionRequestsBuilder) override;
|
||||
void SetDefaultHandler() override;
|
||||
bool InternalHandleMouseViewportInteraction(const MouseInteractionEvent& mouseInteraction) override;
|
||||
bool InternalHandleMouseManipulatorInteraction(const MouseInteractionEvent& mouseInteraction) override;
|
||||
|
||||
AZStd::function<bool(const MouseInteractionEvent& mouseInteraction)> m_internalHandleMouseViewportInteraction;
|
||||
AZStd::function<bool(const MouseInteractionEvent& mouseInteraction)> m_internalHandleMouseManipulatorInteraction;
|
||||
@@ -92,7 +92,7 @@ namespace UnitTest
|
||||
m_inputChannelMapper = AZStd::make_unique<AzToolsFramework::QtEventToAzInputMapper>(m_rootWidget.get(), TestViewportId);
|
||||
}
|
||||
|
||||
void TearDown()
|
||||
void TearDown() override
|
||||
{
|
||||
m_inputChannelMapper.reset();
|
||||
|
||||
|
||||
@@ -1767,7 +1767,7 @@ void MainWindow::RegisterOpenWndCommands()
|
||||
cmdUI.tooltip = (QString("Open ") + className).toUtf8().data();
|
||||
cmdUI.iconFilename = className.toUtf8().data();
|
||||
GetIEditor()->GetCommandManager()->RegisterUICommand("editor", openCommandName.toUtf8().data(),
|
||||
"", "", AZStd::bind(&CEditorOpenViewCommand::Execute, pCmd), cmdUI);
|
||||
"", "", [pCmd] { pCmd->Execute(); }, cmdUI);
|
||||
GetIEditor()->GetCommandManager()->GetUIInfo("editor", openCommandName.toUtf8().data(), cmdUI);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1515,8 +1515,8 @@ void CBaseObject::Serialize(CObjectArchive& ar)
|
||||
SetFrozen(bFrozen);
|
||||
SetHidden(bHidden);
|
||||
|
||||
ar.SetResolveCallback(this, parentId, AZStd::bind(&CBaseObject::ResolveParent, this, AZStd::placeholders::_1 ));
|
||||
ar.SetResolveCallback(this, lookatId, AZStd::bind(&CBaseObject::SetLookAt, this, AZStd::placeholders::_1));
|
||||
ar.SetResolveCallback(this, parentId, [this](CBaseObject* parent) { ResolveParent(parent); });
|
||||
ar.SetResolveCallback(this, lookatId, [this](CBaseObject* target) { SetLookAt(target); });
|
||||
|
||||
InvalidateTM(0);
|
||||
SetModified(false);
|
||||
@@ -2038,7 +2038,7 @@ bool CBaseObject::HitHelperAtTest(HitContext& hc, const Vec3& pos)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CBaseObject* CBaseObject::GetChild(size_t const i) const
|
||||
{
|
||||
assert(i >= 0 && i < m_childs.size());
|
||||
assert(i < m_childs.size());
|
||||
return m_childs[i];
|
||||
}
|
||||
|
||||
@@ -2729,7 +2729,7 @@ void CBaseObject::SetMinSpec(uint32 nSpec, bool bSetChildren)
|
||||
// Set min spec for all childs.
|
||||
if (bSetChildren)
|
||||
{
|
||||
for (size_t i = m_childs.size() - 1; i >= 0; --i)
|
||||
for (int i = static_cast<int>(m_childs.size()) - 1; i >= 0; --i)
|
||||
{
|
||||
m_childs[i]->SetMinSpec(nSpec, true);
|
||||
}
|
||||
|
||||
@@ -230,25 +230,25 @@ CEntityObject::CEntityObject()
|
||||
m_attachmentType = eAT_Pivot;
|
||||
|
||||
// cache all the variable callbacks, must match order of enum defined in header
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnAreaHeightChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnAreaLightChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnAreaLightSizeChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnAreaWidthChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnBoxHeightChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnBoxLengthChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnBoxProjectionChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnBoxSizeXChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnBoxSizeYChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnBoxSizeZChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnBoxWidthChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnColorChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnInnerRadiusChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnOuterRadiusChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnProjectInAllDirsChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnProjectorFOVChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnProjectorTextureChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnPropertyChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.push_back(AZStd::bind(&CEntityObject::OnRadiusChange, this, AZStd::placeholders::_1));
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnAreaHeightChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnAreaLightChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnAreaLightSizeChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnAreaWidthChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnBoxHeightChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnBoxLengthChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnBoxProjectionChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnBoxSizeXChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnBoxSizeYChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnBoxSizeZChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnBoxWidthChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnColorChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnInnerRadiusChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnOuterRadiusChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnProjectInAllDirsChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnProjectorFOVChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnProjectorTextureChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnPropertyChange(var); });
|
||||
m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnRadiusChange(var); });
|
||||
}
|
||||
|
||||
CEntityObject::~CEntityObject()
|
||||
@@ -938,11 +938,14 @@ void CEntityObject::Serialize(CObjectArchive& ar)
|
||||
eventTarget->getAttr("TargetId", targetId);
|
||||
eventTarget->getAttr("Event", et.event);
|
||||
eventTarget->getAttr("SourceEvent", et.sourceEvent);
|
||||
m_eventTargets.push_back(et);
|
||||
m_eventTargets.emplace_back(AZStd::move(et));
|
||||
if (targetId != GUID_NULL)
|
||||
{
|
||||
using namespace AZStd::placeholders;
|
||||
ar.SetResolveCallback(this, targetId, AZStd::bind(&CEntityObject::ResolveEventTarget, this, _1, _2), i);
|
||||
ar.SetResolveCallback(
|
||||
this, targetId,
|
||||
[this](CBaseObject* object, unsigned int index) { ResolveEventTarget(object, index); },
|
||||
i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1413,7 +1416,7 @@ void CEntityObject::PostClone(CBaseObject* pFromObject, CObjectCloneContext& ctx
|
||||
void CEntityObject::ResolveEventTarget(CBaseObject* object, unsigned int index)
|
||||
{
|
||||
// Find target id.
|
||||
assert(index >= 0 && index < m_eventTargets.size());
|
||||
assert(index < m_eventTargets.size());
|
||||
if (object)
|
||||
{
|
||||
object->AddEventListener(this);
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <QPainter>
|
||||
#include <QPalette>
|
||||
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
|
||||
namespace DrawingPrimitives
|
||||
{
|
||||
void DrawTimeSlider(QPainter& painter, const QPalette& palette, const STimeSliderOptions& options)
|
||||
|
||||
@@ -110,7 +110,7 @@ void CTrackViewKeyPropertiesDlg::PopulateVariables()
|
||||
m_wndProps->RemoveAllItems();
|
||||
m_wndProps->AddVarBlock(m_pVarBlock);
|
||||
|
||||
m_wndProps->SetUpdateCallback(AZStd::bind(&CTrackViewKeyPropertiesDlg::OnVarChange, this, AZStd::placeholders::_1));
|
||||
m_wndProps->SetUpdateCallback([this](IVariable* var) { OnVarChange(var); });
|
||||
//m_wndProps->m_props.ExpandAll();
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
}
|
||||
void Undo(bool bUndo) override
|
||||
{
|
||||
for (size_t i = m_undoSteps.size() - 1; i >= 0; i--)
|
||||
for (int i = static_cast<int>(m_undoSteps.size()) - 1; i >= 0; i--)
|
||||
{
|
||||
m_undoSteps[i]->Undo(bUndo);
|
||||
}
|
||||
|
||||
@@ -58,36 +58,26 @@ bool C3DConnexionDriver::InitDevice()
|
||||
//Doc says RIM_TYPEHID: Data comes from an HID that is not a keyboard or a mouse.
|
||||
if (m_pRawInputDeviceList[i].dwType == RIM_TYPEHID)
|
||||
{
|
||||
UINT nchars = 300;
|
||||
TCHAR deviceName[300];
|
||||
if (GetRawInputDeviceInfo(m_pRawInputDeviceList[i].hDevice,
|
||||
RIDI_DEVICENAME, deviceName, &nchars) >= 0)
|
||||
{
|
||||
//_RPT3(_CRT_WARN, "Device[%d]: handle=0x%x name = %S\n", i, g_pRawInputDeviceList[i].hDevice, deviceName);
|
||||
}
|
||||
|
||||
RID_DEVICE_INFO dinfo;
|
||||
UINT sizeofdinfo = sizeof(dinfo);
|
||||
dinfo.cbSize = sizeofdinfo;
|
||||
if (GetRawInputDeviceInfo(m_pRawInputDeviceList[i].hDevice,
|
||||
RIDI_DEVICEINFO, &dinfo, &sizeofdinfo) >= 0)
|
||||
GetRawInputDeviceInfo(m_pRawInputDeviceList[i].hDevice,
|
||||
RIDI_DEVICEINFO, &dinfo, &sizeofdinfo);
|
||||
if (dinfo.dwType == RIM_TYPEHID)
|
||||
{
|
||||
if (dinfo.dwType == RIM_TYPEHID)
|
||||
RID_DEVICE_INFO_HID* phidInfo = &dinfo.hid;
|
||||
// Add this one to the list of interesting devices?
|
||||
// Actually only have to do this once to get input from all usage 1, usagePage 8 devices
|
||||
// This just keeps out the other usages.
|
||||
// You might want to put up a list for users to select amongst the different devices.
|
||||
// In particular, to assign separate functionality to the different devices.
|
||||
if (phidInfo->usUsagePage == 1 && phidInfo->usUsage == 8)
|
||||
{
|
||||
RID_DEVICE_INFO_HID* phidInfo = &dinfo.hid;
|
||||
// Add this one to the list of interesting devices?
|
||||
// Actually only have to do this once to get input from all usage 1, usagePage 8 devices
|
||||
// This just keeps out the other usages.
|
||||
// You might want to put up a list for users to select amongst the different devices.
|
||||
// In particular, to assign separate functionality to the different devices.
|
||||
if (phidInfo->usUsagePage == 1 && phidInfo->usUsage == 8)
|
||||
{
|
||||
m_pRawInputDevices[m_nUsagePage1Usage8Devices].usUsagePage = phidInfo->usUsagePage;
|
||||
m_pRawInputDevices[m_nUsagePage1Usage8Devices].usUsage = phidInfo->usUsage;
|
||||
m_pRawInputDevices[m_nUsagePage1Usage8Devices].dwFlags = 0;
|
||||
m_pRawInputDevices[m_nUsagePage1Usage8Devices].hwndTarget = nullptr;
|
||||
m_nUsagePage1Usage8Devices++;
|
||||
}
|
||||
m_pRawInputDevices[m_nUsagePage1Usage8Devices].usUsagePage = phidInfo->usUsagePage;
|
||||
m_pRawInputDevices[m_nUsagePage1Usage8Devices].usUsage = phidInfo->usUsage;
|
||||
m_pRawInputDevices[m_nUsagePage1Usage8Devices].dwFlags = 0;
|
||||
m_pRawInputDevices[m_nUsagePage1Usage8Devices].hwndTarget = nullptr;
|
||||
m_nUsagePage1Usage8Devices++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,7 +467,7 @@ bool CKDTree::FindNearestVertexRecursively(KDTreeNode* pNode, const Vec3& raySrc
|
||||
uint32 nVertexIndex = pNode->GetVertexIndex(i);
|
||||
uint32 nObjIndex = pNode->GetObjIndex(i);
|
||||
|
||||
assert(nObjIndex < m_StatObjectList.size() && nObjIndex >= 0);
|
||||
assert(nObjIndex < m_StatObjectList.size());
|
||||
|
||||
const SStatObj* pStatObjInfo = &(m_StatObjectList[nObjIndex]);
|
||||
|
||||
|
||||
@@ -769,7 +769,9 @@ namespace
|
||||
|
||||
void PySetViewPaneLayout(unsigned int layoutId)
|
||||
{
|
||||
AZ_PUSH_DISABLE_WARNING(4296, "-Wunknown-warning-option")
|
||||
if ((layoutId >= ET_Layout0) && (layoutId <= ET_Layout8))
|
||||
AZ_POP_DISABLE_WARNING
|
||||
{
|
||||
CLayoutWnd* layout = GetIEditor()->GetViewManager()->GetLayout();
|
||||
if (layout)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/RTTI/TypeInfoSimple.h>
|
||||
#include <AzCore/std/limits.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
|
||||
namespace AZ::Debug
|
||||
{
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <AzCore/std/typetraits/is_const.h>
|
||||
#include <AzCore/std/typetraits/has_member_function.h>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/IO/IOUtils.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
|
||||
namespace AZ::IO
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <AzCore/std/containers/array.h>
|
||||
#include <AzCore/std/string/wildcard.h>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
|
||||
// extern instantiations of Path templates to prevent implicit instantiations
|
||||
namespace AZ::IO
|
||||
|
||||
@@ -17,15 +17,23 @@
|
||||
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
|
||||
#define AZCORE_SYS_ALLOCATOR_HPPA // If you disable this make sure you start building the heapschema.cpp
|
||||
//#define AZCORE_SYS_ALLOCATOR_MALLOC
|
||||
#define AZCORE_SYSTEM_ALLOCATOR_HPHA 1
|
||||
#define AZCORE_SYSTEM_ALLOCATOR_MALLOC 2
|
||||
#define AZCORE_SYSTEM_ALLOCATOR_HEAP 3
|
||||
|
||||
#ifdef AZCORE_SYS_ALLOCATOR_HPPA
|
||||
# include <AzCore/Memory/HphaSchema.h>
|
||||
#elif defined(AZCORE_SYS_ALLOCATOR_MALLOC)
|
||||
#include <AzCore/Memory/MallocSchema.h>
|
||||
#if !defined(AZCORE_SYSTEM_ALLOCATOR)
|
||||
// define the default
|
||||
#define AZCORE_SYSTEM_ALLOCATOR AZCORE_SYSTEM_ALLOCATOR_HPHA
|
||||
#endif
|
||||
|
||||
#if AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HPHA
|
||||
#include <AzCore/Memory/HphaSchema.h>
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_MALLOC
|
||||
#include <AzCore/Memory/MallocSchema.h>
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HEAP
|
||||
#include <AzCore/Memory/HeapSchema.h>
|
||||
#else
|
||||
# include <AzCore/Memory/HeapSchema.h>
|
||||
#error "Invalid allocator selected for SystemAllocator"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -34,12 +42,12 @@ using namespace AZ;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Globals - we use global storage for the first memory schema, since we can't use dynamic memory!
|
||||
static bool g_isSystemSchemaUsed = false;
|
||||
#ifdef AZCORE_SYS_ALLOCATOR_HPPA
|
||||
static AZStd::aligned_storage<sizeof(HphaSchema), AZStd::alignment_of<HphaSchema>::value>::type g_systemSchema;
|
||||
#elif defined(AZCORE_SYS_ALLOCATOR_MALLOC)
|
||||
static AZStd::aligned_storage<sizeof(MallocSchema), AZStd::alignment_of<MallocSchema>::value>::type g_systemSchema;
|
||||
#else
|
||||
static AZStd::aligned_storage<sizeof(HeapSchema), AZStd::alignment_of<HeapSchema>::value>::type g_systemSchema;
|
||||
#if AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HPHA
|
||||
static AZStd::aligned_storage<sizeof(HphaSchema), AZStd::alignment_of<HphaSchema>::value>::type g_systemSchema;
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_MALLOC
|
||||
static AZStd::aligned_storage<sizeof(MallocSchema), AZStd::alignment_of<MallocSchema>::value>::type g_systemSchema;
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HEAP
|
||||
static AZStd::aligned_storage<sizeof(HeapSchema), AZStd::alignment_of<HeapSchema>::value>::type g_systemSchema;
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -97,9 +105,9 @@ SystemAllocator::Create(const Descriptor& desc)
|
||||
else
|
||||
{
|
||||
m_isCustom = false;
|
||||
#ifdef AZCORE_SYS_ALLOCATOR_HPPA
|
||||
HphaSchema::Descriptor heapDesc;
|
||||
heapDesc.m_pageSize = desc.m_heap.m_pageSize;
|
||||
#if AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HPHA
|
||||
HphaSchema::Descriptor heapDesc;
|
||||
heapDesc.m_pageSize = desc.m_heap.m_pageSize;
|
||||
heapDesc.m_poolPageSize = desc.m_heap.m_poolPageSize;
|
||||
AZ_Assert(desc.m_heap.m_numFixedMemoryBlocks <= 1, "We support max1 memory block at the moment!");
|
||||
if (desc.m_heap.m_numFixedMemoryBlocks > 0)
|
||||
@@ -111,11 +119,10 @@ SystemAllocator::Create(const Descriptor& desc)
|
||||
heapDesc.m_isPoolAllocations = desc.m_heap.m_isPoolAllocations;
|
||||
// Fix SystemAllocator from growing in small chunks
|
||||
heapDesc.m_systemChunkSize = desc.m_heap.m_systemChunkSize;
|
||||
|
||||
#elif defined(AZCORE_SYS_ALLOCATOR_MALLOC)
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_MALLOC
|
||||
MallocSchema::Descriptor heapDesc;
|
||||
#else
|
||||
HeapSchema::Descriptor heapDesc;
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HEAP
|
||||
HeapSchema::Descriptor heapDesc;
|
||||
memcpy(heapDesc.m_memoryBlocks, desc.m_heap.m_memoryBlocks, sizeof(heapDesc.m_memoryBlocks));
|
||||
memcpy(heapDesc.m_memoryBlocksByteSize, desc.m_heap.m_memoryBlocksByteSize, sizeof(heapDesc.m_memoryBlocksByteSize));
|
||||
heapDesc.m_numMemoryBlocks = desc.m_heap.m_numMemoryBlocks;
|
||||
@@ -124,11 +131,11 @@ SystemAllocator::Create(const Descriptor& desc)
|
||||
{
|
||||
AZ_Assert(!g_isSystemSchemaUsed, "AZ::SystemAllocator MUST be created first! It's the source of all allocations!");
|
||||
|
||||
#ifdef AZCORE_SYS_ALLOCATOR_HPPA
|
||||
#if AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HPHA
|
||||
m_allocator = new(&g_systemSchema)HphaSchema(heapDesc);
|
||||
#elif defined(AZCORE_SYS_ALLOCATOR_MALLOC)
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_MALLOC
|
||||
m_allocator = new(&g_systemSchema)MallocSchema(heapDesc);
|
||||
#else
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HEAP
|
||||
m_allocator = new(&g_systemSchema)HeapSchema(heapDesc);
|
||||
#endif
|
||||
g_isSystemSchemaUsed = true;
|
||||
@@ -139,14 +146,13 @@ SystemAllocator::Create(const Descriptor& desc)
|
||||
// this class should be inheriting from SystemAllocator
|
||||
AZ_Assert(AllocatorInstance<SystemAllocator>::IsReady(), "System allocator must be created before any other allocator! They allocate from it.");
|
||||
|
||||
#ifdef AZCORE_SYS_ALLOCATOR_HPPA
|
||||
#if AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HPHA
|
||||
m_allocator = azcreate(HphaSchema, (heapDesc), SystemAllocator);
|
||||
#elif defined(AZCORE_SYS_ALLOCATOR_MALLOC)
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_MALLOC
|
||||
m_allocator = azcreate(MallocSchema, (heapDesc), SystemAllocator);
|
||||
#else
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HEAP
|
||||
m_allocator = azcreate(HeapSchema, (heapDesc), SystemAllocator);
|
||||
#endif
|
||||
|
||||
if (m_allocator == NULL)
|
||||
{
|
||||
isReady = false;
|
||||
@@ -178,11 +184,11 @@ SystemAllocator::Destroy()
|
||||
{
|
||||
if ((void*)m_allocator == (void*)&g_systemSchema)
|
||||
{
|
||||
#ifdef AZCORE_SYS_ALLOCATOR_HPPA
|
||||
#if AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HPHA
|
||||
static_cast<HphaSchema*>(m_allocator)->~HphaSchema();
|
||||
#elif defined(AZCORE_SYS_ALLOCATOR_MALLOC)
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_MALLOC
|
||||
static_cast<MallocSchema*>(m_allocator)->~MallocSchema();
|
||||
#else
|
||||
#elif AZCORE_SYSTEM_ALLOCATOR == AZCORE_SYSTEM_ALLOCATOR_HEAP
|
||||
static_cast<HeapSchema*>(m_allocator)->~HeapSchema();
|
||||
#endif
|
||||
g_isSystemSchemaUsed = false;
|
||||
|
||||
@@ -36,10 +36,13 @@ namespace AZ
|
||||
|
||||
void NameData::release()
|
||||
{
|
||||
// this could be released after we decrement the counter, therefore we will
|
||||
// base the release on the hash which is stable
|
||||
Hash hash = m_hash;
|
||||
AZ_Assert(m_useCount > 0, "m_useCount is already 0!");
|
||||
if (m_useCount.fetch_sub(1) == 1)
|
||||
{
|
||||
AZ::NameDictionary::Instance().TryReleaseName(this);
|
||||
AZ::NameDictionary::Instance().TryReleaseName(hash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
|
||||
#include <AzCore/Name/Internal/NameData.h>
|
||||
|
||||
namespace UnitTest
|
||||
{
|
||||
class NameTest;
|
||||
}
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class NameDictionary;
|
||||
@@ -29,6 +34,7 @@ namespace AZ
|
||||
class Name
|
||||
{
|
||||
friend NameDictionary;
|
||||
friend UnitTest::NameTest;
|
||||
public:
|
||||
using Hash = Internal::NameData::Hash;
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void NameDictionary::TryReleaseName(Internal::NameData* nameData)
|
||||
void NameDictionary::TryReleaseName(Name::Hash hash)
|
||||
{
|
||||
// Note that we don't remove NameData from the dictionary if it has been involved in a collision.
|
||||
// This avoids specific edge cases where a Name object could get an incorrect hash value. Consider
|
||||
@@ -179,15 +179,24 @@ namespace AZ
|
||||
// the dictionary *again*, this time with hash value 1000. Name objects pointing to the original
|
||||
// entry and Name objects pointing to the new entry will fail comparison operations.
|
||||
|
||||
// Early exit to avoid locking the mutex unnecessarily.
|
||||
if (nameData->m_hashCollision)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AZStd::unique_lock<AZStd::shared_mutex> lock(m_sharedMutex);
|
||||
|
||||
// Check m_hashCollision again inside the m_sharedMutex because a new collision could have happened
|
||||
auto dictIt = m_dictionary.find(hash);
|
||||
if (dictIt == m_dictionary.end())
|
||||
{
|
||||
// This check is to safeguard around the following scenario
|
||||
// T1, gets into TryReleaseName
|
||||
// T2 gets into MakeName, acquires the lock, returns a new Name that increments the counter
|
||||
// T2 deletes the Name decrements the counter, gets into TryReleaseName
|
||||
// T1 gets the lock, goes to the compare_exchange if and has a counter of 0, deletes
|
||||
// Then T2 continues, gets the lock and crashes because nameData was deleted
|
||||
return;
|
||||
}
|
||||
|
||||
Internal::NameData* nameData = dictIt->second;
|
||||
|
||||
// Check m_hashCollision inside the m_sharedMutex because a new collision could have happened
|
||||
// on another thread before taking the lock.
|
||||
if (nameData->m_hashCollision)
|
||||
{
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace AZ
|
||||
|
||||
// Attempts to release the name from the dictionary, but checks to make sure
|
||||
// a reference wasn't taken by another thread.
|
||||
void TryReleaseName(Internal::NameData* data);
|
||||
void TryReleaseName(Name::Hash hash);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1850,7 +1850,7 @@ namespace AZ
|
||||
* {
|
||||
* // do any conversion of caching of the "data" here and forward this to behavior (often the reason for this is that you can't pass everything to behavior
|
||||
* // plus behavior can't really handle all constructs pointer to pointer, rvalues, etc. as they don't make sense for most script environments
|
||||
* int result = 0; // set the default value for your result if the behavior if there is no implmentation
|
||||
* int result = 0; // set the default value for your result if the behavior if there is no implementation
|
||||
* // The AZ_EBUS_BEHAVIOR_BINDER defines FN_EventName for each index. You can also cache it yourself (but it's slower), static int cacheIndex = GetFunctionIndex("OnEvent1"); and use that .
|
||||
* CallResult(result, FN_OnEvent1, data); // forward to the binding (there can be none, this is why we need to always have properly set result, when there is one)
|
||||
* return result; // return the result like you will in any normal EBus even with result
|
||||
|
||||
@@ -25,6 +25,7 @@ set(FILES
|
||||
Asset/AssetJsonSerializer.h
|
||||
Asset/AssetManager.cpp
|
||||
Asset/AssetManager.h
|
||||
Asset/AssetManager_private.h
|
||||
Asset/AssetManagerBus.h
|
||||
Asset/AssetManagerComponent.cpp
|
||||
Asset/AssetManagerComponent.h
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/std/createdestroy.h>
|
||||
#include <AzCore/std/iterator.h>
|
||||
|
||||
@@ -46,6 +45,10 @@ namespace AZStd
|
||||
return npos;
|
||||
}
|
||||
size_t foundIndex = searchIndex + charFindIndex;
|
||||
if (foundIndex + count > size)
|
||||
{
|
||||
return npos; // the rest of the string doesnt fit in the remainder of the data buffer
|
||||
}
|
||||
if (Traits::compare(&data[foundIndex], ptr, count) == 0)
|
||||
{
|
||||
return foundIndex;
|
||||
|
||||
@@ -53,6 +53,15 @@ ly_add_source_properties(
|
||||
VALUES ${LY_PAL_TOOLS_DEFINES}
|
||||
)
|
||||
|
||||
if(LY_BUILD_WITH_ADDRESS_SANITIZER)
|
||||
# Default to use Malloc schema so ASan works well
|
||||
ly_add_source_properties(
|
||||
SOURCES AzCore/Memory/SystemAllocator.cpp
|
||||
PROPERTY COMPILE_DEFINITIONS
|
||||
VALUES AZCORE_SYSTEM_ALLOCATOR=AZCORE_SYSTEM_ALLOCATOR_MALLOC
|
||||
)
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Tests
|
||||
################################################################################
|
||||
|
||||
@@ -109,6 +109,19 @@
|
||||
#define AZ_TRAIT_USE_ERRNO_T_TYPEDEF 1
|
||||
#define AZ_TRAIT_USE_POSIX_TEMP_FOLDER 0
|
||||
|
||||
// wchar_t/char formatting
|
||||
// Reason: https://docs.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=msvc-160
|
||||
// The Z type character, and the behavior of the c, C, s, and S type characters when they're used with the printf and wprintf functions,
|
||||
// are Microsoft extensions. The ISO C standard uses c and s consistently for narrow characters and strings, and C and S for wide characters
|
||||
// and strings, in all formatting functions.
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_CHAR "%c"
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_WCHAR "%C"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_CHAR "%c"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_WCHAR "%C"
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_STRING "%s"
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_WSTRING "%S"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_STRING "%s"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_WSTRING "%S"
|
||||
// Legacy traits ...
|
||||
#define AZ_TRAIT_LEGACY_CRYCOMMON_USE_WINDOWS_STUBS 1
|
||||
#define AZ_TRAIT_LEGACY_CRYPAK_UNIX_LIKE_FILE_SYSTEM 1
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ namespace AZ::Platform
|
||||
AZ_Assert(m_events[0], "There is no synchronization event created for the main streamer thread to use to suspend.");
|
||||
|
||||
DWORD result = ::WaitForMultipleObjects(m_handleCount, m_events, false, INFINITE);
|
||||
if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + m_handleCount)
|
||||
if (result < WAIT_OBJECT_0 + m_handleCount)
|
||||
{
|
||||
DWORD index = result - WAIT_OBJECT_0;
|
||||
::ResetEvent(m_events[index]);
|
||||
|
||||
@@ -109,6 +109,20 @@
|
||||
#define AZ_TRAIT_USE_ERRNO_T_TYPEDEF 1
|
||||
#define AZ_TRAIT_USE_POSIX_TEMP_FOLDER 1
|
||||
|
||||
// wchar_t/char formatting
|
||||
// Reason: https://docs.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=msvc-160
|
||||
// The Z type character, and the behavior of the c, C, s, and S type characters when they're used with the printf and wprintf functions,
|
||||
// are Microsoft extensions. The ISO C standard uses c and s consistently for narrow characters and strings, and C and S for wide characters
|
||||
// and strings, in all formatting functions.
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_CHAR "%c"
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_WCHAR "%C"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_CHAR "%c"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_WCHAR "%C"
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_STRING "%s"
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_WSTRING "%S"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_STRING "%s"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_WSTRING "%S"
|
||||
|
||||
// Legacy traits ...
|
||||
#define AZ_TRAIT_LEGACY_CRYCOMMON_USE_WINDOWS_STUBS 1
|
||||
#define AZ_TRAIT_LEGACY_CRYPAK_UNIX_LIKE_FILE_SYSTEM 1
|
||||
|
||||
@@ -109,6 +109,20 @@
|
||||
#define AZ_TRAIT_USE_ERRNO_T_TYPEDEF 0
|
||||
#define AZ_TRAIT_USE_POSIX_TEMP_FOLDER 1
|
||||
|
||||
// wchar_t/char formatting
|
||||
// Reason: https://docs.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=msvc-160
|
||||
// The Z type character, and the behavior of the c, C, s, and S type characters when they're used with the printf and wprintf functions,
|
||||
// are Microsoft extensions. The ISO C standard uses c and s consistently for narrow characters and strings, and C and S for wide characters
|
||||
// and strings, in all formatting functions.
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_CHAR "%c"
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_WCHAR "%C"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_CHAR "%c"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_WCHAR "%C"
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_STRING "%s"
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_WSTRING "%S"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_STRING "%s"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_WSTRING "%S"
|
||||
|
||||
// Legacy traits ...
|
||||
#define AZ_TRAIT_LEGACY_CRYCOMMON_USE_WINDOWS_STUBS 1
|
||||
#define AZ_TRAIT_LEGACY_CRYPAK_UNIX_LIKE_FILE_SYSTEM 1
|
||||
|
||||
@@ -109,6 +109,20 @@
|
||||
#define AZ_TRAIT_USE_ERRNO_T_TYPEDEF 0
|
||||
#define AZ_TRAIT_USE_POSIX_TEMP_FOLDER 0
|
||||
|
||||
// wchar_t/char formatting
|
||||
// Reason: https://docs.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=msvc-160
|
||||
// The Z type character, and the behavior of the c, C, s, and S type characters when they're used with the printf and wprintf functions,
|
||||
// are Microsoft extensions. The ISO C standard uses c and s consistently for narrow characters and strings, and C and S for wide characters
|
||||
// and strings, in all formatting functions.
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_CHAR "%c"
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_WCHAR "%C"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_CHAR "%C"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_WCHAR "%c"
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_STRING "%s"
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_WSTRING "%S"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_STRING "%S"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_WSTRING "%s"
|
||||
|
||||
// Legacy traits ...
|
||||
#define AZ_TRAIT_LEGACY_CRYCOMMON_USE_WINDOWS_STUBS 0
|
||||
#define AZ_TRAIT_LEGACY_CRYPAK_UNIX_LIKE_FILE_SYSTEM 0
|
||||
|
||||
@@ -110,6 +110,20 @@
|
||||
#define AZ_TRAIT_USE_ERRNO_T_TYPEDEF 0
|
||||
#define AZ_TRAIT_USE_POSIX_TEMP_FOLDER 0
|
||||
|
||||
// wchar_t/char formatting
|
||||
// Reason: https://docs.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=msvc-160
|
||||
// The Z type character, and the behavior of the c, C, s, and S type characters when they're used with the printf and wprintf functions,
|
||||
// are Microsoft extensions. The ISO C standard uses c and s consistently for narrow characters and strings, and C and S for wide characters
|
||||
// and strings, in all formatting functions.
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_CHAR "%c"
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_WCHAR "%C"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_CHAR "%c"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_WCHAR "%C"
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_STRING "%s"
|
||||
#define AZ_TRAIT_FORMAT_STRING_PRINTF_WSTRING "%S"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_STRING "%s"
|
||||
#define AZ_TRAIT_FORMAT_STRING_WPRINTF_WSTRING "%S"
|
||||
|
||||
// Legacy traits ...
|
||||
#define AZ_TRAIT_LEGACY_CRYCOMMON_USE_WINDOWS_STUBS 1
|
||||
#define AZ_TRAIT_LEGACY_CRYPAK_UNIX_LIKE_FILE_SYSTEM 1
|
||||
|
||||
@@ -1458,17 +1458,17 @@ namespace UnitTest
|
||||
constexpr double v15 = 0;
|
||||
constexpr const char* v16 = "Hello";
|
||||
constexpr const wchar_t* v17 = L"Hello";
|
||||
constexpr void* v18 = 0;
|
||||
constexpr void* v18 = nullptr;
|
||||
|
||||
// This shouldn't give a compile error
|
||||
AZStd::string::format(
|
||||
"%i %c %uc %c %c %i %i %u %i %lu %li %llu %lli %f %f %s %ls %p",
|
||||
"%i %c %uc " AZ_TRAIT_FORMAT_STRING_PRINTF_CHAR AZ_TRAIT_FORMAT_STRING_PRINTF_WCHAR " %i %i %u %i %lu %li %llu %lli %f %f " AZ_TRAIT_FORMAT_STRING_PRINTF_STRING AZ_TRAIT_FORMAT_STRING_PRINTF_WSTRING " %p",
|
||||
v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18);
|
||||
|
||||
// This shouldn't give a compile error
|
||||
AZStd::wstring::format(
|
||||
L"%i %c %uc %c %lc %i %i %u %i %lu %li %llu %lli %f %f %s %ls %p",
|
||||
v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18);
|
||||
L"%i %c %uc " AZ_TRAIT_FORMAT_STRING_WPRINTF_CHAR AZ_TRAIT_FORMAT_STRING_WPRINTF_WCHAR " %i %i %u %i %lu %li %llu %lli %f %f " AZ_TRAIT_FORMAT_STRING_WPRINTF_STRING AZ_TRAIT_FORMAT_STRING_WPRINTF_WSTRING " %p",
|
||||
v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18);
|
||||
|
||||
class WrappedInt
|
||||
{
|
||||
|
||||
@@ -36,12 +36,23 @@ using namespace UnitTestInternal;
|
||||
/**
|
||||
* Validate a vector for certain number of elements.
|
||||
*/
|
||||
#define AZ_TEST_VALIDATE_VECTOR(_Vector, _NumElements) \
|
||||
EXPECT_TRUE(_Vector.validate()); \
|
||||
EXPECT_EQ(_NumElements, _Vector.size()); \
|
||||
EXPECT_TRUE((_NumElements > 0) ? !_Vector.empty() : _Vector.empty()); \
|
||||
EXPECT_TRUE((_NumElements > 0) ? _Vector.capacity() >= _NumElements : true); \
|
||||
EXPECT_TRUE((_NumElements > 0) ? _Vector.begin() != _Vector.end() : _Vector.begin() == _Vector.end()); \
|
||||
#define AZ_TEST_VALIDATE_VECTOR(_Vector, _NumElements) \
|
||||
EXPECT_NE(_NumElements, 0); \
|
||||
EXPECT_TRUE(_Vector.validate()); \
|
||||
EXPECT_EQ(_NumElements, _Vector.size()); \
|
||||
EXPECT_TRUE(!_Vector.empty()); \
|
||||
EXPECT_TRUE(_Vector.capacity() >= _NumElements); \
|
||||
EXPECT_TRUE(_Vector.begin() != _Vector.end()); \
|
||||
EXPECT_NE(nullptr, _Vector.data())
|
||||
|
||||
/**
|
||||
* Validate a vector for 0 number of elements. The above macro creates expressions that are always true for size == 0
|
||||
*/
|
||||
#define AZ_TEST_VALIDATE_VECTOR_0(_Vector) \
|
||||
EXPECT_TRUE(_Vector.validate()); \
|
||||
EXPECT_EQ(0, _Vector.size()); \
|
||||
EXPECT_TRUE(_Vector.empty()); \
|
||||
EXPECT_TRUE(_Vector.begin() == _Vector.end()); \
|
||||
EXPECT_NE(nullptr, _Vector.data())
|
||||
|
||||
namespace UnitTest
|
||||
@@ -312,7 +323,7 @@ namespace UnitTest
|
||||
|
||||
// erase
|
||||
int_vector1.erase(int_vector1.begin(), int_vector1.end());
|
||||
AZ_TEST_VALIDATE_VECTOR(int_vector1, 0); // Zero elements but valid capacity.
|
||||
AZ_TEST_VALIDATE_VECTOR_0(int_vector1); // Zero elements but valid capacity.
|
||||
|
||||
int_vector1.push_back(10);
|
||||
int_vector1.push_back(20);
|
||||
@@ -324,11 +335,11 @@ namespace UnitTest
|
||||
|
||||
// clear
|
||||
int_vector1.clear();
|
||||
AZ_TEST_VALIDATE_VECTOR(int_vector1, 0); // Zero elements but valid capacity.
|
||||
AZ_TEST_VALIDATE_VECTOR_0(int_vector1); // Zero elements but valid capacity.
|
||||
|
||||
// swap
|
||||
int_vector1.swap(int_vector);
|
||||
AZ_TEST_VALIDATE_VECTOR(int_vector, 0);
|
||||
AZ_TEST_VALIDATE_VECTOR_0(int_vector);
|
||||
AZ_TEST_VALIDATE_VECTOR(int_vector1, 33);
|
||||
AZ_TEST_ASSERT(int_vector1.front() == 55);
|
||||
|
||||
@@ -524,11 +535,11 @@ namespace UnitTest
|
||||
|
||||
// Default vector (integral type).
|
||||
fixed_vector<int, 50> int_vector_default;
|
||||
AZ_TEST_VALIDATE_VECTOR(int_vector_default, 0);
|
||||
AZ_TEST_VALIDATE_VECTOR_0(int_vector_default);
|
||||
|
||||
// Default vector (non-integral type).
|
||||
fixed_vector<MyClass, 10> myclass_vector_default;
|
||||
AZ_TEST_VALIDATE_VECTOR(myclass_vector_default, 0);
|
||||
AZ_TEST_VALIDATE_VECTOR_0(myclass_vector_default);
|
||||
|
||||
// Create a vector (using fill ctor, with memset optimization to set the values)
|
||||
typedef fixed_vector<char, 10> char_10_type;
|
||||
@@ -633,7 +644,7 @@ namespace UnitTest
|
||||
|
||||
// erase
|
||||
int_vector1.erase(int_vector1.begin(), int_vector1.end());
|
||||
AZ_TEST_VALIDATE_VECTOR(int_vector1, 0);
|
||||
AZ_TEST_VALIDATE_VECTOR_0(int_vector1);
|
||||
|
||||
int_vector1.push_back(10);
|
||||
int_vector1.push_back(20);
|
||||
@@ -645,11 +656,11 @@ namespace UnitTest
|
||||
|
||||
// clear
|
||||
int_vector1.clear();
|
||||
AZ_TEST_VALIDATE_VECTOR(int_vector1, 0);
|
||||
AZ_TEST_VALIDATE_VECTOR_0(int_vector1);
|
||||
|
||||
// swap
|
||||
int_vector1.swap(int_vector);
|
||||
AZ_TEST_VALIDATE_VECTOR(int_vector, 0);
|
||||
AZ_TEST_VALIDATE_VECTOR_0(int_vector);
|
||||
AZ_TEST_VALIDATE_VECTOR(int_vector1, 33);
|
||||
AZ_TEST_ASSERT(int_vector1.front() == 55);
|
||||
|
||||
@@ -963,7 +974,7 @@ namespace UnitTest
|
||||
AZ_TEST_VALIDATE_VECTOR(deep_vec_2, 12);
|
||||
|
||||
deep_vec_2.clear();
|
||||
AZ_TEST_VALIDATE_VECTOR(deep_vec_2, 0);
|
||||
AZ_TEST_VALIDATE_VECTOR_0(deep_vec_2);
|
||||
}
|
||||
#endif // AZ_UNIT_TEST_SKIP_STD_VECTOR_AND_ARRAY_TESTS
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AzCore/Math/Sfmt.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzCore/Math/Vector4.h>
|
||||
|
||||
using namespace AZ;
|
||||
|
||||
@@ -27,8 +28,8 @@ namespace UnitTest
|
||||
void SetUp() override
|
||||
{
|
||||
AllocatorsFixture::SetUp();
|
||||
array1 = (AZ::u64*)azmalloc(sizeof(AZ::u64) * 2 * (BLOCK_SIZE / 4), AZStd::alignment_of<AZ::u64>::value);
|
||||
array2 = (AZ::u64*)azmalloc(sizeof(AZ::u64) * 2 * (10000 / 4), AZStd::alignment_of<AZ::u64>::value);
|
||||
array1 = (AZ::u64*)azmalloc(sizeof(AZ::u64) * 2 * (BLOCK_SIZE / 4), AZStd::alignment_of<AZ::Vector4>::value);
|
||||
array2 = (AZ::u64*)azmalloc(sizeof(AZ::u64) * 2 * (10000 / 4), AZStd::alignment_of<AZ::Vector4>::value);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
|
||||
@@ -171,7 +171,17 @@ namespace UnitTest
|
||||
azsnprintf(buffer, RandomStringBufferSize, "%d", m_random.GetRandom());
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
AZ::Internal::NameData* GetNameData(AZ::Name& name)
|
||||
{
|
||||
return name.m_data.get();
|
||||
}
|
||||
|
||||
void FreeMemoryFromNameData(AZ::Internal::NameData* nameData)
|
||||
{
|
||||
delete nameData;
|
||||
}
|
||||
|
||||
AZ::SimpleLcgRandom m_random;
|
||||
};
|
||||
|
||||
@@ -488,13 +498,20 @@ namespace UnitTest
|
||||
|
||||
TEST_F(NameTest, ReportLeakedNames)
|
||||
{
|
||||
AZ::Name leakedName{"hello"};
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
AZ::NameDictionary::Destroy();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
AZ::Internal::NameData* leakedNameData = nullptr;
|
||||
{
|
||||
AZ::Name leakedName{ "hello" };
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
AZ::NameDictionary::Destroy();
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
|
||||
// Create the dictionary again to avoid error in TearDown()
|
||||
AZ::NameDictionary::Create();
|
||||
leakedNameData = GetNameData(leakedName);
|
||||
|
||||
// Create the dictionary again to avoid crash when the intrusive_ptr in Name tries to access NameDictionary to free it
|
||||
AZ::NameDictionary::Create();
|
||||
}
|
||||
|
||||
FreeMemoryFromNameData(leakedNameData); // free it to avoid memory system reporting the leak
|
||||
}
|
||||
|
||||
TEST_F(NameTest, NullTerminatedTest)
|
||||
@@ -586,7 +603,7 @@ namespace UnitTest
|
||||
AZ::NameDictionary::Create();
|
||||
|
||||
// 3 threads per name effectively makes two readers and one writer (the first to run will write in the dictionary)
|
||||
RunConcurrencyTest<ThreadCreatesOneName>(AZ_TRAIT_UNIT_TEST_NAME_COUNT, 3);
|
||||
RunConcurrencyTest<ThreadCreatesOneName>(AZStd::thread::hardware_concurrency(), 3);
|
||||
}
|
||||
|
||||
TEST_F(NameTest, ConcurrencyDataTest_EachThreadCreatesOneName_HighCollisions)
|
||||
@@ -595,7 +612,7 @@ namespace UnitTest
|
||||
AZ::NameDictionary::Create();
|
||||
|
||||
// 3 threads per name effectively makes two readers and one writer (the first to run will write in the dictionary)
|
||||
RunConcurrencyTest<ThreadCreatesOneName>(AZ_TRAIT_UNIT_TEST_NAME_COUNT, 3);
|
||||
RunConcurrencyTest<ThreadCreatesOneName>(AZStd::thread::hardware_concurrency() / 2, 3);
|
||||
}
|
||||
|
||||
TEST_F(NameTest, ConcurrencyDataTest_EachThreadRepeatedlyCreatesAndReleasesOneName_NoCollision)
|
||||
@@ -620,7 +637,7 @@ namespace UnitTest
|
||||
|
||||
TEST_F(NameTest, DISABLED_NameVsStringPerf_Creation)
|
||||
{
|
||||
constexpr int CreateCount = AZ_TRAIT_UNIT_TEST_NAME_COUNT;
|
||||
constexpr int CreateCount = 1000;
|
||||
|
||||
char buffer[RandomStringBufferSize];
|
||||
|
||||
@@ -629,7 +646,7 @@ namespace UnitTest
|
||||
AZStd::sys_time_t stringTime;
|
||||
|
||||
{
|
||||
const size_t dictionaryNoiseSize = AZ_TRAIT_UNIT_TEST_NAME_COUNT;
|
||||
const size_t dictionaryNoiseSize = 1000;
|
||||
|
||||
AZStd::vector<AZ::Name> existingNames;
|
||||
existingNames.reserve(dictionaryNoiseSize);
|
||||
|
||||
@@ -1081,16 +1081,6 @@ namespace AZ
|
||||
return ResultCode::Error;
|
||||
}
|
||||
|
||||
//bound check
|
||||
//note that seeking beyond end or before beginning is system dependent
|
||||
//therefore we will define that on all platforms it is not allowed
|
||||
if (newFilePosition < 0)
|
||||
{
|
||||
AZ_TracePrintf(RemoteFileIOChannel, "RemoteFileIO::Seek(fileHandle=%u, offset=%i, type=%s) seek to a position before the begining of a file!", fileHandle, offset, type == SeekType::SeekFromCurrent ? "SeekFromCurrent" : type == SeekType::SeekFromEnd ? "SeekFromEnd" : type == SeekType::SeekFromStart ? "SeekFromStart" : "Unknown");
|
||||
REMOTEFILE_LOG_APPEND(AZStd::string::format("RemoteFileIO::Seek(fileHandle=%u, offset=%i, type=%s) seek to a position before the begining of a file!", fileHandle, offset, type == SeekType::SeekFromCurrent ? "SeekFromCurrent" : type == SeekType::SeekFromEnd ? "SeekFromEnd" : type == SeekType::SeekFromStart ? "SeekFromStart" : "Unknown").c_str());
|
||||
newFilePosition = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ::u64 fileSize = 0;
|
||||
Size(fileHandle, fileSize);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/smart_ptr/shared_ptr.h>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
|
||||
namespace Physics
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user