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

234 lines
12 KiB
C#
Raw Permalink Normal View History

2025-01-07 02:06:59 +01:00
using System;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEditor.Build.Content;
using UnityEditor.Build.Pipeline.Interfaces;
using UnityEditor.Build.Pipeline.Tasks;
using UnityEditor.Build.Utilities;
using UnityEngine;
namespace UnityEditor.Build.Pipeline.Tests
{
class GenerateBundlePackingTests
{
IDependencyData GetDependencyData(List<ObjectIdentifier> objects, params GUID[] guids)
{
IDependencyData dep = new BuildDependencyData();
for (int i = 0; i < guids.Length; i++)
{
AssetLoadInfo loadInfo = new AssetLoadInfo()
{
asset = guids[i],
address = $"path{i}",
includedObjects = objects,
referencedObjects = objects
};
dep.AssetInfo.Add(guids[i], loadInfo);
}
return dep;
}
List<ObjectIdentifier> CreateObjectIdentifierList(string path, params GUID[] guids)
{
var objects = new List<ObjectIdentifier>();
foreach (GUID guid in guids)
{
var obj = new ObjectIdentifier();
obj.SetObjectIdentifier(guid, 0, FileType.SerializedAssetType, path);
objects.Add(obj);
}
return objects;
}
string k_TempAsset = "Assets/temp.prefab";
GUID k_TempGuid;
[OneTimeSetUp]
public void OneTimeSetUp()
{
var root = GameObject.CreatePrimitive(PrimitiveType.Cube);
var child = GameObject.CreatePrimitive(PrimitiveType.Cube);
child.transform.parent = root.transform;
PrefabUtility.SaveAsPrefabAsset(root, k_TempAsset);
k_TempGuid = new GUID(AssetDatabase.AssetPathToGUID(k_TempAsset));
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
AssetDatabase.DeleteAsset(k_TempAsset);
}
[Test]
public void WhenReferencesAreUnique_FilterReferencesForAsset_ReturnsReferences()
{
var assetInBundle = new GUID("00000000000000000000000000000000");
List<ObjectIdentifier> objects = CreateObjectIdentifierList("path", assetInBundle, assetInBundle);
IDependencyData dep = GetDependencyData(objects, assetInBundle);
var references = new List<ObjectIdentifier>(objects);
List<GUID> results = GenerateBundlePacking.FilterReferencesForAsset(dep, assetInBundle, references);
Assert.AreEqual(1, results.Count);
Assert.AreEqual(assetInBundle, results[0]);
}
[Test]
public void WhenReferencesContainsDefaultResources_FilterReferencesForAsset_PrunesDefaultResources()
{
var assetInBundle = new GUID("00000000000000000000000000000000");
List<ObjectIdentifier> objects = CreateObjectIdentifierList(CommonStrings.UnityDefaultResourcePath, assetInBundle);
IDependencyData dep = GetDependencyData(objects, assetInBundle);
var references = new List<ObjectIdentifier>(objects);
GenerateBundlePacking.FilterReferencesForAsset(dep, assetInBundle, references);
Assert.AreEqual(0, references.Count);
}
[Test]
public void WhenReferencesContainsAssetsInBundles_FilterReferencesForAsset_PrunesAssetsInBundles()
{
var assetInBundle = new GUID("00000000000000000000000000000000");
List<ObjectIdentifier> objects = CreateObjectIdentifierList("path", assetInBundle);
IDependencyData dep = GetDependencyData(objects, assetInBundle);
var references = new List<ObjectIdentifier>(objects);
GenerateBundlePacking.FilterReferencesForAsset(dep, assetInBundle, references);
Assert.AreEqual(0, references.Count);
}
[Test]
public void WhenReferencesDoesNotContainAssetsInBundles_FilterReferences_PrunesNothingAndReturnsNothing()
{
var assetInBundle = new GUID("00000000000000000000000000000000");
List<ObjectIdentifier> objects = CreateObjectIdentifierList("path", assetInBundle);
IDependencyData dep = new BuildDependencyData();
var references = new List<ObjectIdentifier>(objects);
List<GUID> results = GenerateBundlePacking.FilterReferencesForAsset(dep, assetInBundle, references);
Assert.AreEqual(1, references.Count);
Assert.AreEqual(assetInBundle, references[0].guid);
Assert.AreEqual(0, results.Count);
}
[Test]
public void WhenReferencesContainsRefsIncludedByNonCircularAssets_FilterReferencesForAsset_PrunesRefsIncludedByNonCircularAssets()
{
var assetNotInBundle = new GUID("00000000000000000000000000000000");
var referenceInBundle = new GUID("00000000000000000000000000000001");
var referenceNotInBundle = new GUID("00000000000000000000000000000002");
List<ObjectIdentifier> objects = CreateObjectIdentifierList("path", referenceNotInBundle);
IDependencyData dep = GetDependencyData(objects, referenceInBundle);
List<ObjectIdentifier> references = CreateObjectIdentifierList("path", referenceInBundle, referenceNotInBundle);
GenerateBundlePacking.FilterReferencesForAsset(dep, assetNotInBundle, references);
Assert.AreEqual(0, references.Count);
}
[Test]
public void WhenReferencesContainsRefsIncludedByCircularAssetsWithLowerGuid_FilterReferencesForAsset_PrunesRefsIncludedByCircularAssetsWithLowerGuid()
{
var assetNotInBundle = new GUID("00000000000000000000000000000001");
var referenceInBundle = new GUID("00000000000000000000000000000000");
List<ObjectIdentifier> objects = CreateObjectIdentifierList("path", assetNotInBundle); // circular reference to asset whose references we want to filter
IDependencyData dep = GetDependencyData(objects, referenceInBundle);
List<ObjectIdentifier> references = CreateObjectIdentifierList("path", referenceInBundle, assetNotInBundle);
GenerateBundlePacking.FilterReferencesForAsset(dep, assetNotInBundle, references);
Assert.AreEqual(0, references.Count);
}
[Test]
public void WhenReferencesContainsRefsIncludedByCircularAssetsWithHigherGuid_FilterReferencesForAsset_DoesNotPruneRefsIncludedByCircularAssetsWithHigherGuid()
{
var assetNotInBundle = new GUID("00000000000000000000000000000000");
var referenceInBundle = new GUID("00000000000000000000000000000001");
List<ObjectIdentifier> objects = CreateObjectIdentifierList("path", assetNotInBundle); // circular reference to asset whose references we want to filter
IDependencyData dep = GetDependencyData(objects, referenceInBundle);
List<ObjectIdentifier> references = CreateObjectIdentifierList("path", referenceInBundle, assetNotInBundle);
GenerateBundlePacking.FilterReferencesForAsset(dep, assetNotInBundle, references);
Assert.AreEqual(1, references.Count);
Assert.AreEqual(assetNotInBundle, references[0].guid);
}
[Test]
public void WhenReferencesContainsPreviousSceneObjects_FilterReferencesForAsset_PrunesPreviousSceneObjects()
{
var assetInBundle = new GUID("00000000000000000000000000000001");
var referenceNotInBundle = new GUID("00000000000000000000000000000000");
List<ObjectIdentifier> objects = CreateObjectIdentifierList("path", referenceNotInBundle);
IDependencyData dep = GetDependencyData(objects, assetInBundle);
var references = new List<ObjectIdentifier>(objects);
GenerateBundlePacking.FilterReferencesForAsset(dep, assetInBundle, references, new HashSet<ObjectIdentifier>() { objects[0] });
Assert.AreEqual(0, references.Count);
}
[Test]
public void WhenReferencesContainPreviousSceneAssetDependencies_FilterReferencesForAsset_PrunesPreviousAssetDependencies([Values] bool containsPreviousSceneAsset)
{
var assetInBundle = new GUID("00000000000000000000000000000001");
var referenceNotInBundle = new GUID("00000000000000000000000000000000");
List<ObjectIdentifier> objects = CreateObjectIdentifierList("path", referenceNotInBundle);
IDependencyData dep = GetDependencyData(objects, assetInBundle);
var references = new List<ObjectIdentifier>(objects);
var previousSceneReferences = new HashSet<GUID>();
if (containsPreviousSceneAsset)
previousSceneReferences.Add(assetInBundle);
GenerateBundlePacking.FilterReferencesForAsset(dep, assetInBundle, references, new HashSet<ObjectIdentifier>(), previousSceneReferences);
if (containsPreviousSceneAsset)
Assert.AreEqual(0, references.Count);
else
Assert.AreEqual(1, references.Count);
}
#if !UNITY_2019_1_OR_NEWER
[Test]
public void WhenPrefabContainsDuplicateTypes_GetSortedSceneObjectIdentifiers_DoesNotThorwError()
{
var includes = new List<ObjectIdentifier>(ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(k_TempGuid, EditorUserBuildSettings.activeBuildTarget));
var sorted = GenerateBundleCommands.GetSortedSceneObjectIdentifiers(includes);
Assert.AreEqual(includes.Count, sorted.Count);
}
#endif
[Test]
public void BuildCacheUtility_GetSortedUniqueTypesForObjects_ReturnsUniqueAndSortedTypeArray()
{
var includes = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(k_TempGuid, EditorUserBuildSettings.activeBuildTarget);
// Test prefab is created using 2 primitive cubes, one parented to the other, so the includes will in turn contain the sequence 2x:
Type[] expectedTypes = new[] { typeof(GameObject), typeof(Transform), typeof(MeshFilter), typeof(MeshRenderer), typeof(BoxCollider) };
Array.Sort(expectedTypes, (x, y) => x.AssemblyQualifiedName.CompareTo(y.AssemblyQualifiedName));
var actualTypes = BuildCacheUtility.GetSortedUniqueTypesForObjects(includes);
Assert.AreEqual(expectedTypes.Length * 2, includes.Length);
Assert.AreEqual(expectedTypes.Length, actualTypes.Length);
CollectionAssert.AreEqual(expectedTypes, actualTypes);
}
[Test]
public void BuildCacheUtility_GetMainTypeForObjects_ReturnsUniqueAndSortedTypeArray()
{
var includes = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(k_TempGuid, EditorUserBuildSettings.activeBuildTarget);
// Test prefab is created using 2 primitive cubes, one parented to the other, so the includes will in turn contain the sequence:
Type[] expectedTypes = new[] { typeof(GameObject), typeof(Transform), typeof(MeshFilter), typeof(MeshRenderer), typeof(BoxCollider),
typeof(GameObject), typeof(Transform), typeof(MeshFilter), typeof(MeshRenderer), typeof(BoxCollider) };
// One catch, the ordering of the expected types is based on the order of includes which is in turn ordered by the local identifier in file.
// Since we are generating the prefab as part of the test, and lfids generation is random, we don't know what order they will be returned in.
// So sort both expected types lists and compare exact.
Array.Sort(expectedTypes, (x, y) => x.AssemblyQualifiedName.CompareTo(y.AssemblyQualifiedName));
var actualTypes = BuildCacheUtility.GetMainTypeForObjects(includes);
Array.Sort(actualTypes, (x, y) => x.AssemblyQualifiedName.CompareTo(y.AssemblyQualifiedName));
Assert.AreEqual(expectedTypes.Length, includes.Length);
Assert.AreEqual(expectedTypes.Length, actualTypes.Length);
CollectionAssert.AreEqual(expectedTypes, actualTypes);
}
}
}