fbx_tests.py 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305
  1. """
  2. Copyright (c) Contributors to the Open 3D Engine Project.
  3. For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. SPDX-License-Identifier: Apache-2.0 OR MIT
  5. """
  6. import binascii
  7. from dataclasses import dataclass
  8. import logging
  9. import os
  10. from pprint import pformat
  11. import pytest
  12. import re
  13. import shutil
  14. from typing import List
  15. import warnings
  16. # Import LyTestTools
  17. import ly_test_tools.builtin.helpers as helpers
  18. from ly_test_tools.o3de import asset_processor as asset_processor_utils
  19. from ly_test_tools.o3de.asset_processor import ASSET_PROCESSOR_PLATFORM_MAP
  20. # Import fixtures
  21. from ..ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
  22. from ..ap_fixtures.ap_setup_fixture import ap_setup_fixture as ap_setup_fixture
  23. from ..ap_fixtures.ap_config_backup_fixture import ap_config_backup_fixture as ap_config_backup_fixture
  24. from ..ap_fixtures.ap_config_default_platform_fixture \
  25. import ap_config_default_platform_fixture as ap_config_default_platform_fixture
  26. # Import LyShared
  27. import ly_test_tools.o3de.pipeline_utils as utils
  28. from automatedtesting_shared import asset_database_utils as asset_db_utils
  29. logger = logging.getLogger(__name__)
  30. # Helper: variables we will use for parameter values in the test:
  31. targetProjects = ["AutomatedTesting"]
  32. # Helper: Gets a case correct version of the cache folder
  33. def get_cache_folder(asset_processor):
  34. # Make sure the folder being checked is fully lowercase.
  35. # Leave the "c" in Cache uppercase.
  36. return re.sub("ache[/\\\\](.*)", lambda m: m.group().lower(), asset_processor.project_test_cache_folder())
  37. @pytest.fixture
  38. def local_resources(request, workspace, ap_setup_fixture):
  39. ap_setup_fixture["tests_dir"] = os.path.dirname(os.path.realpath(__file__))
  40. @dataclass
  41. @pytest.mark.SUITE_sandbox
  42. class BlackboxAssetTest:
  43. test_name: str
  44. asset_folder: str
  45. override_asset_folder: str = ""
  46. scene_debug_file: str = ""
  47. override_scene_debug_file: str = ""
  48. assets: List[asset_db_utils.DBSourceAsset] = ()
  49. override_assets: List[asset_db_utils.DBSourceAsset] = ()
  50. blackbox_fbx_tests = [
  51. pytest.param(
  52. BlackboxAssetTest(
  53. test_name="OneMeshOneMaterial_RunAP_SuccessWithMatchingProducts",
  54. asset_folder="OneMeshOneMaterial",
  55. scene_debug_file="onemeshonematerial.fbx.dbgsg",
  56. assets=[
  57. asset_db_utils.DBSourceAsset(
  58. source_file_name="OneMeshOneMaterial.fbx",
  59. uuid=b"8a9164adb84859be893e18aa819438e1",
  60. jobs=[
  61. asset_db_utils.DBJob(
  62. job_key='Scene compilation',
  63. builder_guid=b'bd8bf65894854fe3830e8ec3a23c35f3',
  64. status=4,
  65. error_count=0,
  66. products=[
  67. asset_db_utils.DBProduct(
  68. product_name='onemeshonematerial/onemeshonematerial.fbx.abdata.json',
  69. sub_id=4194304,
  70. asset_type=b'd0a5e84e98664ad7a6a14d28fe7871c5'),
  71. asset_db_utils.DBProduct(
  72. product_name='onemeshonematerial/onemeshonematerial.fbx.assetinfo.dbg',
  73. sub_id=635465363,
  74. asset_type=b'48a78be7b3f244b88aa6f0607e9a75a5'),
  75. asset_db_utils.DBProduct(
  76. product_name='onemeshonematerial/onemeshonematerial.fbx.dbgsg',
  77. sub_id=2078121323,
  78. asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
  79. asset_db_utils.DBProduct(
  80. product_name='onemeshonematerial/onemeshonematerial.fbx.dbgsg.json',
  81. sub_id=1736583047,
  82. asset_type=b'4342b27e0e1449c3b3b9bcdb9a5fca23'),
  83. asset_db_utils.DBProduct(
  84. product_name='onemeshonematerial/onemeshonematerial.fbx.dbgsg.xml',
  85. sub_id=-976624731, asset_type=b'51f376140d774f369ac67ed70a0ac868'),
  86. asset_db_utils.DBProduct(
  87. product_name='onemeshonematerial/onemeshonematerial_fbx.procprefab',
  88. sub_id=-1819295853,
  89. asset_type=b'9b7c8459471e4eada3637990cc4065a9'),
  90. asset_db_utils.DBProduct(
  91. product_name='onemeshonematerial/onemeshonematerial_fbx.procprefab.json',
  92. sub_id=-1860036023,
  93. asset_type=b'00000000000000000000000000000000')
  94. ]
  95. )
  96. ]
  97. )
  98. ]
  99. ),
  100. id="32250017",
  101. marks=pytest.mark.test_case_id("C32250017"),
  102. ),
  103. pytest.param(
  104. BlackboxAssetTest(
  105. # Verifies that the soft naming convention feature with level of detail meshes works.
  106. test_name="SoftNamingLOD_RunAP_SuccessWithMatchingProducts",
  107. asset_folder="SoftNamingLOD",
  108. scene_debug_file="lodtest.fbx.dbgsg",
  109. assets=[
  110. asset_db_utils.DBSourceAsset(
  111. source_file_name="lodtest.fbx",
  112. uuid=b"44c8627fe2c25aae91fe3ff9547be3b9",
  113. jobs=[
  114. asset_db_utils.DBJob(
  115. job_key='Scene compilation',
  116. builder_guid=b'bd8bf65894854fe3830e8ec3a23c35f3',
  117. status=4,
  118. error_count=0,
  119. products=[
  120. asset_db_utils.DBProduct(
  121. product_name='softnaminglod/lodtest.fbx.abdata.json',
  122. sub_id=4194304,
  123. asset_type=b'd0a5e84e98664ad7a6a14d28fe7871c5'),
  124. asset_db_utils.DBProduct(
  125. product_name='softnaminglod/lodtest.fbx.assetinfo.dbg',
  126. sub_id=-1252475526,
  127. asset_type=b'48a78be7b3f244b88aa6f0607e9a75a5'),
  128. asset_db_utils.DBProduct(
  129. product_name='softnaminglod/lodtest.fbx.dbgsg',
  130. sub_id=1082129636,
  131. asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
  132. asset_db_utils.DBProduct(
  133. product_name='softnaminglod/lodtest.fbx.dbgsg.json',
  134. sub_id=998015244,
  135. asset_type=b'4342b27e0e1449c3b3b9bcdb9a5fca23'),
  136. asset_db_utils.DBProduct(
  137. product_name='softnaminglod/lodtest.fbx.dbgsg.xml',
  138. sub_id=1858673704,
  139. asset_type=b'51f376140d774f369ac67ed70a0ac868'),
  140. asset_db_utils.DBProduct(
  141. product_name='softnaminglod/lodtest_fbx.procprefab',
  142. sub_id=838906682,
  143. asset_type=b'9b7c8459471e4eada3637990cc4065a9'),
  144. asset_db_utils.DBProduct(
  145. product_name='softnaminglod/lodtest_fbx.procprefab.json',
  146. sub_id=-71923453,
  147. asset_type=b'00000000000000000000000000000000'
  148. )
  149. ]
  150. ),
  151. ]
  152. )
  153. ]
  154. ),
  155. id="33887870",
  156. marks=pytest.mark.test_case_id("33887870"),
  157. ),
  158. pytest.param(
  159. BlackboxAssetTest(
  160. # Verifies that the soft naming convention feature with physics proxies works.
  161. test_name="SoftNamingPhysics_RunAP_SuccessWithMatchingProducts",
  162. asset_folder="SoftNamingPhysics",
  163. scene_debug_file="physicstest.fbx.dbgsg",
  164. assets=[
  165. asset_db_utils.DBSourceAsset(
  166. source_file_name="physicstest.fbx",
  167. uuid=b"df957b7918cf5b029806c73f630fa1c8",
  168. jobs=[
  169. asset_db_utils.DBJob(
  170. job_key='Scene compilation',
  171. builder_guid=b'bd8bf65894854fe3830e8ec3a23c35f3',
  172. status=4,
  173. error_count=0,
  174. products=[
  175. asset_db_utils.DBProduct(
  176. product_name='softnamingphysics/physicstest.fbx.abdata.json',
  177. sub_id=4194304,
  178. asset_type=b'd0a5e84e98664ad7a6a14d28fe7871c5'),
  179. asset_db_utils.DBProduct(
  180. product_name='softnamingphysics/physicstest.fbx.assetinfo.dbg',
  181. sub_id=376675704,
  182. asset_type=b'48a78be7b3f244b88aa6f0607e9a75a5'),
  183. asset_db_utils.DBProduct(
  184. product_name='softnamingphysics/physicstest.fbx.dbgsg',
  185. sub_id=530659840,
  186. asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
  187. asset_db_utils.DBProduct(
  188. product_name='softnamingphysics/physicstest.fbx.dbgsg.json',
  189. sub_id=997442341,
  190. asset_type=b'4342b27e0e1449c3b3b9bcdb9a5fca23'),
  191. asset_db_utils.DBProduct(
  192. product_name='softnamingphysics/physicstest.fbx.dbgsg.xml',
  193. sub_id=1618976652,
  194. asset_type=b'51f376140d774f369ac67ed70a0ac868'),
  195. asset_db_utils.DBProduct(
  196. product_name='softnamingphysics/physicstest.fbx.pxmesh',
  197. sub_id=640975857,
  198. asset_type=b'7a2871b95eab4de0a901b0d2c6920ddb'),
  199. asset_db_utils.DBProduct(
  200. product_name='softnamingphysics/physicstest_fbx.procprefab',
  201. sub_id=651014275,
  202. asset_type=b'9b7c8459471e4eada3637990cc4065a9'),
  203. asset_db_utils.DBProduct(
  204. product_name='softnamingphysics/physicstest_fbx.procprefab.json',
  205. sub_id=1124966094,
  206. asset_type=b'00000000000000000000000000000000'
  207. )
  208. ]
  209. ),
  210. ]
  211. )
  212. ]
  213. ),
  214. ),
  215. pytest.param(
  216. BlackboxAssetTest(
  217. test_name="MultipleMeshOneMaterial_RunAP_SuccessWithMatchingProducts",
  218. asset_folder="TwoMeshOneMaterial",
  219. scene_debug_file="multiple_mesh_one_material.fbx.dbgsg",
  220. assets=[
  221. asset_db_utils.DBSourceAsset(
  222. source_file_name="multiple_mesh_one_material.fbx",
  223. uuid=b"597618fd497659a1b197a015fe47aa95",
  224. jobs=[
  225. asset_db_utils.DBJob(
  226. job_key='Scene compilation',
  227. builder_guid=b'bd8bf65894854fe3830e8ec3a23c35f3',
  228. status=4,
  229. error_count=0,
  230. products=[
  231. asset_db_utils.DBProduct(
  232. product_name='twomeshonematerial/multiple_mesh_one_material.fbx.abdata.json',
  233. sub_id=4194304,
  234. asset_type=b'd0a5e84e98664ad7a6a14d28fe7871c5'),
  235. asset_db_utils.DBProduct(
  236. product_name='twomeshonematerial/multiple_mesh_one_material.fbx.assetinfo.dbg',
  237. sub_id=-251254148,
  238. asset_type=b'48a78be7b3f244b88aa6f0607e9a75a5'),
  239. asset_db_utils.DBProduct(
  240. product_name='twomeshonematerial/multiple_mesh_one_material.fbx.dbgsg',
  241. sub_id=-599090337,
  242. asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
  243. asset_db_utils.DBProduct(
  244. product_name='twomeshonematerial/multiple_mesh_one_material.fbx.dbgsg.json',
  245. sub_id=-981232068,
  246. asset_type=b'4342b27e0e1449c3b3b9bcdb9a5fca23'),
  247. asset_db_utils.DBProduct(
  248. product_name='twomeshonematerial/multiple_mesh_one_material.fbx.dbgsg.xml',
  249. sub_id=2098803780,
  250. asset_type=b'51f376140d774f369ac67ed70a0ac868'
  251. )
  252. ]
  253. ),
  254. ]
  255. )
  256. ]
  257. ),
  258. id="34448178",
  259. marks=pytest.mark.test_case_id("C34448178"),
  260. ),
  261. pytest.param(
  262. BlackboxAssetTest(
  263. # Verifies whether multiple meshes can share linked materials
  264. test_name="MultipleMeshLinkedMaterials_RunAP_SuccessWithMatchingProducts",
  265. asset_folder="TwoMeshLinkedMaterials",
  266. scene_debug_file="multiple_mesh_linked_materials.fbx.dbgsg",
  267. assets=[
  268. asset_db_utils.DBSourceAsset(
  269. source_file_name="multiple_mesh_linked_materials.fbx",
  270. uuid=b"25d8301c2eef5dc7bded310db8ea608d",
  271. jobs=[
  272. asset_db_utils.DBJob(
  273. job_key='Scene compilation',
  274. builder_guid=b'bd8bf65894854fe3830e8ec3a23c35f3',
  275. status=4,
  276. error_count=0,
  277. products=[
  278. asset_db_utils.DBProduct(
  279. product_name='twomeshlinkedmaterials/multiple_mesh_linked_materials.fbx.abdata.json',
  280. sub_id=4194304,
  281. asset_type=b'd0a5e84e98664ad7a6a14d28fe7871c5'),
  282. asset_db_utils.DBProduct(
  283. product_name='twomeshlinkedmaterials/multiple_mesh_linked_materials.fbx.assetinfo.dbg',
  284. sub_id=1774684099,
  285. asset_type=b'48a78be7b3f244b88aa6f0607e9a75a5'),
  286. asset_db_utils.DBProduct(
  287. product_name='twomeshlinkedmaterials/multiple_mesh_linked_materials.fbx.dbgsg',
  288. sub_id=399409097,
  289. asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
  290. asset_db_utils.DBProduct(
  291. product_name='twomeshlinkedmaterials/multiple_mesh_linked_materials.fbx.dbgsg.json',
  292. sub_id=-977002611,
  293. asset_type=b'4342b27e0e1449c3b3b9bcdb9a5fca23'),
  294. asset_db_utils.DBProduct(
  295. product_name='twomeshlinkedmaterials/multiple_mesh_linked_materials.fbx.dbgsg.xml',
  296. sub_id=-1473507434,
  297. asset_type=b'51f376140d774f369ac67ed70a0ac868'),
  298. asset_db_utils.DBProduct(
  299. product_name='twomeshlinkedmaterials/multiple_mesh_linked_materials_fbx.procprefab',
  300. sub_id=-859152125,
  301. asset_type=b'9b7c8459471e4eada3637990cc4065a9'),
  302. asset_db_utils.DBProduct(
  303. product_name='twomeshlinkedmaterials/multiple_mesh_linked_materials_fbx.procprefab.json',
  304. sub_id=-841089725,
  305. asset_type=b'00000000000000000000000000000000'
  306. )
  307. ]
  308. ),
  309. ]
  310. )
  311. ]
  312. ),
  313. id="32250018",
  314. marks=pytest.mark.test_case_id("C32250018"),
  315. ),
  316. pytest.param(
  317. BlackboxAssetTest(
  318. # Verifies a mesh with multiple materials
  319. test_name="SingleMeshMultipleMaterials_RunAP_SuccessWithMatchingProducts",
  320. asset_folder="OneMeshMultipleMaterials",
  321. scene_debug_file="single_mesh_multiple_materials.fbx.dbgsg",
  322. assets=[
  323. asset_db_utils.DBSourceAsset(
  324. source_file_name="single_mesh_multiple_materials.fbx",
  325. uuid=b"f08fd585dfa35881b4bf86637da5e858",
  326. jobs=[
  327. asset_db_utils.DBJob(
  328. job_key='Scene compilation',
  329. builder_guid=b'bd8bf65894854fe3830e8ec3a23c35f3',
  330. status=4,
  331. error_count=0,
  332. products=[
  333. asset_db_utils.DBProduct(
  334. product_name='onemeshmultiplematerials/single_mesh_multiple_materials.fbx.abdata.json',
  335. sub_id=4194304,
  336. asset_type=b'd0a5e84e98664ad7a6a14d28fe7871c5'),
  337. asset_db_utils.DBProduct(
  338. product_name='onemeshmultiplematerials/single_mesh_multiple_materials.fbx.assetinfo.dbg',
  339. sub_id=-2146161009,
  340. asset_type=b'48a78be7b3f244b88aa6f0607e9a75a5'),
  341. asset_db_utils.DBProduct(
  342. product_name='onemeshmultiplematerials/single_mesh_multiple_materials.fbx.dbgsg',
  343. sub_id=82607561,
  344. asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
  345. asset_db_utils.DBProduct(
  346. product_name='onemeshmultiplematerials/single_mesh_multiple_materials.fbx.dbgsg.json',
  347. sub_id=72739255,
  348. asset_type=b'4342b27e0e1449c3b3b9bcdb9a5fca23'),
  349. asset_db_utils.DBProduct(
  350. product_name='onemeshmultiplematerials/single_mesh_multiple_materials.fbx.dbgsg.xml',
  351. sub_id=-763826724,
  352. asset_type=b'51f376140d774f369ac67ed70a0ac868'),
  353. asset_db_utils.DBProduct(
  354. product_name='onemeshmultiplematerials/single_mesh_multiple_materials_fbx.procprefab',
  355. sub_id=1496946180,
  356. asset_type=b'9b7c8459471e4eada3637990cc4065a9'),
  357. asset_db_utils.DBProduct(
  358. product_name='onemeshmultiplematerials/single_mesh_multiple_materials_fbx.procprefab.json',
  359. sub_id=-537346917,
  360. asset_type=b'00000000000000000000000000000000'
  361. )
  362. ]
  363. ),
  364. ]
  365. )
  366. ]
  367. ),
  368. id="32250020",
  369. marks=pytest.mark.test_case_id("C32250020"),
  370. ),
  371. pytest.param(
  372. BlackboxAssetTest(
  373. test_name="MeshWithVertexColors_RunAP_SuccessWithMatchingProducts",
  374. asset_folder="VertexColor",
  375. scene_debug_file="vertexcolor.fbx.dbgsg",
  376. assets=[
  377. asset_db_utils.DBSourceAsset(
  378. source_file_name="VertexColor.fbx",
  379. uuid=b"207e7e1540785a26b064e9be67361cdf",
  380. jobs=[
  381. asset_db_utils.DBJob(
  382. job_key='Scene compilation',
  383. builder_guid=b'bd8bf65894854fe3830e8ec3a23c35f3',
  384. status=4,
  385. error_count=0,
  386. products=[
  387. asset_db_utils.DBProduct(
  388. product_name='vertexcolor/vertexcolor.fbx.abdata.json',
  389. sub_id=4194304,
  390. asset_type=b'd0a5e84e98664ad7a6a14d28fe7871c5'),
  391. asset_db_utils.DBProduct(
  392. product_name='vertexcolor/vertexcolor.fbx.assetinfo.dbg',
  393. sub_id=-684486226,
  394. asset_type=b'48a78be7b3f244b88aa6f0607e9a75a5'),
  395. asset_db_utils.DBProduct(
  396. product_name='vertexcolor/vertexcolor.fbx.dbgsg',
  397. sub_id=-501404951,
  398. asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
  399. asset_db_utils.DBProduct(
  400. product_name='vertexcolor/vertexcolor.fbx.dbgsg.json',
  401. sub_id=1580896704,
  402. asset_type=b'4342b27e0e1449c3b3b9bcdb9a5fca23'),
  403. asset_db_utils.DBProduct(
  404. product_name='vertexcolor/vertexcolor.fbx.dbgsg.xml',
  405. sub_id=-2021002009,
  406. asset_type=b'51f376140d774f369ac67ed70a0ac868'),
  407. asset_db_utils.DBProduct(
  408. product_name='vertexcolor/vertexcolor_fbx.procprefab',
  409. sub_id=604991654,
  410. asset_type=b'9b7c8459471e4eada3637990cc4065a9'),
  411. asset_db_utils.DBProduct(
  412. product_name='vertexcolor/vertexcolor_fbx.procprefab.json',
  413. sub_id=-1669533680,
  414. asset_type=b'00000000000000000000000000000000'
  415. )
  416. ]
  417. ),
  418. ]
  419. )
  420. ]
  421. ),
  422. id="35796285",
  423. marks=pytest.mark.test_case_id("C35796285"),
  424. ),
  425. pytest.param(
  426. BlackboxAssetTest(
  427. test_name="MotionTest_RunAP_SuccessWithMatchingProducts",
  428. asset_folder="Motion",
  429. scene_debug_file="jack_idle_aim_zup.fbx.dbgsg",
  430. assets=[
  431. asset_db_utils.DBSourceAsset(
  432. source_file_name="Jack_Idle_Aim_ZUp.fbx",
  433. uuid=b"eda904ae0e145f8b973d57fc5809918b",
  434. jobs=[
  435. asset_db_utils.DBJob(
  436. job_key='Scene compilation',
  437. builder_guid=b'bd8bf65894854fe3830e8ec3a23c35f3',
  438. status=4,
  439. error_count=0,
  440. products=[
  441. asset_db_utils.DBProduct(
  442. product_name='motion/jack_idle_aim_zup.fbx.abdata.json',
  443. sub_id=4194304,
  444. asset_type=b'd0a5e84e98664ad7a6a14d28fe7871c5'),
  445. asset_db_utils.DBProduct(
  446. product_name='motion/jack_idle_aim_zup.fbx.assetinfo.dbg',
  447. sub_id=-1090444673,
  448. asset_type=b'48a78be7b3f244b88aa6f0607e9a75a5'),
  449. asset_db_utils.DBProduct(
  450. product_name='motion/jack_idle_aim_zup.fbx.dbgsg',
  451. sub_id=-1042666277,
  452. asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
  453. asset_db_utils.DBProduct(
  454. product_name='motion/jack_idle_aim_zup.fbx.dbgsg.json',
  455. sub_id=-290748690,
  456. asset_type=b'4342b27e0e1449c3b3b9bcdb9a5fca23'),
  457. asset_db_utils.DBProduct(
  458. product_name='motion/jack_idle_aim_zup.fbx.dbgsg.xml',
  459. sub_id=444631267,
  460. asset_type=b'51f376140d774f369ac67ed70a0ac868'),
  461. asset_db_utils.DBProduct(
  462. product_name='motion/jack_idle_aim_zup.motion',
  463. sub_id=186392073,
  464. asset_type=b'00494b8e75784ba28b28272e90680787'
  465. ),
  466. asset_db_utils.DBProduct(
  467. product_name='motion/jack_idle_aim_zup_fbx.procprefab',
  468. sub_id=1049691217,
  469. asset_type=b'9b7c8459471e4eada3637990cc4065a9'
  470. ),
  471. asset_db_utils.DBProduct(
  472. product_name='motion/jack_idle_aim_zup_fbx.procprefab.json',
  473. sub_id=-980081481,
  474. asset_type=b'00000000000000000000000000000000'
  475. )
  476. ]
  477. ),
  478. ]
  479. )
  480. ]
  481. ),
  482. ),
  483. pytest.param(
  484. BlackboxAssetTest(
  485. test_name="ShaderBall_RunAP_SuccessWithMatchingProducts",
  486. asset_folder="ShaderBall",
  487. scene_debug_file="shaderball.fbx.dbgsg",
  488. assets=[
  489. asset_db_utils.DBSourceAsset(
  490. source_file_name="shaderball.fbx",
  491. uuid=b"48181ba8038e5193997540fc8dffb06d",
  492. jobs=[
  493. asset_db_utils.DBJob(
  494. job_key='Scene compilation',
  495. builder_guid=b'bd8bf65894854fe3830e8ec3a23c35f3',
  496. status=4,
  497. error_count=0,
  498. products=[
  499. asset_db_utils.DBProduct(
  500. product_name='shaderball/shaderball.fbx.abdata.json',
  501. sub_id=4194304,
  502. asset_type=b'd0a5e84e98664ad7a6a14d28fe7871c5'),
  503. asset_db_utils.DBProduct(
  504. product_name='shaderball/shaderball.fbx.assetinfo.dbg',
  505. sub_id=2366451,
  506. asset_type=b'48a78be7b3f244b88aa6f0607e9a75a5'),
  507. asset_db_utils.DBProduct(
  508. product_name='shaderball/shaderball.fbx.dbgsg',
  509. sub_id=919030955,
  510. asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
  511. asset_db_utils.DBProduct(
  512. product_name='shaderball/shaderball.fbx.dbgsg.json',
  513. sub_id=-1710127594,
  514. asset_type=b'4342b27e0e1449c3b3b9bcdb9a5fca23'),
  515. asset_db_utils.DBProduct(
  516. product_name='shaderball/shaderball.fbx.dbgsg.xml',
  517. sub_id=-1137683506,
  518. asset_type=b'51f376140d774f369ac67ed70a0ac868'),
  519. asset_db_utils.DBProduct(
  520. product_name='shaderball/shaderball_fbx.procprefab',
  521. sub_id=-1501914312,
  522. asset_type=b'9b7c8459471e4eada3637990cc4065a9'),
  523. asset_db_utils.DBProduct(
  524. product_name='shaderball/shaderball_fbx.procprefab.json',
  525. sub_id=-1464074454,
  526. asset_type=b'00000000000000000000000000000000'
  527. ),
  528. ]
  529. ),
  530. ]
  531. )
  532. ]
  533. ),
  534. ),
  535. pytest.param(
  536. BlackboxAssetTest(
  537. test_name="cubewithline_RunAP_CubeOutputsWithoutLine",
  538. asset_folder="cubewithline",
  539. scene_debug_file="cubewithline.fbx.dbgsg",
  540. assets=[
  541. asset_db_utils.DBSourceAsset(
  542. source_file_name="cubewithline.fbx",
  543. uuid=b'1ee8fbf7c1f25b8399395a112e51906c',
  544. jobs=[
  545. asset_db_utils.DBJob(
  546. job_key='Scene compilation',
  547. builder_guid=b'bd8bf65894854fe3830e8ec3a23c35f3',
  548. status=4,
  549. error_count=0,
  550. products=[
  551. asset_db_utils.DBProduct(
  552. product_name='cubewithline/cubewithline.fbx.abdata.json',
  553. sub_id=4194304,
  554. asset_type=b'd0a5e84e98664ad7a6a14d28fe7871c5'),
  555. asset_db_utils.DBProduct(
  556. product_name='cubewithline/cubewithline.fbx.assetinfo.dbg',
  557. sub_id=705480985,
  558. asset_type=b'48a78be7b3f244b88aa6f0607e9a75a5'),
  559. asset_db_utils.DBProduct(
  560. product_name='cubewithline/cubewithline.fbx.dbgsg',
  561. sub_id=25987353,
  562. asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
  563. asset_db_utils.DBProduct(
  564. product_name='cubewithline/cubewithline.fbx.dbgsg.json',
  565. sub_id=-1971624352,
  566. asset_type=b'4342b27e0e1449c3b3b9bcdb9a5fca23'),
  567. asset_db_utils.DBProduct(
  568. product_name='cubewithline/cubewithline.fbx.dbgsg.xml',
  569. sub_id=975809434,
  570. asset_type=b'51f376140d774f369ac67ed70a0ac868'),
  571. asset_db_utils.DBProduct(
  572. product_name='cubewithline/cubewithline_fbx.procprefab',
  573. sub_id=1800163200,
  574. asset_type=b'9b7c8459471e4eada3637990cc4065a9'),
  575. asset_db_utils.DBProduct(
  576. product_name='cubewithline/cubewithline_fbx.procprefab.json',
  577. sub_id=2139660816,
  578. asset_type=b'00000000000000000000000000000000'
  579. ),
  580. ]
  581. ),
  582. ]
  583. )
  584. ]
  585. ),
  586. ),
  587. pytest.param(
  588. BlackboxAssetTest(
  589. test_name="MorphTargetOneMaterial_RunAP_SuccessWithMatchingProducts",
  590. asset_folder="MorphTargetOneMaterial",
  591. scene_debug_file="morphtargetonematerial.fbx.dbgsg",
  592. assets=[
  593. asset_db_utils.DBSourceAsset(
  594. source_file_name="morphtargetonematerial.fbx",
  595. uuid=b'6f2c17db3f4a5be8bcd2bece01c92f6d',
  596. jobs=[
  597. asset_db_utils.DBJob(
  598. job_key='Scene compilation',
  599. builder_guid=b'bd8bf65894854fe3830e8ec3a23c35f3',
  600. status=4,
  601. error_count=0,
  602. products=[
  603. asset_db_utils.DBProduct(
  604. product_name='morphtargetonematerial/morphtargetonematerial.actor',
  605. sub_id=-999339669,
  606. asset_type=b'f67cc648ea51464c9f5d4a9ce41a7f86'),
  607. asset_db_utils.DBProduct(
  608. product_name='morphtargetonematerial/morphtargetonematerial.fbx.abdata.json',
  609. sub_id=4194304,
  610. asset_type=b'd0a5e84e98664ad7a6a14d28fe7871c5'),
  611. asset_db_utils.DBProduct(
  612. product_name='morphtargetonematerial/morphtargetonematerial.fbx.assetinfo.dbg',
  613. sub_id=726384549,
  614. asset_type=b'48a78be7b3f244b88aa6f0607e9a75a5'),
  615. asset_db_utils.DBProduct(
  616. product_name='morphtargetonematerial/morphtargetonematerial.fbx.dbgsg',
  617. sub_id=1620685182,
  618. asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
  619. asset_db_utils.DBProduct(
  620. product_name='morphtargetonematerial/morphtargetonematerial.fbx.dbgsg.json',
  621. sub_id=1253137975,
  622. asset_type=b'4342b27e0e1449c3b3b9bcdb9a5fca23'),
  623. asset_db_utils.DBProduct(
  624. product_name='morphtargetonematerial/morphtargetonematerial.fbx.dbgsg.xml',
  625. sub_id=-340185820,
  626. asset_type=b'51f376140d774f369ac67ed70a0ac868'),
  627. asset_db_utils.DBProduct(
  628. product_name='morphtargetonematerial/morphtargetonematerial.motion',
  629. sub_id=692653652,
  630. asset_type=b'00494b8e75784ba28b28272e90680787'),
  631. ]
  632. ),
  633. ]
  634. )
  635. ]
  636. ),
  637. ),
  638. pytest.param(
  639. BlackboxAssetTest(
  640. test_name="MorphTargetTwoMaterials_RunAP_SuccessWithMatchingProducts",
  641. asset_folder="MorphTargetTwoMaterials",
  642. scene_debug_file="morphtargettwomaterials.fbx.dbgsg",
  643. assets=[
  644. asset_db_utils.DBSourceAsset(
  645. source_file_name="morphtargettwomaterials.fbx",
  646. uuid=b'37c55eedd26658a4a6f7cbe2bec267d7',
  647. jobs=[
  648. asset_db_utils.DBJob(
  649. job_key='Scene compilation',
  650. builder_guid=b'bd8bf65894854fe3830e8ec3a23c35f3',
  651. status=4,
  652. error_count=0,
  653. products=[
  654. asset_db_utils.DBProduct(
  655. product_name='morphtargettwomaterials/morphtargettwomaterials.actor',
  656. sub_id=-557664045,
  657. asset_type=b'f67cc648ea51464c9f5d4a9ce41a7f86'),
  658. asset_db_utils.DBProduct(
  659. product_name='morphtargettwomaterials/morphtargettwomaterials.fbx.abdata.json',
  660. sub_id=4194304,
  661. asset_type=b'd0a5e84e98664ad7a6a14d28fe7871c5'),
  662. asset_db_utils.DBProduct(
  663. product_name='morphtargettwomaterials/morphtargettwomaterials.fbx.assetinfo.dbg',
  664. sub_id=-1807090167,
  665. asset_type=b'48a78be7b3f244b88aa6f0607e9a75a5'),
  666. asset_db_utils.DBProduct(
  667. product_name='morphtargettwomaterials/morphtargettwomaterials.fbx.dbgsg',
  668. sub_id=-303201013,
  669. asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
  670. asset_db_utils.DBProduct(
  671. product_name='morphtargettwomaterials/morphtargettwomaterials.fbx.dbgsg.json',
  672. sub_id=-1396790465,
  673. asset_type=b'4342b27e0e1449c3b3b9bcdb9a5fca23'),
  674. asset_db_utils.DBProduct(
  675. product_name='morphtargettwomaterials/morphtargettwomaterials.fbx.dbgsg.xml',
  676. sub_id=-1157438659,
  677. asset_type=b'51f376140d774f369ac67ed70a0ac868'),
  678. asset_db_utils.DBProduct(
  679. product_name='morphtargettwomaterials/morphtargettwomaterials.motion',
  680. sub_id=1527116269,
  681. asset_type=b'00494b8e75784ba28b28272e90680787'),
  682. ]
  683. ),
  684. ]
  685. )
  686. ]
  687. ),
  688. ),
  689. pytest.param(
  690. BlackboxAssetTest(
  691. test_name="StingRayPBRAsset_PBRMaterialConvertion_AutoAssignOnProcessing",
  692. asset_folder="PBRMaterialConvertion",
  693. scene_debug_file="nagamaki1.fbx.dbgsg",
  694. assets=[
  695. asset_db_utils.DBSourceAsset(
  696. source_file_name="nagamaki1.fbx",
  697. uuid=b'9dbee85b454d53cf894b90a9ceb1430a',
  698. jobs=[
  699. asset_db_utils.DBJob(
  700. job_key='Scene compilation',
  701. builder_guid=b'bd8bf65894854fe3830e8ec3a23c35f3',
  702. status=4,
  703. error_count=0,
  704. products=[
  705. asset_db_utils.DBProduct(
  706. product_name='pbrmaterialconvertion/nagamaki1.fbx.abdata.json',
  707. sub_id=4194304,
  708. asset_type=b'd0a5e84e98664ad7a6a14d28fe7871c5'),
  709. asset_db_utils.DBProduct(
  710. product_name='pbrmaterialconvertion/nagamaki1.fbx.assetinfo.dbg',
  711. sub_id=-799018249,
  712. asset_type=b'48a78be7b3f244b88aa6f0607e9a75a5'),
  713. asset_db_utils.DBProduct(
  714. product_name='pbrmaterialconvertion/nagamaki1.fbx.dbgsg',
  715. sub_id=-1473851462,
  716. asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
  717. asset_db_utils.DBProduct(
  718. product_name='pbrmaterialconvertion/nagamaki1.fbx.dbgsg.json',
  719. sub_id=-1739655040,
  720. asset_type=b'4342b27e0e1449c3b3b9bcdb9a5fca23'),
  721. asset_db_utils.DBProduct(
  722. product_name='pbrmaterialconvertion/nagamaki1.fbx.dbgsg.xml',
  723. sub_id=-2094917174,
  724. asset_type=b'51f376140d774f369ac67ed70a0ac868'),
  725. asset_db_utils.DBProduct(
  726. product_name='pbrmaterialconvertion/nagamaki1_fbx.procprefab',
  727. sub_id=-1637699071,
  728. asset_type=b'9b7c8459471e4eada3637990cc4065a9'),
  729. asset_db_utils.DBProduct(
  730. product_name='pbrmaterialconvertion/nagamaki1_fbx.procprefab.json',
  731. sub_id=-602240166,
  732. asset_type=b'00000000000000000000000000000000'
  733. )
  734. ]
  735. )
  736. ]
  737. )
  738. ]
  739. )
  740. )
  741. ]
  742. blackbox_fbx_special_tests = [
  743. pytest.param(
  744. BlackboxAssetTest(
  745. test_name="MultipleMeshMultipleMaterial_MultipleAssetInfo_RunAP_SuccessWithMatchingProducts",
  746. asset_folder="TwoMeshTwoMaterial",
  747. override_asset_folder="OverrideAssetInfoForTwoMeshTwoMaterial",
  748. scene_debug_file="multiple_mesh_multiple_material.fbx.dbgsg",
  749. override_scene_debug_file="multiple_mesh_multiple_material_override.fbx.dbgsg",
  750. assets=[
  751. asset_db_utils.DBSourceAsset(
  752. source_file_name="multiple_mesh_multiple_material.fbx",
  753. uuid=b"b5915fb874af5c8a866ccabbddb57595",
  754. jobs=[
  755. asset_db_utils.DBJob(
  756. job_key='Scene compilation',
  757. builder_guid=b'bd8bf65894854fe3830e8ec3a23c35f3',
  758. status=4,
  759. error_count=0,
  760. products=[
  761. asset_db_utils.DBProduct(
  762. product_name='twomeshtwomaterial/multiple_mesh_multiple_material.fbx.abdata.json',
  763. sub_id=4194304,
  764. asset_type=b'd0a5e84e98664ad7a6a14d28fe7871c5'),
  765. asset_db_utils.DBProduct(
  766. product_name='twomeshtwomaterial/multiple_mesh_multiple_material.fbx.assetinfo.dbg',
  767. sub_id=-1020411616,
  768. asset_type=b'48a78be7b3f244b88aa6f0607e9a75a5'),
  769. asset_db_utils.DBProduct(
  770. product_name='twomeshtwomaterial/multiple_mesh_multiple_material.fbx.dbgsg',
  771. sub_id=2097661127,
  772. asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
  773. asset_db_utils.DBProduct(
  774. product_name='twomeshtwomaterial/multiple_mesh_multiple_material.fbx.dbgsg.json',
  775. sub_id=-1745484895,
  776. asset_type=b'4342b27e0e1449c3b3b9bcdb9a5fca23'),
  777. asset_db_utils.DBProduct(
  778. product_name='twomeshtwomaterial/multiple_mesh_multiple_material.fbx.dbgsg.xml',
  779. sub_id=694850264,
  780. asset_type=b'51f376140d774f369ac67ed70a0ac868'
  781. )
  782. ]
  783. ),
  784. ]
  785. )
  786. ],
  787. override_assets=[
  788. asset_db_utils.DBSourceAsset(
  789. source_file_name="multiple_mesh_multiple_material.fbx",
  790. uuid=b"b5915fb874af5c8a866ccabbddb57595",
  791. jobs=[
  792. asset_db_utils.DBJob(
  793. job_key='Scene compilation',
  794. builder_guid=b'bd8bf65894854fe3830e8ec3a23c35f3',
  795. status=4,
  796. error_count=0,
  797. products=[
  798. asset_db_utils.DBProduct(
  799. product_name='twomeshtwomaterial/multiple_mesh_multiple_material.fbx.abdata.json',
  800. sub_id=4194304,
  801. asset_type=b'd0a5e84e98664ad7a6a14d28fe7871c5'),
  802. asset_db_utils.DBProduct(
  803. product_name='twomeshtwomaterial/multiple_mesh_multiple_material.fbx.assetinfo.dbg',
  804. sub_id=-1020411616,
  805. asset_type=b'48a78be7b3f244b88aa6f0607e9a75a5'),
  806. asset_db_utils.DBProduct(
  807. product_name='twomeshtwomaterial/multiple_mesh_multiple_material.fbx.dbgsg',
  808. sub_id=2097661127,
  809. asset_type=b'07f289d14dc74c4094b40a53bbcb9f0b'),
  810. asset_db_utils.DBProduct(
  811. product_name='twomeshtwomaterial/multiple_mesh_multiple_material.fbx.dbgsg.json',
  812. sub_id=-1745484895,
  813. asset_type=b'4342b27e0e1449c3b3b9bcdb9a5fca23'),
  814. asset_db_utils.DBProduct(
  815. product_name='twomeshtwomaterial/multiple_mesh_multiple_material.fbx.dbgsg.xml',
  816. sub_id=694850264,
  817. asset_type=b'51f376140d774f369ac67ed70a0ac868'
  818. )
  819. ]
  820. ),
  821. ]
  822. )
  823. ]
  824. ),
  825. id="34389075",
  826. marks=pytest.mark.test_case_id("C34389075"),
  827. ),
  828. ]
  829. @pytest.mark.usefixtures("asset_processor")
  830. @pytest.mark.usefixtures("ap_setup_fixture")
  831. @pytest.mark.usefixtures("local_resources")
  832. @pytest.mark.parametrize("project", targetProjects)
  833. @pytest.mark.assetpipeline
  834. @pytest.mark.SUITE_sandbox
  835. class TestsFBX_AllPlatforms(object):
  836. @pytest.mark.BAT
  837. @pytest.mark.parametrize("blackbox_param", blackbox_fbx_tests)
  838. def test_FBXBlackboxTest_SourceFiles_Processed_ResultInExpectedProducts(self, workspace, ap_setup_fixture,
  839. asset_processor, project, blackbox_param):
  840. """
  841. Please see run_fbx_test(...) for details
  842. Test Steps:
  843. 1. Determine if blackbox is set to none
  844. 2. Run FBX Test
  845. """
  846. if blackbox_param == None:
  847. return
  848. self.run_fbx_test(workspace, ap_setup_fixture, asset_processor, project, blackbox_param)
  849. @pytest.mark.BAT
  850. @pytest.mark.parametrize("blackbox_param", blackbox_fbx_special_tests)
  851. def test_FBXBlackboxTest_AssetInfoModified_AssetReprocessed_ResultInExpectedProducts(
  852. self, workspace, ap_setup_fixture, asset_processor, project, blackbox_param):
  853. """
  854. Please see run_fbx_test(...) for details
  855. Test Steps:
  856. 1. Determine if blackbox is set to none
  857. 2. Run FBX Test
  858. 2. Re-run FBX test and validate the information in override assets
  859. """
  860. if blackbox_param == None:
  861. return
  862. self.run_fbx_test(workspace, ap_setup_fixture,
  863. asset_processor, project, blackbox_param)
  864. # Run the test again and validate the information in the override assets
  865. self.run_fbx_test(workspace, ap_setup_fixture,
  866. asset_processor, project, blackbox_param, True)
  867. @staticmethod
  868. def populate_asset_info(workspace, project, assets):
  869. # Check that each given source asset resulted in the expected jobs and products.
  870. for expected_source in assets:
  871. for job in expected_source.jobs:
  872. job.platform = ASSET_PROCESSOR_PLATFORM_MAP[workspace.asset_processor_platform]
  873. for product in job.products:
  874. product.product_name = job.platform + "/" \
  875. + product.product_name
  876. @staticmethod
  877. def trim_floating_point_values_from_same_length_lists(diff_actual: List[str], diff_expected: List[str],
  878. actual_file_path:str, expected_file_path:str) -> (List[str], List[str]):
  879. # Linux and non-Linux platforms generate slightly different values for floating points.
  880. # Long term, it will be important to stabilize the output of product assets, because this difference
  881. # will cause problems: If an Android asset is generated from a Linux versus Windows machine, for example,
  882. # it will be different when it's not expected to be different.
  883. # In the short term, it's not something addressed yet, so instead this function will
  884. # truncate any floating point values to be short enough to be stable. It will then emit a warning, to help keep track of this issue.
  885. # Get the initial list lengths, so they can be compared to the list lengths later to see if any differences were
  886. # removed due to floating point value drift.
  887. initial_diff_actual_len = len(diff_actual)
  888. initial_diff_expected_len = len(diff_expected)
  889. # This function requires the two lists to be equal length.
  890. assert initial_diff_actual_len == initial_diff_expected_len, "Scene mismatch - different line counts"
  891. # Floating point values between Linux and Windows aren't consistent yet. For now, trim these values for comparison.
  892. # Store the trimmed values and compare the un-trimmed values separately, emitting warnings.
  893. # Trim decimals from the lists to be compared, if any where found, re-compare and generate new lists.
  894. DECIMAL_DIGITS_TO_PRESERVE = 3
  895. floating_point_regex = re.compile(f"(.*?-?[0-9]+\\.[0-9]{{{DECIMAL_DIGITS_TO_PRESERVE},{DECIMAL_DIGITS_TO_PRESERVE}}})[0-9]+(.*)")
  896. for index, diff_actual_line in enumerate(diff_actual):
  897. # Loop, because there may be multiple floats on the same line.
  898. while True:
  899. match_result = floating_point_regex.match(diff_actual[index])
  900. if not match_result:
  901. break
  902. diff_actual[index] = f"{match_result.group(1)}{match_result.group(2)}"
  903. # diff_actual and diff_expected have the same line count, so they can both be checked here
  904. while True:
  905. match_result = floating_point_regex.match(diff_expected[index])
  906. if not match_result:
  907. break
  908. diff_expected[index] = f"{match_result.group(1)}{match_result.group(2)}"
  909. # Re-run the diff now that floating point values have been truncated.
  910. diff_actual, diff_expected = utils.get_differences_between_lists(diff_actual, diff_expected)
  911. # If both lists are now empty, then the only differences between the two scene files were floating point drift.
  912. if (diff_actual == None and diff_expected == None) or (len(diff_actual) == 0 and len(diff_actual) == 0):
  913. warnings.warn(f"Floating point drift detected between {expected_file_path} and {actual_file_path}.")
  914. return diff_actual, diff_expected
  915. # Something has gone wrong if the lists are now somehow different lengths after the comparison.
  916. assert len(diff_actual) == len(diff_expected), "Scene mismatch - different line counts after truncation"
  917. # If some entries were removed from both lists but not all, then there was some floating point drift causing
  918. # differences to appear between the scene files. Provide a warning on that so it can be tracked, then
  919. # continue on to the next set of list comparisons.
  920. if len(diff_actual) != initial_diff_actual_len or len(diff_expected) != initial_diff_expected_len:
  921. warnings.warn(f"Floating point drift detected between {expected_file_path} and {actual_file_path}.")
  922. return diff_actual, diff_expected
  923. @staticmethod
  924. def scan_scene_debug_xml_file_for_issues(diff_actual: List[str], diff_expected: List[str],
  925. actual_hashes_to_skip: List[str], expected_hashes_to_skip: List[str]) -> (List[str], List[str]):
  926. # Given the differences between the newly generated XML file versus the last known good, and the lists of hashes that were
  927. # skipped in the non-XML debug scene graph comparison, check if the differences in the XML file are the same as the hashes
  928. # that were skipped in the non-XML file.
  929. # Hashes are generated differently on Linux than other platforms right now. Long term this is a problem, it will mean that
  930. # product assets generated on Linux are different than other platforms. Short term, this is a known issue. This automated
  931. # test handles this by emitting warnings when this occurs.
  932. # If the difference count doesn't match the non-XML file, then it's not just hash mis-matches in the XML file, and the test has failed.
  933. assert len(expected_hashes_to_skip) == len(diff_expected), "Scene mismatch"
  934. assert len(actual_hashes_to_skip) == len(diff_actual), "Scene mismatch"
  935. # This test did a simple line by line comparison, and didn't actually load the XML data into a graph to compare.
  936. # Which means that the relevant info for this field to make it clear that it is a hash and not another number is not immediately available.
  937. # So instead, extract the number and compare it to the known list of hashes.
  938. # If this regex fails or the number isn't in the hash list, then it means this is a non-hash difference and should cause a test failure.
  939. # Otherwise, if it's just a hash difference, it can be a warning for now, while the information being hashed is not stable across platforms.
  940. xml_number_regex = re.compile('.*<Class name="AZ::u64" field="m_data" value="([0-9]*)" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"\\/>')
  941. for list_entry in diff_actual:
  942. match_result = xml_number_regex.match(list_entry)
  943. assert match_result, "Scene mismatch"
  944. data_value = match_result.group(1)
  945. # This value doesn't match the list of known hash differences, so mark this test as failed.
  946. assert (data_value in actual_hashes_to_skip), "Scene mismatch"
  947. for list_entry in diff_expected:
  948. match_result = xml_number_regex.match(list_entry)
  949. assert match_result, "Scene mismatch"
  950. data_value = match_result.group(1)
  951. # This value doesn't match the list of known hash differences, so mark this test as failed.
  952. assert (data_value in expected_hashes_to_skip), "Scene mismatch"
  953. return expected_hashes_to_skip, actual_hashes_to_skip
  954. @staticmethod
  955. def scan_scene_debug_scene_graph_file_differences_for_issues(diff_actual: List[str], diff_expected: List[str],
  956. actual_file_path:str, expected_file_path:str) -> (List[str], List[str]):
  957. # Given the set of differences between two debug scene graph files, check for any known issues and emit warnings.
  958. # For unknown issues, fail the test. This primarily checks for hashes that are different.
  959. # Right now, hash generation is sometimes different on Linux from other platforms, and the test assets were generated on Windows,
  960. # so the hashes may be different when run on Linux. Also, it's been a pain point to need to re-generate debug scene graphs
  961. # when small changes occur in the scenes. This layer of data changing hasn't been causing issues yet, and is caught by other
  962. # automated tests focused on the specific set of data. This automated test is to verify that the basic structure of the scene
  963. # is the same with each run.
  964. diff_actual_hashes_removed = []
  965. diff_expected_hashes_removed = []
  966. hash_regex = re.compile("(.*Hash: )([0-9]*)")
  967. actual_hashes = []
  968. expected_hashes = []
  969. for list_entry in diff_actual:
  970. match_result = hash_regex.match(list_entry)
  971. assert match_result, "Scene mismatch"
  972. diff_actual_hashes_removed.append(match_result.group(1))
  973. actual_hashes.append(match_result.group(2))
  974. for list_entry in diff_expected:
  975. match_result = hash_regex.match(list_entry)
  976. assert match_result, "Scene mismatch"
  977. diff_expected_hashes_removed.append(match_result.group(1))
  978. expected_hashes.append(match_result.group(2))
  979. hashes_removed_diffs_identical = utils.compare_lists(diff_actual_hashes_removed, diff_expected_hashes_removed)
  980. # If, after removing all of the hash values, the lists are now identical, emit a warning.
  981. if hashes_removed_diffs_identical == True:
  982. warnings.warn(f"Hash values no longer match for debug scene graph between files {expected_file_path} and {actual_file_path}")
  983. return expected_hashes, actual_hashes
  984. @staticmethod
  985. def compare_scene_debug_file(asset_processor, expected_file_path: str, actual_file_path: str,
  986. expected_hashes_to_skip: List[str] = None, actual_hashes_to_skip: List[str] = None):
  987. # Given the paths to the debug scene graph generated by re-processing the test scene file and the path to the
  988. # last known good debug scene graph for that file, load both debug scene graphs into memory and scan them for differences.
  989. # Warns on known issues, and fails on unknown issues.
  990. debug_graph_path = os.path.join(get_cache_folder(asset_processor), actual_file_path)
  991. expected_debug_graph_path = os.path.join(asset_processor.project_test_source_folder(), "SceneDebug", expected_file_path)
  992. logger.info(f"Parsing scene graph: {debug_graph_path}")
  993. with open(debug_graph_path, "r") as scene_file:
  994. actual_lines = scene_file.readlines()
  995. logger.info(f"Parsing scene graph: {expected_debug_graph_path}")
  996. with open(expected_debug_graph_path, "r") as scene_file:
  997. expected_lines = scene_file.readlines()
  998. diff_actual, diff_expected = utils.get_differences_between_lists(actual_lines, expected_lines)
  999. if diff_actual == None and diff_expected == None:
  1000. return None, None
  1001. # There are some differences that are currently considered warnings.
  1002. # Long term these should become errors, but right now product assets on Linux and non-Linux
  1003. # are showing differences in hashes.
  1004. # Linux and non-Linux platforms are also generating different floating point values.
  1005. diff_actual, diff_expected = TestsFBX_AllPlatforms.trim_floating_point_values_from_same_length_lists(diff_actual, diff_expected, actual_file_path, expected_file_path)
  1006. # If this is the XML debug file, then it will be difficult to verify if a line is a hash line or another integer.
  1007. # However, because XML files are always compared after standard dbgsg files, the hashes from that initial comparison can be used here to check.
  1008. is_xml_dbgsg = os.path.splitext(expected_file_path)[-1].lower() == ".xml"
  1009. if is_xml_dbgsg:
  1010. return TestsFBX_AllPlatforms.scan_scene_debug_xml_file_for_issues(diff_actual, diff_expected, actual_hashes_to_skip, expected_hashes_to_skip)
  1011. else:
  1012. return TestsFBX_AllPlatforms.scan_scene_debug_scene_graph_file_differences_for_issues(diff_actual, diff_expected, actual_file_path, expected_file_path)
  1013. # Helper to run Asset Processor with debug output enabled and Atom output disabled
  1014. @staticmethod
  1015. def run_ap_debug_skip_atom_output(asset_processor):
  1016. result, output = asset_processor.batch_process(capture_output=True, extra_params=["--debugOutput",
  1017. "--regset=\"/O3DE/SceneAPI/AssetImporter/SkipAtomOutput=true\""])
  1018. # If the test fails, it's helpful to have the output from asset processor in the logs, to track the failure down.
  1019. logger.info(f"Asset Processor Output: {pformat(output)}")
  1020. assert result, "Asset Processor Failed"
  1021. def run_fbx_test(self, workspace, ap_setup_fixture, asset_processor,
  1022. project, blackbox_params: BlackboxAssetTest, overrideAsset=False):
  1023. """
  1024. These tests work by having the test case ingest the test data and determine the run pattern.
  1025. Tests will process scene settings files and will additionally do a verification against a provided debug file
  1026. Additionally, if an override is passed, the output is checked against the override.
  1027. Test Steps:
  1028. 1. Create temporary test environment
  1029. 2. Process Assets
  1030. 3. Determine what assets to validate based upon test data
  1031. 4. Validate assets were created in cache
  1032. 5. If debug file provided, verify scene files were generated correctly
  1033. 6. Verify that each given source asset resulted in the expected jobs and products
  1034. """
  1035. test_assets_folder = blackbox_params.override_asset_folder if overrideAsset else blackbox_params.asset_folder
  1036. logger.info(f"{blackbox_params.test_name}: Processing assets in folder '"
  1037. f"{test_assets_folder}' and verifying they match expected output.")
  1038. # Prepare test environment and process assets
  1039. if not overrideAsset:
  1040. asset_processor.prepare_test_environment(ap_setup_fixture['tests_dir'], test_assets_folder)
  1041. else:
  1042. asset_processor.prepare_test_environment(ap_setup_fixture['tests_dir'], test_assets_folder,
  1043. use_current_root=True, add_scan_folder=False,
  1044. existing_function_name=blackbox_params.asset_folder)
  1045. self.run_ap_debug_skip_atom_output(asset_processor)
  1046. logger.info(f"Validating assets.")
  1047. assetsToValidate = blackbox_params.override_assets if overrideAsset else blackbox_params.assets
  1048. expected_product_list = []
  1049. for expected_source in assetsToValidate:
  1050. for expected_job in expected_source.jobs:
  1051. for expected_product in expected_job.products:
  1052. expected_product_list.append(expected_product.product_name)
  1053. cache_folder = get_cache_folder(asset_processor)
  1054. missing_assets, _ = utils.compare_assets_with_cache(expected_product_list,
  1055. cache_folder)
  1056. # If the test is going to fail, print information to help track down the cause of failure.
  1057. if missing_assets:
  1058. logger.info(f"The following assets were missing from cache: {pformat(missing_assets)}")
  1059. in_cache = os.listdir(cache_folder)
  1060. logger.info(f"The cache {cache_folder} contains this content: {pformat(in_cache)}")
  1061. assert not missing_assets, \
  1062. f'The following assets were expected to be in, but not found in cache: {str(missing_assets)}'
  1063. # Load the asset database.
  1064. db_path = os.path.join(asset_processor.temp_asset_root(), workspace.project, "Cache",
  1065. "assetdb.sqlite")
  1066. cache_root = os.path.dirname(os.path.join(asset_processor.temp_asset_root(), workspace.project, "Cache",
  1067. ASSET_PROCESSOR_PLATFORM_MAP[workspace.asset_processor_platform]))
  1068. if blackbox_params.scene_debug_file:
  1069. scene_debug_file = blackbox_params.override_scene_debug_file if overrideAsset \
  1070. else blackbox_params.scene_debug_file
  1071. expected_hashes_to_skip, actual_hashes_to_skip = self.compare_scene_debug_file(asset_processor, scene_debug_file, blackbox_params.scene_debug_file)
  1072. # Run again for the .dbgsg.xml file
  1073. self.compare_scene_debug_file(asset_processor,
  1074. scene_debug_file + ".xml",
  1075. blackbox_params.scene_debug_file + ".xml",
  1076. expected_hashes_to_skip = expected_hashes_to_skip,
  1077. actual_hashes_to_skip = actual_hashes_to_skip)
  1078. # Check that each given source asset resulted in the expected jobs and products.
  1079. self.populate_asset_info(workspace, project, assetsToValidate)
  1080. for expected_source in assetsToValidate:
  1081. for job in expected_source.jobs:
  1082. for product in job.products:
  1083. asset_db_utils.compare_expected_asset_to_actual_asset(db_path,
  1084. expected_source,
  1085. f"{blackbox_params.asset_folder}/"
  1086. f"{expected_source.source_file_name}",
  1087. cache_root)
  1088. def test_FBX_ModifiedFBXFile_ConsistentProductOutput_OutputSucceeds(self, workspace, ap_setup_fixture,
  1089. asset_processor):
  1090. """
  1091. Test verifies changing an FBX file with a custom .assetinfo file produces an expected output
  1092. The .assetinfo file will remain unchanged.
  1093. Test Steps:
  1094. 1. Create test environment with an FBX file and a custom .assetinfo file
  1095. 2. Launch Asset Processor
  1096. 3. Validate that Asset Processor generates the expected output
  1097. 4. Modify the FBX file
  1098. 5. Run asset processor
  1099. 6. Validate that Asset Processor generates the expected output
  1100. """
  1101. # Copying test assets to project folder
  1102. TEST_FOLDER_NAME = "ModifiedFBXFile_ConsistentProductOutput"
  1103. asset_processor.prepare_test_environment(ap_setup_fixture["tests_dir"], TEST_FOLDER_NAME)
  1104. # Run AP against the FBX file and the .assetinfo file
  1105. self.run_ap_debug_skip_atom_output(asset_processor)
  1106. # Set path to expected dbgsg output, copied from test folder
  1107. scene_debug_expected = os.path.join(asset_processor.project_test_source_folder(), "SceneDebug", "modifiedfbxfile.fbx.dbgsg")
  1108. assert os.path.exists(scene_debug_expected), "Expected scene file missing in SceneDebug/modifiedfbxfile.fbx.dbgsg - Check test assets"
  1109. # Set path to actual dbgsg output, obtained when running AP
  1110. scene_debug_actual = os.path.join(
  1111. asset_processor.temp_project_cache(asset_platform=ASSET_PROCESSOR_PLATFORM_MAP[workspace.asset_processor_platform]),
  1112. TEST_FOLDER_NAME.lower(),
  1113. "modifiedfbxfile.fbx.dbgsg")
  1114. assert os.path.exists(scene_debug_actual)
  1115. # Compare the dbgsg files to ensure expected outputs
  1116. expected_hashes_to_skip, actual_hashes_to_skip = self.compare_scene_debug_file(asset_processor, scene_debug_expected, scene_debug_actual)
  1117. # Run again for the .dbgsg.xml files
  1118. self.compare_scene_debug_file(asset_processor, scene_debug_expected + ".xml", scene_debug_actual + ".xml",
  1119. expected_hashes_to_skip=expected_hashes_to_skip, actual_hashes_to_skip=actual_hashes_to_skip)
  1120. # Remove the files to be replaced from the source test asset folder
  1121. filestoremove = [
  1122. os.path.join(asset_processor.project_test_source_folder(),"ModifiedFBXFile.fbx"),
  1123. scene_debug_expected,
  1124. scene_debug_expected + ".xml"
  1125. ]
  1126. for file in filestoremove:
  1127. os.remove(file)
  1128. assert not os.path.exists(file), f"File failed to be removed: {file}"
  1129. # Add the replacement FBX and expected dbgsg files into the test project
  1130. source = os.path.join(ap_setup_fixture["tests_dir"], "assets",
  1131. "Override_ModifiedFBXFile_ConsistentProductOutput")
  1132. destination = asset_processor.project_test_source_folder()
  1133. shutil.copytree(source, destination, dirs_exist_ok=True)
  1134. assert os.path.exists(scene_debug_expected), \
  1135. "Expected scene file missing in SceneDebug/modifiedfbxfile.fbx.dbgsg - Check test assets"
  1136. # Run AP again to regenerate the .dbgsg files
  1137. self.run_ap_debug_skip_atom_output(asset_processor)
  1138. # Compare the new .dbgsg files with their expected outputs
  1139. expected_hashes_to_skip, actual_hashes_to_skip = self.compare_scene_debug_file(asset_processor, scene_debug_expected, scene_debug_actual)
  1140. # Run again for the .dbgsg.xml file
  1141. self.compare_scene_debug_file(asset_processor, scene_debug_expected + ".xml", scene_debug_actual + ".xml",
  1142. expected_hashes_to_skip=expected_hashes_to_skip, actual_hashes_to_skip=actual_hashes_to_skip)
  1143. def test_FBX_MixedCaseFileExtension_OutputSucceeds(self, workspace, ap_setup_fixture, asset_processor):
  1144. """
  1145. Test verifies FBX file with any combination of mixed casing in its file extension produces the
  1146. expected output.
  1147. Test Steps:
  1148. 1. Create test environment with an FBX file
  1149. 2. Change the .fbx file extension casing
  1150. 2. Launch Asset Processor
  1151. 3. Validate that Asset Processor generates the expected output
  1152. 4. Modify the FBX file's extension to a different casing
  1153. 5. Run asset processor
  1154. 6. Validate that Asset Processor generates the expected output
  1155. """
  1156. extensionlist = [
  1157. "OneMeshOneMaterial.Fbx",
  1158. "OneMeshOneMaterial.fBX",
  1159. "OneMeshOneMaterial.FBX",
  1160. ]
  1161. expected_debug_list = [
  1162. "onemeshonematerial_capf.fbx.dbgsg",
  1163. "onemeshonematerial_capbx.fbx.dbgsg",
  1164. "onemeshonematerial_capfbx.fbx.dbgsg"
  1165. ]
  1166. original_extension = "OneMeshOneMaterial.fbx"
  1167. for (extension, expected_debug_name) in zip(extensionlist, expected_debug_list):
  1168. asset_processor.prepare_test_environment(ap_setup_fixture["tests_dir"], "OneMeshOneMaterial")
  1169. rename_src = os.path.join(asset_processor.project_test_source_folder(), original_extension)
  1170. rename_dst = os.path.join(asset_processor.project_test_source_folder(), extension)
  1171. os.rename(rename_src, rename_dst)
  1172. assert os.path.exists(rename_dst), "Expected test file missing"
  1173. # Run AP while generating debug output and skipping atom output
  1174. self.run_ap_debug_skip_atom_output(asset_processor)
  1175. expectedassets = [
  1176. 'onemeshonematerial/onemeshonematerial.fbx.abdata.json',
  1177. 'onemeshonematerial/onemeshonematerial.fbx.assetinfo.dbg',
  1178. 'onemeshonematerial/onemeshonematerial.fbx.dbgsg',
  1179. 'onemeshonematerial/onemeshonematerial.fbx.dbgsg.xml',
  1180. 'onemeshonematerial/onemeshonematerial_fbx.procprefab',
  1181. 'onemeshonematerial/onemeshonematerial_fbx.procprefab.json'
  1182. ]
  1183. missing_assets, _ = utils.compare_assets_with_cache(expectedassets,
  1184. get_cache_folder(asset_processor))
  1185. assert not missing_assets, \
  1186. f'The following assets were expected to be in when processing {extension}, but not found in cache: ' \
  1187. f'{str(missing_assets)}'
  1188. scene_debug_expected = os.path.join(asset_processor.project_test_source_folder(), "SceneDebug",
  1189. expected_debug_name)
  1190. assert os.path.exists(scene_debug_expected), \
  1191. f'Expected scene file missing in {scene_debug_expected} - Check test assets'
  1192. # Set path to actual dbgsg output, obtained when running AP
  1193. scene_debug_actual = os.path.join(asset_processor.temp_project_cache(
  1194. asset_platform=ASSET_PROCESSOR_PLATFORM_MAP[workspace.asset_processor_platform]),
  1195. "onemeshonematerial", "onemeshonematerial.fbx.dbgsg")
  1196. assert os.path.exists(scene_debug_actual), f"Scene debug output missing after running AP on {extension}."
  1197. expected_hashes_to_skip, actual_hashes_to_skip = self.compare_scene_debug_file(asset_processor, scene_debug_expected, scene_debug_actual)
  1198. # Run again for the .dbgsg.xml file
  1199. self.compare_scene_debug_file(asset_processor,
  1200. scene_debug_expected + ".xml",
  1201. scene_debug_actual + ".xml",
  1202. expected_hashes_to_skip = expected_hashes_to_skip,
  1203. actual_hashes_to_skip = actual_hashes_to_skip)