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

291 lines
11 KiB
C#
Raw Normal View History

2025-01-07 02:06:59 +01:00
using NUnit.Framework;
using System.Collections;
using System.IO;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.AddressableAssets.Build;
using UnityEditor.AddressableAssets.Settings;
using UnityEditor.AddressableAssets.Build.DataBuilders;
using UnityEditor.SceneManagement;
#endif
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.Util;
using UnityEngine.TestTools;
using System;
using UnityEngine;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;
using Object = UnityEngine.Object;
public abstract class AddressablesTestFixture : IPrebuildSetup, IPostBuildCleanup
{
internal AddressablesImpl m_Addressables;
internal string m_RuntimeSettingsPath;
internal readonly string m_UniqueTestName;
protected const string kCatalogExt =
#if ENABLE_BINARY_CATALOG
".bin";
#else
".json";
#endif
protected AddressablesTestFixture()
{
m_UniqueTestName = this.GetType().Name;
}
protected enum TestBuildScriptMode
{
Fast,
Virtual,
PackedPlaymode,
Packed
}
protected virtual TestBuildScriptMode BuildScriptMode { get; }
protected string GetGeneratedAssetsPath()
{
return Path.Combine("Assets", "gen", m_UniqueTestName);
}
[UnitySetUp]
public virtual IEnumerator RuntimeSetup()
{
#if ENABLE_CACHING
Caching.ClearCache();
#endif
Assert.IsNull(m_Addressables);
m_Addressables = new AddressablesImpl(new LRUCacheAllocationStrategy(1000, 1000, 100, 10));
m_RuntimeSettingsPath = m_Addressables.ResolveInternalId(GetRuntimeAddressablesSettingsPath(m_UniqueTestName));
var op = m_Addressables.InitializeAsync(m_RuntimeSettingsPath, null, false);
yield return op;
Assert.AreEqual(AsyncOperationStatus.Succeeded, op.Status);
OnRuntimeSetup();
if (op.IsValid())
op.Release();
}
protected virtual void OnRuntimeSetup()
{
}
[TearDown]
public virtual void RuntimeTeardown()
{
m_Addressables.ResourceManager.Dispose();
m_Addressables = null;
}
void IPrebuildSetup.Setup()
{
#if UNITY_EDITOR
bool currentIgnoreState = LogAssert.ignoreFailingMessages;
LogAssert.ignoreFailingMessages = true;
var activeScenePath = EditorSceneManager.GetActiveScene().path;
string rootFolder = GetGeneratedAssetsPath();
AddressableAssetSettings settings = CreateSettings("Settings", rootFolder);
Setup(settings, rootFolder);
RunBuilder(settings);
if (activeScenePath != EditorSceneManager.GetActiveScene().path)
EditorSceneManager.OpenScene(activeScenePath, OpenSceneMode.Single);
LogAssert.ignoreFailingMessages = currentIgnoreState;
#endif
}
void IPostBuildCleanup.Cleanup()
{
#if UNITY_EDITOR
string path = Path.Combine("Assets", "gen");
if (Directory.Exists(path))
AssetDatabase.DeleteAsset(path);
#endif
}
#if UNITY_EDITOR
internal virtual void Setup(AddressableAssetSettings settings, string tempAssetFolder)
{
}
protected AddressableAssetSettings CreateSettings(string name, string rootFolder)
{
if (Directory.Exists(rootFolder))
Directory.Delete(rootFolder, true);
Directory.CreateDirectory(rootFolder);
return AddressableAssetSettings.Create(Path.Combine(rootFolder, name), "AddressableAssetSettings.Tests", false, true);
}
protected virtual void RunBuilder(AddressableAssetSettings settings)
{
RunBuilder(settings, m_UniqueTestName);
}
protected void RunBuilder(AddressableAssetSettings settings, string id)
{
var buildContext = new AddressablesDataBuilderInput(settings);
buildContext.RuntimeSettingsFilename = "settings" + id + ".json";
buildContext.RuntimeCatalogFilename = "catalog" + id + kCatalogExt;
// buildContext.PathFormat = "{0}" + Addressables.LibraryPath + "{1}_" + id + kCatalogExt;
buildContext.PathSuffix = "_" + id;
if (BuildScriptMode == TestBuildScriptMode.PackedPlaymode)
{
IDataBuilder packedModeBuilder = GetBuilderOfType(settings, typeof(BuildScriptPackedMode));
packedModeBuilder.BuildData<AddressableAssetBuildResult>(buildContext);
}
IDataBuilder b = GetBuilderOfType(settings, GetBuildScriptTypeFromMode(BuildScriptMode));
b.BuildData<AddressableAssetBuildResult>(buildContext);
PlayerPrefs.SetString(Addressables.kAddressablesRuntimeDataPath + id, PlayerPrefs.GetString(Addressables.kAddressablesRuntimeDataPath, ""));
}
static IDataBuilder GetBuilderOfType(AddressableAssetSettings settings, Type modeType)
{
foreach (var db in settings.DataBuilders)
{
var b = db;
if (b.GetType() == modeType)
return b as IDataBuilder;
}
throw new Exception("DataBuilder not found");
}
protected Type GetBuildScriptTypeFromMode(TestBuildScriptMode mode)
{
switch (mode)
{
case TestBuildScriptMode.Fast: return typeof(BuildScriptFastMode);
case TestBuildScriptMode.Virtual: return typeof(BuildScriptVirtualMode);
case TestBuildScriptMode.Packed: return typeof(BuildScriptPackedMode);
case TestBuildScriptMode.PackedPlaymode: return typeof(BuildScriptPackedPlayMode);
}
throw new Exception("Unknown script mode");
}
#endif
protected string GetRuntimeAddressablesSettingsPath(string id)
{
if (BuildScriptMode == TestBuildScriptMode.Packed || BuildScriptMode == TestBuildScriptMode.PackedPlaymode)
return "{UnityEngine.AddressableAssets.Addressables.RuntimePath}/settings" + id + ".json";
else if (BuildScriptMode == TestBuildScriptMode.Fast)
{
return PlayerPrefs.GetString(Addressables.kAddressablesRuntimeDataPath + id, "");
}
else
{
return string.Format("{0}" + Addressables.LibraryPath + "settings_{1}.json", "file://{UnityEngine.Application.dataPath}/../", id);
}
}
internal static string CreateAssetPath(string rootFolder, string key, string extension)
{
return Path.Combine(rootFolder, String.Concat(key, extension));
}
#if UNITY_EDITOR
internal static string CreateScene(string assetPath)
{
var scene = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Additive);
EditorSceneManager.SaveScene(scene, assetPath);
return AssetDatabase.AssetPathToGUID(scene.path);
}
internal static string CreatePrefab(string assetPath)
{
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube);
PrefabUtility.SaveAsPrefabAsset(go, assetPath);
Object.DestroyImmediate(go, false);
return AssetDatabase.AssetPathToGUID(assetPath);
}
protected string CreateFolderDeep(string path)
{
path = path.Replace('\\', '/');
if (!path.StartsWith("Assets/", StringComparison.Ordinal))
return null;
if (Directory.Exists(path))
{
if (AssetDatabase.IsValidFolder(path))
return AssetDatabase.AssetPathToGUID(path);
AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
return AssetDatabase.AssetPathToGUID(path);
}
Directory.CreateDirectory(path);
AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
return AssetDatabase.AssetPathToGUID(path);
}
protected string CreateAsset(string assetPath, string objectName = null)
{
if (string.IsNullOrEmpty(objectName))
objectName = Path.GetFileNameWithoutExtension(assetPath);
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube);
go.name = objectName;
//this is to ensure that bundles are different for every run.
go.transform.localPosition = UnityEngine.Random.onUnitSphere;
var mat = new Material(Shader.Find("Standard"));
var tex = new Texture2D(32, 32);
var texPath = assetPath.Replace(".prefab", ".png");
File.WriteAllBytes(texPath, tex.EncodeToPNG());
AssetDatabase.ImportAsset(texPath, ImportAssetOptions.ForceSynchronousImport);
mat.mainTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(texPath);
var matPath = assetPath.Replace(".prefab", ".mat");
AssetDatabase.CreateAsset(mat, matPath);
AssetDatabase.ImportAsset(matPath, ImportAssetOptions.ForceSynchronousImport);
go.GetComponent<MeshRenderer>().sharedMaterial = AssetDatabase.LoadAssetAtPath<Material>(matPath);
string directoryName = Path.GetDirectoryName(assetPath);
CreateFolderDeep(directoryName);
try
{
Assert.IsTrue(AssetDatabase.IsValidFolder(directoryName), "Attempting to save prefab to invalid Folder : " + directoryName);
Assert.IsTrue(Directory.Exists(directoryName), "Folder is not in FileSystem, but is in ADB : " + directoryName);
Assert.IsNotNull(go, "Attempting to save null GameObject to Prefab");
PrefabUtility.SaveAsPrefabAsset(go, assetPath);
}
catch (Exception e)
{
Debug.LogError($"Error while attempting to save prefab {objectName} to {assetPath} with Exception message {e.Message}");
throw e;
}
UnityEngine.Object.DestroyImmediate(go, false);
return AssetDatabase.AssetPathToGUID(assetPath);
}
#endif
internal static IEnumerator UnloadSceneFromHandler(AsyncOperationHandle<SceneInstance> op, AddressablesImpl addressables)
{
string sceneName = op.Result.Scene.name;
Assert.IsNotNull(sceneName);
var unloadOp = addressables.UnloadSceneAsync(op, UnloadSceneOptions.None, false);
yield return unloadOp;
Assert.AreEqual(AsyncOperationStatus.Succeeded, unloadOp.Status);
Assert.IsFalse(unloadOp.Result.Scene.isLoaded);
Assert.IsTrue(unloadOp.IsDone);
addressables.Release(unloadOp);
Assert.IsNull(SceneManager.GetSceneByName(sceneName).name);
}
internal static IEnumerator UnloadSceneFromHandlerRefCountCheck(AsyncOperationHandle<SceneInstance> op, AddressablesImpl addressables)
{
string sceneName = op.Result.Scene.name;
Assert.IsNotNull(sceneName);
var prevRefCount = op.ReferenceCount;
var unloadOp = addressables.UnloadSceneAsync(op, UnloadSceneOptions.None, false);
yield return unloadOp;
Assert.AreEqual(AsyncOperationStatus.Succeeded, unloadOp.Status);
Assert.IsFalse(unloadOp.Result.Scene.isLoaded);
if (op.IsValid())
Assert.AreEqual(prevRefCount - 1, op.ReferenceCount);
}
}