WuhuIslandTesting/Library/PackageCache/com.unity.addressables@1.21.12/Tests/Editor/Diagnostics/BuildLayoutTests.cs

649 lines
33 KiB
C#
Raw Normal View History

2025-01-07 02:06:59 +01:00
using System;
using System.Collections.Generic;
using System.IO;
using AddressableAssetsIntegrationTests;
using NUnit.Framework;
using UnityEditor.AddressableAssets.Build.BuildPipelineTasks;
using UnityEditor.AddressableAssets.Build.Layout;
using UnityEditor.Animations;
using UnityEngine;
namespace UnityEditor.AddressableAssets.Tests.Diagnostics
{
public class BuildLayoutTests
{
private BuildLayout.ExplicitAsset CreateExplicitAssetWithParentBundle(BuildLayout.Bundle parent, ulong filesize = 1)
{
BuildLayout.ExplicitAsset asset = new BuildLayout.ExplicitAsset();
asset.Bundle = parent;
asset.SerializedSize = filesize;
return asset;
}
private BuildLayout.Bundle CreateBundleWithFileSize(ulong filesize, string name = "default")
{
var bundle = new BuildLayout.Bundle();
bundle.Name = name;
bundle.FileSize = (ulong) filesize;
return bundle;
}
private BuildLayout.Bundle CreateBundleWithFileSize(int assetCount, string name = "default")
{
var bundle = new BuildLayout.Bundle();
bundle.AssetCount = assetCount;
bundle.Name = name;
bundle.FileSize = (ulong) assetCount;
return bundle;
}
[Test]
public void BuildLayoutBundle_CalculateEfficiency_CorrectlyWorksInSimpleCase()
{
BuildLayout.Bundle parent = CreateBundleWithFileSize(5);
BuildLayout.Bundle child = CreateBundleWithFileSize(10);
BuildLayout.ExplicitAsset parentAsset = CreateExplicitAssetWithParentBundle(parent);
BuildLayout.ExplicitAsset childAsset = CreateExplicitAssetWithParentBundle(child);
child.DependentBundles.Add(parent);
parent.UpdateBundleDependency(parentAsset, childAsset);
parent.SerializeBundleToBundleDependency();
BuildLayoutGenerationTask.CalculateEfficiency(parent);
float expectedEfficiency = .10f;
Assert.AreEqual(expectedEfficiency, parent.BundleDependencies[0].ExpandedEfficiency);
}
[Test]
public void BuildLayoutBundle_CalculateEfficiency_MultipleAssetDependencyCaseStillCreatesCorrectEfficiency()
{
BuildLayout.Bundle parent = CreateBundleWithFileSize(5);
BuildLayout.Bundle child = CreateBundleWithFileSize(10);
BuildLayout.ExplicitAsset parentAsset = CreateExplicitAssetWithParentBundle(parent);
for (int i = 0; i < 10; i++)
{
var asset = CreateExplicitAssetWithParentBundle(child);
parent.UpdateBundleDependency(parentAsset, asset);
}
parent.SerializeBundleToBundleDependency();
BuildLayoutGenerationTask.CalculateEfficiency(parent);
float expectedEfficiency = 1f;
Assert.AreEqual(expectedEfficiency, parent.BundleDependencies[0].ExpandedEfficiency);
}
[Test]
[TestCase(5, 10, 1, 5)]
[TestCase(6, 12, 2, 7)]
[TestCase(20, 43, 7, 15)]
[TestCase(27, 68, 25, 60)]
public void BuildLayoutBundle_CalculateEfficiency_ThreeLayeredTreeGeneratesCorrectEfficiencyAtAllLevels(
int parentAssetCount,
int childAssetCount,
int parentDependencyCount,
int childDependencyCount)
{
BuildLayout.Bundle grandparent = CreateBundleWithFileSize(1);
BuildLayout.Bundle parent = CreateBundleWithFileSize(parentAssetCount);
BuildLayout.Bundle child = CreateBundleWithFileSize(childAssetCount);
BuildLayout.ExplicitAsset grandparentAsset = CreateExplicitAssetWithParentBundle(grandparent);
List<BuildLayout.ExplicitAsset> parentAssets = new List<BuildLayout.ExplicitAsset>();
for (int i = 0; i < parentDependencyCount; i++)
{
var parentAsset = CreateExplicitAssetWithParentBundle(parent);
grandparent.UpdateBundleDependency(grandparentAsset, parentAsset);
parentAssets.Add(parentAsset);
}
for (int i = 0; i < childDependencyCount; i++)
{
var childAsset = CreateExplicitAssetWithParentBundle(child);
parent.UpdateBundleDependency(parentAssets[0], childAsset);
}
grandparent.SerializeBundleToBundleDependency();
parent.SerializeBundleToBundleDependency();
BuildLayoutGenerationTask.CalculateEfficiency(grandparent);
float expectedGrandparentEfficiency = (float) parentDependencyCount / parentAssetCount;
float expectedGrandparentExpandedEfficiency = (float) (childDependencyCount + parentDependencyCount) / (childAssetCount + parentAssetCount);
float expectedParentEfficiency = (float) childDependencyCount / childAssetCount;
Assert.AreEqual(expectedGrandparentEfficiency, grandparent.BundleDependencies[0].Efficiency, "Grandparent Efficiency not calculated correctly - this should not be affected by the children of parent.");
Assert.AreEqual(expectedGrandparentExpandedEfficiency, grandparent.BundleDependencies[0].ExpandedEfficiency, "Grandparent ExpandedEfficiency not calculated correctly - this should take into account the total Efficiency of both the direct children Dependency Links as well as all BundleDependencies below the child.");
Assert.AreEqual(expectedParentEfficiency, parent.BundleDependencies[0].ExpandedEfficiency, "Parent ExpandedEfficiency not calculated correctly - this should take into account the Efficiency of the direct child only.");
}
[Test]
public void BuildLayoutBundle_CalculateEfficiency_AssetDependenciesAreNotDoubleCounted()
{
var parentBundle = CreateBundleWithFileSize(1);
var childBundle = CreateBundleWithFileSize(1);
var parentAsset = CreateExplicitAssetWithParentBundle(parentBundle);
var childAsset = CreateExplicitAssetWithParentBundle(childBundle);
parentBundle.UpdateBundleDependency(parentAsset, childAsset);
parentBundle.SerializeBundleToBundleDependency();
BuildLayoutGenerationTask.CalculateEfficiency(parentBundle);
Assert.AreEqual(1f, parentBundle.BundleDependencies[0].ExpandedEfficiency, "ExpandedEfficiency not correctly calculated");
Assert.AreEqual(1f, parentBundle.BundleDependencies[0].Efficiency, "Efficiency not correctly calculated");
}
[Test]
[TestCase(3, 3, 1, 1 )]
[TestCase(50, 5, 5, 2)]
[TestCase(100, 100, 1, 50)]
public void BuildLayoutBundle_CalculateEfficiency_MultiProngedShortTreeGeneratesCorrectEfficiency(
int child1AssetCount,
int child2AssetCount,
int child1DependencyCount,
int child2DependencyCount)
{
BuildLayout.Bundle parentBundle = CreateBundleWithFileSize(2);
BuildLayout.Bundle childBundle1 = CreateBundleWithFileSize(child1AssetCount);
BuildLayout.Bundle childBundle2 = CreateBundleWithFileSize(child2AssetCount);
var parentAsset1 = CreateExplicitAssetWithParentBundle(parentBundle);
var parentAsset2 = CreateExplicitAssetWithParentBundle(parentBundle);
for (int i = 0; i < child1DependencyCount; i++)
{
var childAsset = CreateExplicitAssetWithParentBundle(childBundle1);
parentBundle.UpdateBundleDependency(parentAsset1, childAsset);
}
for (int i = 0; i < child2DependencyCount; i++)
{
var childAsset = CreateExplicitAssetWithParentBundle(childBundle2);
parentBundle.UpdateBundleDependency(parentAsset2, childAsset);
}
parentBundle.SerializeBundleToBundleDependency();
BuildLayoutGenerationTask.CalculateEfficiency(parentBundle);
float expectedChild1Efficiency = (float) child1DependencyCount / child1AssetCount;
float expectedChild2Efficiency = (float) child2DependencyCount / child2AssetCount;
Assert.AreEqual(expectedChild1Efficiency, parentBundle.BundleDependencies[0].ExpandedEfficiency);
Assert.AreEqual(expectedChild2Efficiency, parentBundle.BundleDependencies[1].ExpandedEfficiency);
}
[Test]
public void BuildLayoutBundle_CalculateEfficiency_DoesNotDoubleCountDependencies()
{
BuildLayout.Bundle parent = CreateBundleWithFileSize(2);
BuildLayout.Bundle child = CreateBundleWithFileSize(2);
BuildLayout.ExplicitAsset parentAsset1 = CreateExplicitAssetWithParentBundle(parent);
BuildLayout.ExplicitAsset parentAsset2 = CreateExplicitAssetWithParentBundle(parent);
BuildLayout.ExplicitAsset childAsset1 = CreateExplicitAssetWithParentBundle(child);
parent.UpdateBundleDependency(parentAsset1, childAsset1);
parent.UpdateBundleDependency(parentAsset2, childAsset1);
parent.SerializeBundleToBundleDependency();
BuildLayoutGenerationTask.CalculateEfficiency(parent);
float expectedEfficiency = .5f;
Assert.AreEqual(expectedEfficiency, parent.BundleDependencies[0].ExpandedEfficiency, "If multiple assets in a parent bundle depend on a single asset in the child, this reliance should not be double counted.");
Assert.AreEqual(expectedEfficiency, parent.BundleDependencies[0].Efficiency, "If multiple assets in a parent bundle depend on a single asset in the child, this reliance should not be double counted.");
}
[Test]
[TestCase(2, 1, 1, 1, 1)]
[TestCase(2, 5, 5, 2, 3)]
[TestCase(10, 3,3, 3,3)]
[TestCase(30, 30, 30, 20, 20)]
[TestCase(50, 50, 50, 50, 50)]
public void BuildLayoutBundle_CalculateEfficiency_HigherLevelTreesCorrectlyPromulgateLowerLevelEfficiency(
int parentAssetCount,
int child1AssetCount,
int child2AssetCount,
int child1DependencyCount,
int child2DependencyCount)
{
BuildLayout.Bundle grandparent = CreateBundleWithFileSize(1);
BuildLayout.Bundle parent = CreateBundleWithFileSize(parentAssetCount);
BuildLayout.Bundle childBundle1 = CreateBundleWithFileSize(child1AssetCount);
BuildLayout.Bundle childBundle2 = CreateBundleWithFileSize(child2AssetCount);
BuildLayout.ExplicitAsset grandparentAsset = CreateExplicitAssetWithParentBundle(grandparent);
BuildLayout.ExplicitAsset parentAsset = CreateExplicitAssetWithParentBundle(parent);
grandparent.UpdateBundleDependency(grandparentAsset, parentAsset);
for (int i = 0; i < child1DependencyCount; i++)
{
var childAsset = CreateExplicitAssetWithParentBundle(childBundle1);
parent.UpdateBundleDependency(parentAsset, childAsset);
}
for (int i = 0; i < child2DependencyCount; i++)
{
var childAsset = CreateExplicitAssetWithParentBundle(childBundle2);
parent.UpdateBundleDependency(parentAsset, childAsset);
}
grandparent.SerializeBundleToBundleDependency();
parent.SerializeBundleToBundleDependency();
BuildLayoutGenerationTask.CalculateEfficiency(grandparent);
float expectedGrandparentToParentEfficiency = (float) 1 / parentAssetCount;
float expectedGrandparentToParentExpandedEfficiency = (float) (1 + child1DependencyCount + child2DependencyCount) / (parentAssetCount + child1AssetCount + child2AssetCount);
float expectedParentToChild1Efficiency = (float) child1DependencyCount / child1AssetCount;
float expectedParentToChild2Efficiency = (float) child2DependencyCount / child2AssetCount;
Assert.AreEqual(expectedGrandparentToParentEfficiency, grandparent.BundleDependencies[0].Efficiency);
Assert.AreEqual(expectedGrandparentToParentExpandedEfficiency, grandparent.BundleDependencies[0].ExpandedEfficiency);
Assert.AreEqual(expectedParentToChild1Efficiency, parent.BundleDependencies[0].Efficiency);
Assert.AreEqual(expectedParentToChild2Efficiency, parent.BundleDependencies[1].Efficiency);
}
[Test]
[TestCase(5, 10, 10, 3, 5)]
[TestCase(7, 20, 15, 5, 8)]
[TestCase(11, 35, 40, 15, 20)]
public void BuildLayoutBundle_CalculateEfficiency_CacheCorrectlyAvoidsDoubleComputation(
int parentAssetCount,
int child1AssetCount,
int child2AssetCount,
int child1DependencyCount,
int child2DependencyCount)
{
BuildLayout.Bundle grandparent1 = CreateBundleWithFileSize(1);
BuildLayout.Bundle grandparent2 = CreateBundleWithFileSize(1);
BuildLayout.Bundle parent = CreateBundleWithFileSize(parentAssetCount);
BuildLayout.Bundle child1 = CreateBundleWithFileSize(child1AssetCount);
BuildLayout.Bundle child2 = CreateBundleWithFileSize(child2AssetCount);
BuildLayout.ExplicitAsset grandparent1Asset = CreateExplicitAssetWithParentBundle(grandparent1);
BuildLayout.ExplicitAsset grandparent2Asset = CreateExplicitAssetWithParentBundle(grandparent2);
BuildLayout.ExplicitAsset parentAsset = CreateExplicitAssetWithParentBundle(parent);
grandparent1.UpdateBundleDependency(grandparent1Asset, parentAsset);
grandparent2.UpdateBundleDependency(grandparent2Asset, parentAsset);
for (int i = 0; i < child1DependencyCount; i++)
{
var childAsset = CreateExplicitAssetWithParentBundle(child1);
parent.UpdateBundleDependency(parentAsset, childAsset);
}
for (int i = 0; i < child2DependencyCount; i++)
{
var childAsset = CreateExplicitAssetWithParentBundle(child2);
parent.UpdateBundleDependency(parentAsset, childAsset);
}
Dictionary<BuildLayout.Bundle.BundleDependency, BuildLayout.Bundle.EfficiencyInfo> bdCache = new Dictionary<BuildLayout.Bundle.BundleDependency, BuildLayout.Bundle.EfficiencyInfo>();
grandparent1.SerializeBundleToBundleDependency();
grandparent2.SerializeBundleToBundleDependency();
parent.SerializeBundleToBundleDependency();
BuildLayoutGenerationTask.CalculateEfficiency(grandparent1, bdCache);
var ef1 = new BuildLayout.Bundle.EfficiencyInfo
{
totalAssetFileSize = (ulong) child1AssetCount,
referencedAssetFileSize = (ulong) child1DependencyCount
};
var ef2 = new BuildLayout.Bundle.EfficiencyInfo
{
totalAssetFileSize = (ulong) child2AssetCount,
referencedAssetFileSize = (ulong) child2DependencyCount
};
float bd1Efficiency = (float) child1DependencyCount / child1AssetCount;
float bd2Efficiency = (float) child2DependencyCount / child2AssetCount;
float gp1Efficiency = (float) (1 + child1DependencyCount + child2DependencyCount) / (parentAssetCount + child1AssetCount + child2AssetCount);
Assert.IsTrue(bdCache.ContainsKey(parent.BundleDependencies[0]), "BundleDependencyCache not properly populated");
Assert.AreEqual(bdCache[parent.BundleDependencies[0]], ef1);
Assert.AreEqual(parent.BundleDependencies[0].ExpandedEfficiency, bd1Efficiency);
Assert.IsTrue(bdCache.ContainsKey(parent.BundleDependencies[1]), "BundleDependencyCache not properly populated");
Assert.AreEqual(bdCache[parent.BundleDependencies[1]], ef2);
Assert.AreEqual(parent.BundleDependencies[1].ExpandedEfficiency, bd2Efficiency);
Assert.AreEqual(grandparent1.BundleDependencies[0].ExpandedEfficiency, gp1Efficiency);
// Create a new asset that is not cached - we do this to ensure that cached values are used and that we're not recalculating Efficiency
// This will never happen in normal execution - this is just a workaround to make sure the cache is working properly.
var uncachedAsset = CreateExplicitAssetWithParentBundle(child1);
parent.UpdateBundleDependency(parentAsset, uncachedAsset);
BuildLayoutGenerationTask.CalculateEfficiency(grandparent2, bdCache);
Assert.IsTrue(bdCache.ContainsKey(parent.BundleDependencies[0]), "Key should not be removed");
Assert.AreEqual(bdCache[parent.BundleDependencies[0]], ef1, "Efficiency should not change since cached value should be used");
Assert.AreEqual(parent.BundleDependencies[0].ExpandedEfficiency, bd1Efficiency, "Efficiency should not change since cached value should be used.");
Assert.AreEqual(grandparent2.BundleDependencies[0].ExpandedEfficiency, gp1Efficiency, "Efficiency of grandparent2 should be equal to grandparent1, since cache was used.");
//Calculation without cache should be incorrect
BuildLayoutGenerationTask.CalculateEfficiency(grandparent2);
Assert.AreNotEqual(parent.BundleDependencies[0].ExpandedEfficiency, bd1Efficiency, "Efficiency should change since cached value is not used");
Assert.AreNotEqual(grandparent2.BundleDependencies[0].ExpandedEfficiency, gp1Efficiency, "Efficiency of grandparent2 should not be equal to grandparent1 since cache isnt used");
}
[Test]
[TestCase(5, 5, 5, 3, 2, 3, 4)]
[TestCase(50, 2, 10, 10, 1, 2, 4)]
[TestCase(1, 1, 1, 1, 1, 1, 1)]
[TestCase(100, 100, 100, 20, 30, 40, 40)]
public void BuildLayoutBundle_CalculateEfficiency_NonTreeStructureProperlyHandled(
int bundleBAssetCount,
int bundleCAssetCount,
int bundleDAssetCount,
int bundleBDependencyCount,
int bundleBToBundleCDependencyCount,
int bundleCDependencyCount,
int bundleDDependencyCount)
{
BuildLayout.Bundle bundleA = CreateBundleWithFileSize(1);
BuildLayout.Bundle bundleB = CreateBundleWithFileSize(bundleBAssetCount);
BuildLayout.Bundle bundleC = CreateBundleWithFileSize(bundleCAssetCount);
BuildLayout.Bundle bundleD = CreateBundleWithFileSize(bundleDAssetCount);
var assetA = CreateExplicitAssetWithParentBundle(bundleA);
var assetB = CreateExplicitAssetWithParentBundle(bundleB);
var assetC = CreateExplicitAssetWithParentBundle(bundleC);
bundleA.UpdateBundleDependency(assetA, assetB);
for (int i = 0; i < bundleBDependencyCount - 1; i++)
{
var childAsset = CreateExplicitAssetWithParentBundle(bundleB);
bundleA.UpdateBundleDependency(assetA, childAsset);
}
bundleA.UpdateBundleDependency(assetA, assetC);
for (int i = 0; (i < bundleCDependencyCount - 1) || (i < bundleBToBundleCDependencyCount); i++)
{
var childAsset = CreateExplicitAssetWithParentBundle(bundleC);
if (i < bundleCDependencyCount - 1)
bundleA.UpdateBundleDependency(assetA, childAsset);
if (i < bundleBToBundleCDependencyCount)
bundleB.UpdateBundleDependency(assetB, childAsset);
}
for (int i = 0; i < bundleDDependencyCount; i++)
{
var childAsset = CreateExplicitAssetWithParentBundle(bundleD);
bundleC.UpdateBundleDependency(assetC, childAsset);
}
bundleA.SerializeBundleToBundleDependency();
bundleB.SerializeBundleToBundleDependency();
bundleC.SerializeBundleToBundleDependency();
bundleD.SerializeBundleToBundleDependency();
BuildLayoutGenerationTask.CalculateEfficiency(bundleA);
var cToDExpandedEfficiency = (float)bundleDDependencyCount / bundleDAssetCount;
var BToCExpandedEfficiency = (float)(bundleDDependencyCount + bundleBToBundleCDependencyCount) / (bundleCAssetCount + bundleDAssetCount);
var AToBExpandedEfficiency = (float) (bundleBDependencyCount + bundleDDependencyCount + bundleBToBundleCDependencyCount) / (bundleBAssetCount + bundleCAssetCount + bundleDAssetCount);
Assert.AreEqual(bundleC.BundleDependencies[0].ExpandedEfficiency, cToDExpandedEfficiency);
Assert.AreEqual(bundleB.BundleDependencies[0].ExpandedEfficiency, BToCExpandedEfficiency);
Assert.AreEqual(bundleA.BundleDependencies[0].ExpandedEfficiency, AToBExpandedEfficiency);
}
[Test]
[TestCase(20, 20, 20, 5, 5, 5, 5)]
[TestCase(50, 30, 10, 15, 10, 8, 7)]
[TestCase(100, 75, 35, 35, 7, 30, 25)]
public void BuildLayoutBundle_CalculateEfficiency_HandlesCycleWithLeadInByCuttingOffLastNodeConnections(
int bundleBAssetCount,
int bundleCAssetCount,
int bundleDAssetCount,
int bundleAToBDependencyCount,
int bundleBToCDependencyCount,
int bundleCToDDependencyCount,
int bundleDToBDependencyCount)
{
BuildLayout.Bundle bundleA = CreateBundleWithFileSize(1);
BuildLayout.Bundle bundleB = CreateBundleWithFileSize(bundleBAssetCount, "B");
BuildLayout.Bundle bundleC = CreateBundleWithFileSize(bundleCAssetCount, "C");
BuildLayout.Bundle bundleD = CreateBundleWithFileSize(bundleDAssetCount, "D");
var assetA = CreateExplicitAssetWithParentBundle(bundleA);
var assetB = CreateExplicitAssetWithParentBundle(bundleB);
var assetC = CreateExplicitAssetWithParentBundle(bundleC);
var assetD = CreateExplicitAssetWithParentBundle(bundleD);
bundleA.UpdateBundleDependency(assetA, assetB);
bundleB.UpdateBundleDependency(assetB, assetC);
bundleC.UpdateBundleDependency(assetC, assetD);
bundleD.UpdateBundleDependency(assetD, assetB);
for (int i = 0; i < bundleAToBDependencyCount - 1; i++)
{
var childAsset = CreateExplicitAssetWithParentBundle(bundleB);
bundleA.UpdateBundleDependency(assetA, childAsset);
}
for (int i = 0; i < bundleBToCDependencyCount - 1; i++)
{
var childAsset = CreateExplicitAssetWithParentBundle(bundleC);
bundleB.UpdateBundleDependency(assetB, childAsset);
}
for (int i = 0; i < bundleCToDDependencyCount - 1; i++)
{
var childAsset = CreateExplicitAssetWithParentBundle(bundleD);
bundleC.UpdateBundleDependency(assetC, childAsset);
}
for (int i = 0; i < bundleDToBDependencyCount - 1; i++)
{
var childAsset = CreateExplicitAssetWithParentBundle(bundleB);
bundleD.UpdateBundleDependency(assetD, childAsset);
}
bundleA.SerializeBundleToBundleDependency();
bundleB.SerializeBundleToBundleDependency();
bundleC.SerializeBundleToBundleDependency();
bundleD.SerializeBundleToBundleDependency();
BuildLayoutGenerationTask.CalculateEfficiency(bundleA);
float bundleDToBExpandedEfficiency = (float) bundleDToBDependencyCount / bundleBAssetCount;
float bundleCToDExpandedEfficiency = (float) (bundleCToDDependencyCount + bundleDToBDependencyCount) / (bundleDAssetCount + bundleBAssetCount);
float bundleBToCExpandedEfficiency = (float) (bundleBToCDependencyCount + bundleCToDDependencyCount + bundleDToBDependencyCount) / (bundleCAssetCount + bundleDAssetCount + bundleBAssetCount);
float bundleAToBExpandedEfficiency = (float) (bundleAToBDependencyCount + bundleBToCDependencyCount + bundleCToDDependencyCount + bundleDToBDependencyCount) / (bundleBAssetCount + bundleCAssetCount + bundleDAssetCount + bundleBAssetCount);
Assert.AreEqual(bundleAToBExpandedEfficiency, bundleA.BundleDependencies[0].ExpandedEfficiency);
Assert.AreEqual(bundleBToCExpandedEfficiency, bundleB.BundleDependencies[0].ExpandedEfficiency);
Assert.AreEqual(bundleCToDExpandedEfficiency, bundleC.BundleDependencies[0].ExpandedEfficiency);
Assert.AreEqual(bundleDToBExpandedEfficiency, bundleD.BundleDependencies[0].ExpandedEfficiency);
}
BuildLayout CreateTestLayout(DateTime buildDate, string error = null)
{
BuildLayout layout = new BuildLayout();
layout.BuildTarget = BuildTarget.Android;
layout.BuildResultHash = "testHash123";
layout.BuildType = BuildType.UpdateBuild;
layout.BuildStart = buildDate;
layout.Duration = 10;
layout.BuildError = error;
layout.BuildScript = "DefaultBuildScript";
BuildLayout.Bundle bundle = CreateBundleWithFileSize(2);
bundle.Files = new List<BuildLayout.File>();
BuildLayout.File file = new BuildLayout.File();
bundle.Files.Add(file);
file.Assets = new List<BuildLayout.ExplicitAsset>();
file.Assets.Add(CreateExplicitAssetWithParentBundle(bundle));
file.Assets.Add(CreateExplicitAssetWithParentBundle(bundle));
BuildLayout.Group group = new BuildLayout.Group();
group.Bundles = new List<BuildLayout.Bundle>();
group.Bundles.Add(bundle);
layout.Groups = new List<BuildLayout.Group>();
layout.Groups.Add(group);
layout.DefaultGroup = group;
return layout;
}
[Test]
public void BuildLayoutBundle_SaveAndLoad_SavesCorrectlyToDisk()
{
DateTime time = DateTime.Now;
BuildLayout layout = CreateTestLayout(time);
string filePath = $"{Application.dataPath}/testLayout.json";
try
{
layout.WriteToFile(filePath, false);
FileAssert.Exists(filePath, $"Failed to save build layout to {filePath}");
}
finally
{
if (File.Exists(filePath))
File.Delete(filePath);
}
}
[Test]
[TestCase(50UL, 50UL, 20UL, 20UL, 10, 5)]
[TestCase(30UL, 50UL, 10UL, 5UL, 3, 2)]
[TestCase(1UL, 1UL, 1UL, 1UL, 1, 1)]
[TestCase(30UL, 1UL, 30UL, 1UL, 1, 1)]
[TestCase(5000UL, 5000UL, 500UL, 500UL, 30, 50)]
public void BuildLayoutBundle_CalculateEfficiency_CorrectlyUsesFilesizeForEfficiency(
ulong parentTotalFilesize, ulong childTotalFilesize,
ulong parentDepFileSize, ulong childDepFilesize,
int parentDependencyCount, int childDependencyCount)
{
BuildLayout.Bundle grandparent = CreateBundleWithFileSize(1);
BuildLayout.Bundle parent = CreateBundleWithFileSize(parentTotalFilesize);
BuildLayout.Bundle child = CreateBundleWithFileSize(childTotalFilesize);
BuildLayout.ExplicitAsset grandparentAsset = CreateExplicitAssetWithParentBundle(grandparent);
List<BuildLayout.ExplicitAsset> parentAssets = new List<BuildLayout.ExplicitAsset>();
ulong expectedParentDepFileSize = 0;
for (int i = 0; i < parentDependencyCount; i++)
{
var curFileSize = (ulong)parentDependencyCount / parentDepFileSize;
expectedParentDepFileSize += curFileSize;
var parentAsset = CreateExplicitAssetWithParentBundle(parent, curFileSize);
grandparent.UpdateBundleDependency(grandparentAsset, parentAsset);
parentAssets.Add(parentAsset);
}
ulong expectedChildDepFileSize = 0;
for (int i = 0; i < childDependencyCount; i++)
{
var curFileSize = (ulong)childDependencyCount / childDepFilesize;
expectedChildDepFileSize += curFileSize;
var childAsset = CreateExplicitAssetWithParentBundle(child, curFileSize);
parent.UpdateBundleDependency(parentAssets[0], childAsset);
}
grandparent.SerializeBundleToBundleDependency();
parent.SerializeBundleToBundleDependency();
BuildLayoutGenerationTask.CalculateEfficiency(grandparent);
float expectedGrandparentEfficiency = (float) expectedParentDepFileSize / parentTotalFilesize;
float expectedGrandparentExpandedEfficiency = (float) (expectedParentDepFileSize + expectedChildDepFileSize) / (parentTotalFilesize + childTotalFilesize);
float expectedParentEfficiency = (float) expectedChildDepFileSize / childTotalFilesize;
Assert.AreEqual(expectedGrandparentEfficiency, grandparent.BundleDependencies[0].Efficiency, "Grandparent Efficiency not calculated correctly - this should not be affected by the children of parent.");
Assert.AreEqual(expectedGrandparentExpandedEfficiency, grandparent.BundleDependencies[0].ExpandedEfficiency, "Grandparent ExpandedEfficiency not calculated correctly - this should take into account the total Efficiency of both the direct children Dependency Links as well as all BundleDependencies below the child.");
Assert.AreEqual(expectedParentEfficiency, parent.BundleDependencies[0].ExpandedEfficiency, "Parent ExpandedEfficiency not calculated correctly - this should take into account the Efficiency of the direct child only.");
}
[Test]
public void BuildLayoutBundle_SaveAndLoad_ReadsCorrectDataForHeader()
{
DateTime time = DateTime.Now;
BuildLayout layout = CreateTestLayout(time, "testError123");
time = layout.BuildStart; // due to removing miliseconds in the layout
string filePath = $"{Application.dataPath}/testLayout.json";
try
{
layout.WriteToFile(filePath, false);
FileAssert.Exists(filePath, $"Failed to save build layout to {filePath}");
BuildLayout readLayout = BuildLayout.Open(filePath, false, false);
Assert.AreEqual(DateTime.MinValue, readLayout.BuildStart, "StartDate was not expected to have read a valid date");
// test all header values to ensure the values are as expect (not the same as default values)
readLayout.ReadHeader();
Assert.AreEqual(time, readLayout.Header.BuildStart, "Header Data written or Read incorrectly");
Assert.AreEqual(10, readLayout.Header.Duration, "Header Data written or Read incorrectly");
Assert.AreEqual("testError123", readLayout.Header.BuildError, "Header Data written or Read incorrectly");
Assert.AreEqual(BuildTarget.Android, readLayout.Header.BuildTarget, "Header Data written or Read incorrectly");
Assert.AreEqual(BuildType.UpdateBuild, readLayout.Header.BuildType, "Header Data written or Read incorrectly");
Assert.AreEqual("testHash123", readLayout.Header.BuildResultHash, "Header Data written or Read incorrectly");
// that the test groups have not been read
Assert.AreEqual(0, readLayout.Groups.Count, "Expect to have not read any Groups yet with only Header read");
}
finally
{
if (File.Exists(filePath))
File.Delete(filePath);
}
}
[Test]
public void BuildLayoutBundle_SaveAndLoad_ReadsCorrectDataForBody()
{
DateTime time = DateTime.Now;
BuildLayout layout = CreateTestLayout(time);
string filePath = $"{Application.dataPath}/testLayout.json";
try
{
layout.WriteToFile(filePath, false);
FileAssert.Exists(filePath, $"Failed to save build layout to {filePath}");
BuildLayout readLayout = BuildLayout.Open(filePath, false, false);
Assert.AreEqual(0, readLayout.Groups.Count, "Expect to have not read any Groups yet with no data yet read read");
readLayout.ReadHeader();
Assert.AreEqual(0, readLayout.Groups.Count, "Expect to have not read any Groups yet with only Header read");
readLayout.ReadFull();
Assert.AreEqual(1, readLayout.Groups.Count, "Expect to have 1 Groups after doing a full read read");
}
finally
{
if (File.Exists(filePath))
File.Delete(filePath);
}
}
[Test]
[TestCase(typeof(GameObject), AssetType.GameObject)]
[TestCase(typeof(SceneAsset), AssetType.Scene)]
[TestCase(typeof(AnimatorController), AssetType.AnimationController)]
[TestCase(typeof(TestObject), AssetType.ScriptableObject)]
[TestCase(typeof(ObjectReferenceMonoBehaviour), AssetType.MonoBehaviour)]
public void GetAssetType_ReturnsCorrect(System.Type typeIn, AssetType expectedType)
{
AssetType actual = BuildLayoutHelpers.GetAssetType(typeIn);
Assert.AreEqual(expectedType, actual);
}
}
}