WuhuIslandTesting/Library/PackageCache/com.unity.scriptablebuildpipeline@1.21.5/Tests/Editor/CalculateCustomDependencyTests.cs

215 lines
10 KiB
C#
Raw Normal View History

2025-01-07 02:06:59 +01:00
#if UNITY_2019_3_OR_NEWER
using NUnit.Framework;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor.Build.Content;
using UnityEditor.Build.Pipeline.Injector;
using UnityEditor.Build.Pipeline.Interfaces;
using UnityEditor.Build.Pipeline.Tasks;
using UnityEditor.Build.Pipeline.Utilities;
using UnityEditor.Build.Player;
using UnityEngine;
namespace UnityEditor.Build.Pipeline.Tests
{
public class CalculateCustomDependencyTests
{
class TestBuildParameters : TestBuildParametersBase
{
// Optional Inputs
public override BuildTarget Target => BuildTarget.NoTarget;
public override TypeDB ScriptInfo => null;
public override bool UseCache { get => false; set => base.UseCache = value; }
}
class TestContent : TestBundleBuildContent
{
// Inputs
List<CustomContent> m_CustomAssets;
public override List<CustomContent> CustomAssets => m_CustomAssets;
// Outputs
Dictionary<string, List<GUID>> m_BundleLayout;
Dictionary<GUID, string> m_Addresses;
public override Dictionary<string, List<GUID>> BundleLayout => m_BundleLayout;
public override Dictionary<GUID, string> Addresses => m_Addresses;
public TestContent(List<CustomContent> customAssets)
{
m_CustomAssets = customAssets;
m_BundleLayout = new Dictionary<string, List<GUID>>();
m_Addresses = new Dictionary<GUID, string>();
}
}
class TestDependencyData : TestDependencyDataBase
{
// Input / Output
Dictionary<GUID, AssetLoadInfo> m_AssetInfo;
public override Dictionary<GUID, AssetLoadInfo> AssetInfo => m_AssetInfo;
// Optional Inputs
BuildUsageTagGlobal m_GlobalUsage;
Dictionary<GUID, SceneDependencyInfo> m_SceneInfo;
public override BuildUsageTagGlobal GlobalUsage { get => m_GlobalUsage; set => m_GlobalUsage = value; }
public override Dictionary<GUID, SceneDependencyInfo> SceneInfo => m_SceneInfo;
public override BuildUsageCache DependencyUsageCache => null;
// Outputs
Dictionary<GUID, BuildUsageTagSet> m_AssetUsage;
public override Dictionary<GUID, BuildUsageTagSet> AssetUsage => m_AssetUsage;
public TestDependencyData(Dictionary<GUID, AssetLoadInfo> assetInfo)
{
m_AssetInfo = assetInfo;
m_GlobalUsage = new BuildUsageTagGlobal();
m_SceneInfo = new Dictionary<GUID, SceneDependencyInfo>();
m_AssetUsage = new Dictionary<GUID, BuildUsageTagSet>();
}
}
static CalculateCustomDependencyData CreateDefaultBuildTask(List<CustomContent> customAssets, Dictionary<GUID, AssetLoadInfo> assetInfo = null)
{
var task = new CalculateCustomDependencyData();
var testParams = new TestBuildParameters();
var testContent = new TestContent(customAssets);
if (assetInfo == null)
assetInfo = new Dictionary<GUID, AssetLoadInfo>();
var testData = new TestDependencyData(assetInfo);
IBuildContext context = new BuildContext(testParams, testContent, testData);
ContextInjector.Inject(context, task);
return task;
}
static void ExtractTestData(IBuildTask task, out CustomAssets customAssets, out TestContent content, out TestDependencyData dependencyData)
{
IBuildContext context = new BuildContext();
ContextInjector.Extract(context, task);
customAssets = (CustomAssets)context.GetContextObject<ICustomAssets>();
content = (TestContent)context.GetContextObject<IBundleBuildContent>();
dependencyData = (TestDependencyData)context.GetContextObject<IDependencyData>();
}
static ObjectIdentifier MakeObjectId(string guid, long localIdentifierInFile, FileType fileType, string filePath)
{
var objectId = new ObjectIdentifier();
var boxed = (object)objectId;
var type = typeof(ObjectIdentifier);
type.GetField("m_GUID", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(boxed, new GUID(guid));
type.GetField("m_LocalIdentifierInFile", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(boxed, localIdentifierInFile);
type.GetField("m_FileType", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(boxed, fileType);
type.GetField("m_FilePath", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(boxed, filePath);
return (ObjectIdentifier)boxed;
}
[Test]
public void CreateAssetEntryForObjectIdentifiers_ThrowsExceptionOnAssetGUIDCollision()
{
var assetPath = "temp/test_serialized_file.asset";
UnityEditorInternal.InternalEditorUtility.SaveToSerializedFileAndForget(new[] { Texture2D.whiteTexture, Texture2D.redTexture }, assetPath, false);
var address = "CustomAssetAddress";
var assetInfo = new Dictionary<GUID, AssetLoadInfo>();
assetInfo.Add(HashingMethods.Calculate(address).ToGUID(), new AssetLoadInfo());
var customContent = new List<CustomContent>
{
new CustomContent
{
Asset = new GUID(),
Processor = (guid, task) =>
{
task.GetObjectIdentifiersAndTypesForSerializedFile(assetPath, out var objectIdentifiers, out var types);
var ex = Assert.Throws<System.ArgumentException>(() => task.CreateAssetEntryForObjectIdentifiers(objectIdentifiers, assetPath, "CustomAssetBundle", address, types[0]));
var expected = string.Format("Custom Asset '{0}' already exists. Building duplicate asset entries is not supported.", address);
Assert.That(ex.Message, Is.EqualTo(expected));
}
}
};
var buildTask = CreateDefaultBuildTask(customContent, assetInfo);
buildTask.Run();
}
[Test]
public void GetObjectIdentifiersAndTypesForSerializedFile_ReturnsAllObjectIdentifiersAndTypes()
{
var assetPath = "temp/test_serialized_file.asset";
UnityEditorInternal.InternalEditorUtility.SaveToSerializedFileAndForget(new[] { Texture2D.whiteTexture, Texture2D.redTexture }, assetPath, false);
var customContent = new List<CustomContent>
{
new CustomContent
{
Asset = new GUID(),
Processor = (guid, task) =>
{
task.GetObjectIdentifiersAndTypesForSerializedFile(assetPath, out var objectIdentifiers, out var types);
Assert.AreEqual(2, objectIdentifiers.Length);
Assert.AreEqual(MakeObjectId("00000000000000000000000000000000", 1, FileType.NonAssetType, assetPath), objectIdentifiers[0]);
Assert.AreEqual(MakeObjectId("00000000000000000000000000000000", 2, FileType.NonAssetType, assetPath), objectIdentifiers[1]);
Assert.AreEqual(1, types.Length);
Assert.AreEqual(typeof(Texture2D), types[0]);
}
}
};
var buildTask = CreateDefaultBuildTask(customContent);
buildTask.Run();
}
[Test]
public void CreateAssetEntryForObjectIdentifiers_AddsNewBundleAndAssetDataForCustomAsset()
{
var assetPath = "temp/test_serialized_file.asset";
var bundleName = "CustomAssetBundle";
var address = "CustomAssetAddress";
var assetGuid = HashingMethods.Calculate(address).ToGUID();
UnityEditorInternal.InternalEditorUtility.SaveToSerializedFileAndForget(new[] { Texture2D.whiteTexture, Texture2D.redTexture }, assetPath, false);
var customContent = new List<CustomContent>
{
new CustomContent
{
Asset = new GUID(),
Processor = (guid, task) =>
{
task.GetObjectIdentifiersAndTypesForSerializedFile(assetPath, out var includedObjects, out var types);
task.CreateAssetEntryForObjectIdentifiers(includedObjects, assetPath, bundleName, address, types[0]);
}
}
};
var buildTask = CreateDefaultBuildTask(customContent);
buildTask.Run();
ExtractTestData(buildTask, out var customAssets, out var content, out var dependencyData);
// Ensure the bundle name was added, and the custom asset guid was added to that bundle
Assert.IsTrue(content.BundleLayout.ContainsKey(bundleName));
CollectionAssert.Contains(content.BundleLayout[bundleName], assetGuid);
// Ensure the custom address was added
Assert.IsTrue(content.Addresses.ContainsKey(assetGuid));
Assert.AreEqual(address, content.Addresses[assetGuid]);
// Ensure AssetInfo contains the calculated includes and references for the custom asset
Assert.IsTrue(dependencyData.AssetInfo.ContainsKey(assetGuid));
var loadInfo = dependencyData.AssetInfo[assetGuid];
Assert.AreEqual(address, loadInfo.address);
Assert.AreEqual(assetGuid, loadInfo.asset);
Assert.AreEqual(2, loadInfo.includedObjects.Count);
Assert.AreEqual(0, loadInfo.referencedObjects.Count);
// Ensure the usage tags were added
Assert.IsTrue(dependencyData.AssetUsage.ContainsKey(assetGuid));
Assert.IsNotNull(dependencyData.AssetUsage[assetGuid]);
// Ensure the custom asset was registered in the customAssets list
CollectionAssert.Contains(customAssets.Assets, assetGuid);
}
}
}
#endif