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

276 lines
12 KiB
C#
Raw Normal View History

2025-01-07 02:06:59 +01:00
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using NUnit.Framework;
#if UNITY_EDITOR
using UnityEditor.AddressableAssets.Settings;
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
#endif
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.ResourceManagement.Util;
using UnityEngine.SceneManagement;
using UnityEngine.TestTools;
namespace AddressableTests.SyncAddressables
{
public abstract class AssetBundleProviderTests : AddressablesTestFixture
{
protected string m_PrefabKey = "syncprefabkey";
protected string m_InvalidKey = "notarealkey";
protected string m_SceneKey = "syncscenekey";
const int kForceUWRBundleCount = 10;
const int kMaxConcurrentRequests = 3;
string GetForceUWRAddrName(int i)
{
return $"forceuwrasset{i}";
}
#if UNITY_EDITOR
internal override void Setup(AddressableAssetSettings settings, string tempAssetFolder)
{
AddressableAssetGroup regGroup = settings.CreateGroup("localNoUWRGroup", false, false, true,
new List<AddressableAssetGroupSchema>(), typeof(BundledAssetGroupSchema));
regGroup.GetSchema<BundledAssetGroupSchema>().BundleNaming = BundledAssetGroupSchema.BundleNamingStyle.OnlyHash;
AddressableAssetGroup forceUWRGroup = settings.CreateGroup("ForceUWRGroup", false, false, true,
new List<AddressableAssetGroupSchema>(), typeof(BundledAssetGroupSchema));
forceUWRGroup.GetSchema<BundledAssetGroupSchema>().UseUnityWebRequestForLocalBundles = true;
forceUWRGroup.GetSchema<BundledAssetGroupSchema>().BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackSeparately;
forceUWRGroup.GetSchema<BundledAssetGroupSchema>().BundleNaming = BundledAssetGroupSchema.BundleNamingStyle.OnlyHash;
settings.MaxConcurrentWebRequests = kMaxConcurrentRequests;
for (int i = 0; i < kForceUWRBundleCount; i++)
{
string s = GetForceUWRAddrName(i);
string guid = CreatePrefab(tempAssetFolder + $"/{s}.prefab");
AddressableAssetEntry entry = settings.CreateOrMoveEntry(guid, forceUWRGroup);
entry.address = s;
}
{
string guid = CreatePrefab(tempAssetFolder + $"/testprefab.prefab");
AddressableAssetEntry entry = settings.CreateOrMoveEntry(guid, regGroup);
entry.address = "testprefab";
}
}
#endif
[SetUp]
public void Setup()
{
#if ENABLE_CACHING
Caching.ClearCache();
#endif
if (m_Addressables != null)
m_Addressables.WebRequestOverride = null;
}
[UnityTest]
[Platform(Exclude = "PS5")]
public IEnumerator WhenUWRExceedsMaxLimit_UWRAreQueued()
{
List<AsyncOperationHandle<GameObject>> l =
Enumerable.Range(0, kForceUWRBundleCount).Select(x => m_Addressables.LoadAssetAsync<GameObject>(GetForceUWRAddrName(x))).ToList();
Assert.AreEqual(kMaxConcurrentRequests, WebRequestQueue.s_ActiveRequests.Count);
Assert.AreEqual((kForceUWRBundleCount - kMaxConcurrentRequests), WebRequestQueue.s_QueuedOperations.Count);
foreach (AsyncOperationHandle<GameObject> h in l)
{
yield return h;
h.Release();
}
}
[UnityTest]
[Platform(Exclude = "PS5")]
public IEnumerator WhenUWRExceedsMaxLimit_CompletesSynchronously()
{
List<AsyncOperationHandle<GameObject>> loadOps =
Enumerable.Range(0, kForceUWRBundleCount).Select(x => m_Addressables.LoadAssetAsync<GameObject>(GetForceUWRAddrName(x))).ToList();
AsyncOperationHandle<GameObject> lastHandle = loadOps[kForceUWRBundleCount - 1];
lastHandle.WaitForCompletion();
lastHandle.Release();
for (int i = 0; i < kForceUWRBundleCount - 1; i++)
{
AsyncOperationHandle<GameObject> handle = loadOps[i];
yield return loadOps[i];
handle.Release();
}
}
[Test]
[Platform(Exclude = "PS5")]
public void WhenUWRIsUsed_CompletesSynchronously()
{
AsyncOperationHandle<GameObject> h = m_Addressables.LoadAssetAsync<GameObject>(GetForceUWRAddrName(0));
h.WaitForCompletion();
h.Release();
}
[UnityTest]
[Platform(Exclude = "PS5")]
public IEnumerator WhenAssetBundleIsLocal_AndForceUWRIsEnabled_UWRIsUsed()
{
AsyncOperationHandle<GameObject> h = m_Addressables.LoadAssetAsync<GameObject>(GetForceUWRAddrName(0));
Assert.AreEqual(1, WebRequestQueue.s_ActiveRequests.Count);
yield return h;
h.Release();
}
[UnityTest]
[Platform(Exclude = "PS5")]
public IEnumerator WhenAssetBundleIsLocal_AndForceUWRIsDisabled_UWRIsNotUsed()
{
AsyncOperationHandle<GameObject> h = m_Addressables.LoadAssetAsync<GameObject>("testprefab");
Assert.AreEqual(0, WebRequestQueue.s_ActiveRequests.Count);
yield return h;
h.Release();
}
[UnityTest]
[Platform(Exclude = "PS5")]
public IEnumerator WhenWebRequestOverrideIsSet_CallbackIsCalled_AssetBundleProvider()
{
bool webRequestOverrideCalled = false;
m_Addressables.WebRequestOverride = request => webRequestOverrideCalled = true;
var prev = LogAssert.ignoreFailingMessages;
LogAssert.ignoreFailingMessages = true;
var nonExistingPath = "http://127.0.0.1/non-existing-bundle";
var loc = new ResourceLocationBase(nonExistingPath, nonExistingPath, typeof(AssetBundleProvider).FullName, typeof(AssetBundleResource));
loc.Data = new AssetBundleRequestOptions();
var h = m_Addressables.ResourceManager.ProvideResource<AssetBundleResource>(loc);
yield return h;
if (h.IsValid()) h.Release();
LogAssert.ignoreFailingMessages = prev;
Assert.IsTrue(webRequestOverrideCalled);
}
[UnityTest]
[Platform(Exclude = "PS5")]
public IEnumerator WhenWebRequestFails_RetriesCorrectAmount_AssetBundleProvider()
{
var prev = LogAssert.ignoreFailingMessages;
LogAssert.ignoreFailingMessages = true;
var nonExistingPath = "http://127.0.0.1/non-existing-bundle";
var loc = new ResourceLocationBase(nonExistingPath, nonExistingPath, typeof(AssetBundleProvider).FullName, typeof(AssetBundleResource));
var d = new AssetBundleRequestOptions();
d.RetryCount = 3;
loc.Data = d;
LogAssert.Expect(LogType.Log, new Regex(@"^(Web request failed, retrying \(0/3)"));
LogAssert.Expect(LogType.Log, new Regex(@"^(Web request failed, retrying \(1/3)"));
LogAssert.Expect(LogType.Log, new Regex(@"^(Web request failed, retrying \(2/3)"));
var h = m_Addressables.ResourceManager.ProvideResource<AssetBundleResource>(loc);
yield return h;
if (h.IsValid()) h.Release();
LogAssert.ignoreFailingMessages = prev;
}
[Test]
[Platform(Exclude = "PS5")]
[TestCase("Relative/Local/Path", true, false)]
[TestCase("Relative/Local/Path", true, true)]
[TestCase("http://127.0.0.1/Web/Path", false, true)]
[TestCase("jar:file://Local/Path", true, false)]
[TestCase("jar:file://Local/Path", true, true)]
public void AssetBundleLoadPathsCorrectForGetLoadInfo(string internalId, bool isLocal, bool useUnityWebRequestForLocalBundles)
{
if (internalId.StartsWith("jar") && Application.platform != RuntimePlatform.Android)
Assert.Ignore($"Skipping test {TestContext.CurrentContext.Test.Name} due jar based tests are only for running on Android Platform.");
var loc = new ResourceLocationBase("dummy", internalId, "dummy", typeof(Object));
loc.Data = new AssetBundleRequestOptions {UseUnityWebRequestForLocalBundles = useUnityWebRequestForLocalBundles};
ProviderOperation<Object> op = new ProviderOperation<Object>();
op.Init(m_Addressables.ResourceManager, null, loc, new AsyncOperationHandle<IList<AsyncOperationHandle>>());
ProvideHandle h = new ProvideHandle(m_Addressables.ResourceManager, op);
AssetBundleResource.GetLoadInfo(h, out AssetBundleResource.LoadType loadType, out string path);
var expectedLoadType = isLocal ? useUnityWebRequestForLocalBundles ? AssetBundleResource.LoadType.Web : AssetBundleResource.LoadType.Local : AssetBundleResource.LoadType.Web;
Assert.AreEqual(expectedLoadType, loadType, "Incorrect load type found for internalId " + internalId);
var expectedPath = internalId;
if (isLocal && useUnityWebRequestForLocalBundles)
{
expectedPath = internalId.StartsWith("jar") ? internalId : "file:///" + Path.GetFullPath(internalId);
}
Assert.AreEqual(expectedPath, path);
}
[UnityTest]
public IEnumerator LoadBundleAsync_WithUnfinishedUnload_WaitsForUnloadAndCompletes()
{
var h = m_Addressables.LoadAssetAsync<GameObject>("testprefab");
yield return h;
Assert.IsNotNull(h.Result);
h.Release();
h = m_Addressables.LoadAssetAsync<GameObject>("testprefab");
yield return h;
Assert.IsNotNull(h.Result);
h.Release();
}
[UnityTest]
public IEnumerator LoadBundleSync_WithUnfinishedUnload_WaitsForUnloadAndCompletes()
{
var h = m_Addressables.LoadAssetAsync<GameObject>("testprefab");
yield return h;
Assert.IsNotNull(h.Result);
h.Release();
h = m_Addressables.LoadAssetAsync<GameObject>("testprefab");
h.WaitForCompletion();
Assert.IsNotNull(h.Result);
h.Release();
}
[Test]
// Only testing against important errors instead of full list
[TestCase("", true)]
[TestCase("Unknown error", true)]
[TestCase("Request aborted", false)]
[TestCase("Unable to write data", false)]
public void UnityWebRequestResult_ShouldRetryReturnsExpected(string error, bool expected)
{
UnityWebRequestResult rst = new UnityWebRequestResult(new UnityWebRequest());
rst.Error = error;
bool result = rst.ShouldRetryDownloadError();
Assert.AreEqual(expected, result, "Unexpected retry value for the input error.");
}
}
#if UNITY_EDITOR
class AssetBundleProviderTests_PackedPlaymodeMode : AssetBundleProviderTests
{
protected override TestBuildScriptMode BuildScriptMode
{
get { return TestBuildScriptMode.PackedPlaymode; }
}
}
#endif
[UnityPlatform(exclude = new[] {RuntimePlatform.WindowsEditor, RuntimePlatform.OSXEditor, RuntimePlatform.LinuxEditor})]
class AssetBundleProviderTests_PackedMode : AssetBundleProviderTests
{
protected override TestBuildScriptMode BuildScriptMode
{
get { return TestBuildScriptMode.Packed; }
}
}
}