WuhuIslandTesting/Library/PackageCache/com.unity.addressables@1.21.12/Tests/Runtime/ResourceProviders/ContentCatalogProviderTests.cs

378 lines
19 KiB
C#
Raw Normal View History

2025-01-07 02:06:59 +01:00
using System;
using System.Collections;
using NUnit.Framework;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
#if UNITY_EDITOR
using UnityEditor.AddressableAssets.Settings;
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
#endif
using UnityEngine.AddressableAssets.Initialization;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.TestTools;
using UnityEngine.AddressableAssets.ResourceLocators;
namespace UnityEngine.AddressableAssets.ResourceProviders.Tests
{
[TestFixture]
public class ContentCatalogProviderTests : AddressablesTestFixture
{
const string k_LocationName = "TestLocation";
const string k_LocationId = "TestLocationID";
const string k_CacheLocationId = "CacheLocationID";
const string k_RemoteLocationId = "RemoteLocationID";
private const string k_TempAssetFolder = "Assets/TempFolder";
private const string k_TempBuildFolder = "TempBuildFolder";
private readonly string m_RuntimeCatalogFilename;
public ContentCatalogProviderTests()
{
m_RuntimeCatalogFilename = "catalog" + m_UniqueTestName + ".bundle";
}
ResourceLocationBase m_SimpleLocation = new ResourceLocationBase(k_LocationName, k_LocationId, typeof(ContentCatalogProvider).FullName, typeof(object));
protected override TestBuildScriptMode BuildScriptMode => TestBuildScriptMode.Packed;
#if UNITY_EDITOR
internal override void Setup(AddressableAssetSettings settings, string tempAssetFolder)
{
settings.BundleLocalCatalog = true;
settings.DefaultGroup.GetSchema<BundledAssetGroupSchema>().BundleNaming = BundledAssetGroupSchema.BundleNamingStyle.AppendHash;
}
#endif
[Test]
public void DetermineIdToLoad_IfLocalCatalogsOnly_ReturnsMainId()
{
var contentCatalogOp = new ContentCatalogProvider.InternalOp();
IResourceLocation[] dependencies = new IResourceLocation[(int) ContentCatalogProvider.DependencyHashIndex.Count];
dependencies[(int) ContentCatalogProvider.DependencyHashIndex.Remote] = new ResourceLocationBase(string.Empty, k_RemoteLocationId, typeof(ContentCatalogProvider).FullName, typeof(object));
dependencies[(int) ContentCatalogProvider.DependencyHashIndex.Cache] = new ResourceLocationBase(string.Empty, k_CacheLocationId, typeof(ContentCatalogProvider).FullName, typeof(object));
var location = new ResourceLocationBase(k_LocationName, k_LocationId, typeof(ContentCatalogProvider).FullName, typeof(object), dependencies);
var loadedId = contentCatalogOp.DetermineIdToLoad(location, new List<object> {"hash", string.Empty}, true);
Assert.AreEqual(k_LocationId, loadedId);
}
[Test]
public void DetermineIdToLoad_IfNoDependencies_ReturnsMainId()
{
var contentCatalogOp = new ContentCatalogProvider.InternalOp();
var loadedId = contentCatalogOp.DetermineIdToLoad(m_SimpleLocation, null);
Assert.AreEqual(k_LocationId, loadedId);
}
[Test]
public void DetermineIdToLoad_IfTooFewDependencies_ReturnsMainId()
{
var contentCatalogOp = new ContentCatalogProvider.InternalOp();
var loadedId = contentCatalogOp.DetermineIdToLoad(m_SimpleLocation, new List<object> {1});
Assert.AreEqual(k_LocationId, loadedId);
}
[Test]
public void DetermineIdToLoad_IfTooManyDependencies_ReturnsMainId()
{
var contentCatalogOp = new ContentCatalogProvider.InternalOp();
var loadedId = contentCatalogOp.DetermineIdToLoad(m_SimpleLocation, new List<object> {1, 2, 3});
Assert.AreEqual(k_LocationId, loadedId);
}
[Test]
public void DetermineIdToLoad_IfOfflineAndNoCache_ReturnsMainId()
{
var contentCatalogOp = new ContentCatalogProvider.InternalOp();
var loadedId = contentCatalogOp.DetermineIdToLoad(m_SimpleLocation, new List<object> {string.Empty, string.Empty});
Assert.AreEqual(k_LocationId, loadedId);
}
[Test]
public void DetermineIdToLoad_IfOfflineAndHasCache_ReturnsCacheId()
{
var contentCatalogOp = new ContentCatalogProvider.InternalOp();
IResourceLocation[] dependencies = new IResourceLocation[(int) ContentCatalogProvider.DependencyHashIndex.Count];
dependencies[(int) ContentCatalogProvider.DependencyHashIndex.Remote] = new ResourceLocationBase(string.Empty, k_RemoteLocationId, typeof(ContentCatalogProvider).FullName, typeof(object));
dependencies[(int) ContentCatalogProvider.DependencyHashIndex.Cache] = new ResourceLocationBase(string.Empty, k_CacheLocationId, typeof(ContentCatalogProvider).FullName, typeof(object));
var location = new ResourceLocationBase(k_LocationName, k_LocationId, typeof(ContentCatalogProvider).FullName, typeof(object), dependencies);
var loadedId = contentCatalogOp.DetermineIdToLoad(location, new List<object> {string.Empty, "hash"});
Assert.AreEqual(k_CacheLocationId, loadedId);
}
[Test]
public void DetermineIdToLoad_IfOnlineMatchesCache_ReturnsCacheId()
{
var contentCatalogOp = new ContentCatalogProvider.InternalOp();
IResourceLocation[] dependencies = new IResourceLocation[(int) ContentCatalogProvider.DependencyHashIndex.Count];
dependencies[(int) ContentCatalogProvider.DependencyHashIndex.Remote] = new ResourceLocationBase(string.Empty, k_RemoteLocationId, typeof(ContentCatalogProvider).FullName, typeof(object));
dependencies[(int) ContentCatalogProvider.DependencyHashIndex.Cache] = new ResourceLocationBase(string.Empty, k_CacheLocationId, typeof(ContentCatalogProvider).FullName, typeof(object));
var location = new ResourceLocationBase(k_LocationName, k_LocationId, typeof(ContentCatalogProvider).FullName, typeof(object), dependencies);
var loadedId = contentCatalogOp.DetermineIdToLoad(location, new List<object> {"hash", "hash"});
Assert.AreEqual(k_CacheLocationId, loadedId);
}
[Test]
public void DetermineIdToLoad_IfDisableContentCatalogUpdateTrue_ForcesLocalId()
{
var contentCatalogOp = new ContentCatalogProvider.InternalOp();
IResourceLocation[] dependencies = new IResourceLocation[(int) ContentCatalogProvider.DependencyHashIndex.Count];
dependencies[(int) ContentCatalogProvider.DependencyHashIndex.Remote] = new ResourceLocationBase(string.Empty, k_RemoteLocationId, typeof(ContentCatalogProvider).FullName, typeof(object));
dependencies[(int) ContentCatalogProvider.DependencyHashIndex.Cache] = new ResourceLocationBase(string.Empty, k_CacheLocationId, typeof(ContentCatalogProvider).FullName, typeof(object));
var location = new ResourceLocationBase(k_LocationName, k_LocationId, typeof(ContentCatalogProvider).FullName, typeof(object), dependencies);
var loadedId = contentCatalogOp.DetermineIdToLoad(location, new List<object> {"hash", ""}, true);
Assert.AreEqual(k_LocationId, loadedId);
}
[Test]
public void DetermineIdToLoad_IfDisableContentCatalogUpdateTrue_ForcesCachedIdWhenLocalHashExists()
{
var contentCatalogOp = new ContentCatalogProvider.InternalOp();
IResourceLocation[] dependencies = new IResourceLocation[(int) ContentCatalogProvider.DependencyHashIndex.Count];
dependencies[(int) ContentCatalogProvider.DependencyHashIndex.Remote] = new ResourceLocationBase(string.Empty, k_RemoteLocationId, typeof(ContentCatalogProvider).FullName, typeof(object));
dependencies[(int) ContentCatalogProvider.DependencyHashIndex.Cache] = new ResourceLocationBase(string.Empty, k_CacheLocationId, typeof(ContentCatalogProvider).FullName, typeof(object));
var location = new ResourceLocationBase(k_LocationName, k_LocationId, typeof(ContentCatalogProvider).FullName, typeof(object), dependencies);
var loadedId = contentCatalogOp.DetermineIdToLoad(location, new List<object> {"hash", "local"}, true);
Assert.AreEqual(k_CacheLocationId, loadedId);
}
[Test]
public void DetermineIdToLoad_SetsLocalHash_WhenDisableContentCatalogIsTrue_AndNoLocalHashExists()
{
var contentCatalogOp = new ContentCatalogProvider.InternalOp();
IResourceLocation[] dependencies = new IResourceLocation[(int) ContentCatalogProvider.DependencyHashIndex.Count];
dependencies[(int) ContentCatalogProvider.DependencyHashIndex.Remote] = new ResourceLocationBase(string.Empty, k_RemoteLocationId, typeof(ContentCatalogProvider).FullName, typeof(object));
dependencies[(int) ContentCatalogProvider.DependencyHashIndex.Cache] = new ResourceLocationBase(string.Empty, k_CacheLocationId, typeof(ContentCatalogProvider).FullName, typeof(object));
var location = new ResourceLocationBase(k_LocationName, k_LocationId, typeof(ContentCatalogProvider).FullName, typeof(object), dependencies);
Assert.IsTrue(string.IsNullOrEmpty(contentCatalogOp.m_LocalHashValue));
var loadedId = contentCatalogOp.DetermineIdToLoad(location, new List<object> {"hash", ""}, true);
Assert.IsFalse(string.IsNullOrEmpty(contentCatalogOp.m_LocalHashValue));
}
[Test]
public void DetermineIdToLoad_IfOnlineMismatchesCache_ReturnsRemoteId()
{
var contentCatalogOp = new ContentCatalogProvider.InternalOp();
IResourceLocation[] dependencies = new IResourceLocation[(int) ContentCatalogProvider.DependencyHashIndex.Count];
dependencies[(int) ContentCatalogProvider.DependencyHashIndex.Remote] = new ResourceLocationBase(string.Empty, k_RemoteLocationId, typeof(ContentCatalogProvider).FullName, typeof(object));
dependencies[(int) ContentCatalogProvider.DependencyHashIndex.Cache] = new ResourceLocationBase(string.Empty, k_CacheLocationId, typeof(ContentCatalogProvider).FullName, typeof(object));
var location = new ResourceLocationBase(k_LocationName, k_LocationId, typeof(ContentCatalogProvider).FullName, typeof(object), dependencies);
var loadedId = contentCatalogOp.DetermineIdToLoad(location, new List<object> {"newHash", "hash"});
Assert.AreEqual(k_RemoteLocationId, loadedId);
loadedId = contentCatalogOp.DetermineIdToLoad(location, new List<object> {"newHash", string.Empty});
Assert.AreEqual(k_RemoteLocationId, loadedId);
}
[Test]
[TestCase(null, typeof(ArgumentNullException))]
[TestCase("invalid", typeof(ArgumentException))]
[TestCase("file.txt", typeof(ArgumentException))]
public void BundledCatalog_LoadCatalogFromBundle_InvalidBundlePath_ShouldThrow(string path, Type exceptionType)
{
Assert.Throws(exceptionType, () => new ContentCatalogProvider.InternalOp.BundledCatalog(path));
}
[UnityTest]
[Ignore("https://jira.unity3d.com/browse/ADDR-1451")]
public IEnumerator BundledCatalog_LoadCatalogFromBundle_InvalidBundleFileFormat_ShouldFail()
{
var bundleFilePath = Path.Combine(k_TempBuildFolder, "catalog.bundle");
Directory.CreateDirectory(Path.GetDirectoryName(bundleFilePath));
var bytes = new byte[] {1, 2, 3, 4, 5, 6};
File.WriteAllBytes(bundleFilePath, bytes);
LogAssert.Expect(LogType.Error, new Regex("Failed to read data for the AssetBundle", RegexOptions.IgnoreCase));
LogAssert.Expect(LogType.Error, new Regex("Unable to load dependent " +
$"bundle from location :", RegexOptions.IgnoreCase));
var bundledCatalog = new ContentCatalogProvider.InternalOp.BundledCatalog(bundleFilePath);
bundledCatalog.LoadCatalogFromBundleAsync();
yield return new WaitWhile(() => bundledCatalog.OpInProgress);
Assert.IsFalse(bundledCatalog.OpIsSuccess);
if (Directory.Exists(k_TempBuildFolder))
Directory.Delete(k_TempBuildFolder, true);
}
[UnityTest]
public IEnumerator BundledCatalog_WhenCatalogIsLocal_LoadCatalogFromBundle_ShouldLoadCatalogAndUnloadResources()
{
var bundleFilePath = Path.Combine(Addressables.RuntimePath, m_RuntimeCatalogFilename);
var bundledCatalog = new ContentCatalogProvider.InternalOp.BundledCatalog(bundleFilePath);
bundledCatalog.LoadCatalogFromBundleAsync();
bundledCatalog.OnLoaded += catalogData =>
{
Assert.NotNull(catalogData);
Assert.AreEqual(ResourceManagerRuntimeData.kCatalogAddress, catalogData.ProviderId);
};
yield return new WaitWhile(() => bundledCatalog.OpInProgress);
Assert.IsTrue(bundledCatalog.OpIsSuccess);
Assert.Null(bundledCatalog.m_CatalogAssetBundle);
}
[UnityTest]
[UnityPlatform(exclude = new[] {RuntimePlatform.Android})]
public IEnumerator BundledCatalog_WhenCatalogIsRemote_LoadCatalogFromBundle_ShouldLoadCatalogAndUnloadResources()
{
string localBundleFilePath = Path.Combine(Addressables.RuntimePath, m_RuntimeCatalogFilename);
string bundleFilePath = "file:///" + Path.GetFullPath(localBundleFilePath);
var bundledCatalog = new ContentCatalogProvider.InternalOp.BundledCatalog(bundleFilePath);
bundledCatalog.LoadCatalogFromBundleAsync();
bundledCatalog.OnLoaded += catalogData =>
{
Assert.NotNull(catalogData);
Assert.AreEqual(ResourceManagerRuntimeData.kCatalogAddress, catalogData.ProviderId);
};
yield return new WaitWhile(() => bundledCatalog.OpInProgress);
Assert.IsTrue(bundledCatalog.OpIsSuccess);
Assert.Null(bundledCatalog.m_CatalogAssetBundle);
}
[UnityTest]
public IEnumerator BundledCatalog_WhenRemoteCatalogDoesNotExist_LoadCatalogFromBundle_LogsErrorAndOpFails()
{
string bundleFilePath = "file:///doesnotexist.bundle";
var bundledCatalog = new ContentCatalogProvider.InternalOp.BundledCatalog(bundleFilePath);
bundledCatalog.LoadCatalogFromBundleAsync();
LogAssert.Expect(LogType.Error, $"Unable to load dependent bundle from location : {bundleFilePath}");
yield return new WaitWhile(() => bundledCatalog.OpInProgress);
Assert.IsFalse(bundledCatalog.OpIsSuccess);
}
[UnityTest]
public IEnumerator BundledCatalog_LoadCatalogFromBundle_WhenCalledMultipleTimes_OpNotCompleted_FirstShouldSucceedAndOthersShouldFail()
{
var bundleFilePath = Path.Combine(Addressables.RuntimePath, m_RuntimeCatalogFilename);
var timesCalled = 0;
var bundledCatalog = new ContentCatalogProvider.InternalOp.BundledCatalog(bundleFilePath);
bundledCatalog.OnLoaded += catalogData =>
{
Assert.NotNull(catalogData);
Assert.AreEqual(ResourceManagerRuntimeData.kCatalogAddress, catalogData.ProviderId);
timesCalled++;
};
bundledCatalog.LoadCatalogFromBundleAsync();
bundledCatalog.LoadCatalogFromBundleAsync();
LogAssert.Expect(LogType.Error, new Regex("progress", RegexOptions.IgnoreCase));
yield return new WaitWhile(() => bundledCatalog.OpInProgress);
Assert.AreEqual(1, timesCalled);
}
[UnityTest]
public IEnumerator BundledCatalog_LoadCatalogFromBundle_WhenCalledMultipleTimes_OpCompleted_AllShouldSucceed()
{
var bundleFilePath = Path.Combine(Addressables.RuntimePath, m_RuntimeCatalogFilename);
var timesCalled = 0;
var bundledCatalog = new ContentCatalogProvider.InternalOp.BundledCatalog(bundleFilePath);
bundledCatalog.OnLoaded += catalogData =>
{
Assert.NotNull(catalogData);
Assert.AreEqual(ResourceManagerRuntimeData.kCatalogAddress, catalogData.ProviderId);
timesCalled++;
};
bundledCatalog.LoadCatalogFromBundleAsync();
yield return new WaitWhile(() => bundledCatalog.OpInProgress);
bundledCatalog.LoadCatalogFromBundleAsync();
yield return new WaitWhile(() => bundledCatalog.OpInProgress);
Assert.AreEqual(2, timesCalled);
Assert.IsTrue(bundledCatalog.OpIsSuccess);
}
[Test]
public void ContentCatalogProvider_InternalOp_LoadCatalog_InvalidId_Throws()
{
Assert.Throws<NullReferenceException>(() => new ContentCatalogProvider.InternalOp().LoadCatalog("fakeId", false));
}
#if ENABLE_BINARY_CATALOG
[TestCase("http://127.0.0.1/catalog.bin", false)]
#else
[TestCase("http://127.0.0.1/catalog.json", false)]
#endif
[TestCase("http://127.0.0.1/catalog.bundle", true)]
public void BundledCatalog_WhenRequestingRemoteCatalog_CanLoadCatalogFromBundle_ReturnsExpectedResult(string internalId, bool result)
{
var loc = new ResourceLocationBase(internalId, internalId, typeof(ContentCatalogProvider).FullName, typeof(IResourceLocator));
ProviderOperation<Object> op = new ProviderOperation<Object>();
op.Init(m_Addressables.ResourceManager, null, loc, new AsyncOperationHandle<IList<AsyncOperationHandle>>());
ProvideHandle handle = new ProvideHandle(m_Addressables.ResourceManager, op);
bool loadCatalogFromLocalBundle = new ContentCatalogProvider.InternalOp().CanLoadCatalogFromBundle(internalId, handle.Location);
Assert.AreEqual(result, loadCatalogFromLocalBundle);
}
[Test]
public void BundledCatalog_WhenRequestingLocalCatalog_CanLoadCatalogFromBundle_ReturnsTrue()
{
string internalId = Path.Combine(Addressables.RuntimePath, m_RuntimeCatalogFilename);
var loc = new ResourceLocationBase(internalId, internalId, typeof(ContentCatalogProvider).FullName, typeof(IResourceLocator));
ProviderOperation<Object> op = new ProviderOperation<Object>();
op.Init(m_Addressables.ResourceManager, null, loc, new AsyncOperationHandle<IList<AsyncOperationHandle>>());
ProvideHandle handle = new ProvideHandle(m_Addressables.ResourceManager, op);
bool loadCatalogFromLocalBundle = new ContentCatalogProvider.InternalOp().CanLoadCatalogFromBundle(internalId, handle.Location);
Assert.IsTrue(loadCatalogFromLocalBundle);
}
}
}