initial commit
This commit is contained in:
parent
6715289efe
commit
788c3389af
37645 changed files with 2526849 additions and 80 deletions
|
|
@ -0,0 +1,81 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AddressableAssets.Build.BuildPipelineTasks;
|
||||
using UnityEditor.AddressableAssets.Build.DataBuilders;
|
||||
using UnityEditor.AddressableAssets.Settings;
|
||||
using UnityEditor.Build.Content;
|
||||
using UnityEditor.Build.Pipeline;
|
||||
using UnityEditor.Build.Pipeline.Interfaces;
|
||||
using UnityEditor.Build.Pipeline.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
public class AddHashToBundleNameTaskTests : AddressableBuildTaskTestBase
|
||||
{
|
||||
[Test]
|
||||
public void AddHashToBundleNameTask_DoesNotChangeHash_WhenAssetsChangeOrder()
|
||||
{
|
||||
//Setup
|
||||
string path1 = $"{TempPath}/test1.prefab";
|
||||
string path2 = $"{TempPath}/test2.prefab";
|
||||
string path3 = $"{TempPath}/test3.prefab";
|
||||
|
||||
GUID guid1 = new GUID(CreateAsset(path1, "1"));
|
||||
GUID guid2 = new GUID(CreateAsset(path2, "2"));
|
||||
GUID guid3 = new GUID(CreateAsset(path3, "3"));
|
||||
|
||||
List<GUID> list1 = new List<GUID>()
|
||||
{
|
||||
guid1,
|
||||
guid2,
|
||||
guid3
|
||||
};
|
||||
|
||||
List<GUID> list2 = new List<GUID>()
|
||||
{
|
||||
guid2,
|
||||
guid1,
|
||||
guid3
|
||||
};
|
||||
|
||||
AddressableAssetGroup group = m_Settings.CreateGroup("AddHashTestGroup", false, false, false,
|
||||
new List<AddressableAssetGroupSchema>());
|
||||
m_Settings.CreateOrMoveEntry(guid1.ToString(), group);
|
||||
m_Settings.CreateOrMoveEntry(guid2.ToString(), group);
|
||||
m_Settings.CreateOrMoveEntry(guid3.ToString(), group);
|
||||
|
||||
IDependencyData dependencyData = new BuildDependencyData()
|
||||
{
|
||||
AssetInfo =
|
||||
{
|
||||
{guid1, new AssetLoadInfo() {referencedObjects = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(guid1, EditorUserBuildSettings.activeBuildTarget).ToList()}},
|
||||
{guid2, new AssetLoadInfo() {referencedObjects = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(guid2, EditorUserBuildSettings.activeBuildTarget).ToList()}},
|
||||
{
|
||||
guid3, new AssetLoadInfo() {referencedObjects = ContentBuildInterface.GetPlayerObjectIdentifiersInAsset(guid3, EditorUserBuildSettings.activeBuildTarget).ToList()}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddressableAssetsBuildContext context = new AddressableAssetsBuildContext()
|
||||
{
|
||||
Settings = m_Settings
|
||||
};
|
||||
|
||||
AddHashToBundleNameTask addHashTask = new AddHashToBundleNameTask();
|
||||
var field = typeof(AddHashToBundleNameTask).GetField("m_DependencyData", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
field.SetValue(addHashTask, dependencyData);
|
||||
|
||||
//Test
|
||||
RawHash hash1 = addHashTask.GetAssetsHash(list1, context);
|
||||
RawHash hash2 = addHashTask.GetAssetsHash(list2, context);
|
||||
|
||||
//Assert
|
||||
Assert.AreEqual(hash1, hash2);
|
||||
|
||||
//Cleanup
|
||||
m_Settings.RemoveGroup(group);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 47c8f9980c2f63349a8fb20e6e1b5013
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AddressableAssets.Build.BuildPipelineTasks;
|
||||
using UnityEditor.AddressableAssets.Settings;
|
||||
using UnityEngine;
|
||||
|
||||
public class AddressableBuildTaskTestBase
|
||||
{
|
||||
protected AddressableAssetSettings m_Settings;
|
||||
|
||||
protected string TempPath
|
||||
{
|
||||
get { return $"Assets/{GetType().Name}TestData"; }
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
using (new IgnoreFailingLogMessage())
|
||||
{
|
||||
if (AssetDatabase.IsValidFolder(TempPath))
|
||||
AssetDatabase.DeleteAsset(TempPath);
|
||||
Directory.CreateDirectory(TempPath);
|
||||
|
||||
m_Settings = AddressableAssetSettings.Create(Path.Combine(TempPath, "Settings"),
|
||||
"AddressableAssetSettings.Tests", false, true);
|
||||
}
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void Teardown()
|
||||
{
|
||||
// Many of the tests keep recreating assets in the same path, so we need to unload them completely so they don't get reused by the next test
|
||||
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(m_Settings));
|
||||
Resources.UnloadAsset(m_Settings);
|
||||
if (Directory.Exists(TempPath))
|
||||
Directory.Delete(TempPath, true);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
protected static string CreateAsset(string assetPath, string objectName)
|
||||
{
|
||||
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;
|
||||
PrefabUtility.SaveAsPrefabAsset(go, assetPath);
|
||||
UnityEngine.Object.DestroyImmediate(go, false);
|
||||
return AssetDatabase.AssetPathToGUID(assetPath);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0fc8c72284fb9414ca3384e659772838
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
#if UNITY_2021_2_OR_NEWER
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AddressableAssets;
|
||||
using UnityEditor.AddressableAssets.Settings;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
|
||||
public class AddressablesPlayerBuildProcessorTests
|
||||
{
|
||||
protected static string TestFolder => $"Assets/AddressablesPlayerBuildProcessor_Tests";
|
||||
protected static string ConfigFolder => TestFolder + "/Config";
|
||||
|
||||
AddressableAssetSettings m_Settings;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
DirectoryUtility.DeleteDirectory(TestFolder, false);
|
||||
Directory.CreateDirectory(ConfigFolder);
|
||||
m_Settings = AddressableAssetSettings.Create(ConfigFolder, "AddressableAssetSettings.Tests", true, true);
|
||||
CreateAddressablePrefab("test");
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void Teardown()
|
||||
{
|
||||
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(m_Settings));
|
||||
Resources.UnloadAsset(m_Settings);
|
||||
DirectoryUtility.DeleteDirectory(TestFolder, false);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
AddressableAssetEntry CreateAddressablePrefab(string name, AddressableAssetGroup group = null)
|
||||
{
|
||||
string guid = CreateAsset(name);
|
||||
return MakeAddressable(guid, null, group);
|
||||
}
|
||||
|
||||
static string CreateAsset(string name)
|
||||
{
|
||||
string assetPath = $"{TestFolder}/{name}.prefab";
|
||||
return CreateAsset(assetPath, name);
|
||||
}
|
||||
|
||||
static string CreateAsset(string assetPath, string objectName)
|
||||
{
|
||||
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;
|
||||
PrefabUtility.SaveAsPrefabAsset(go, assetPath);
|
||||
UnityEngine.Object.DestroyImmediate(go, false);
|
||||
return AssetDatabase.AssetPathToGUID(assetPath);
|
||||
}
|
||||
|
||||
AddressableAssetEntry MakeAddressable(string guid, string address = null, AddressableAssetGroup group = null)
|
||||
{
|
||||
if (group == null)
|
||||
{
|
||||
if (m_Settings.DefaultGroup == null)
|
||||
throw new System.Exception("No DefaultGroup to assign Addressable to");
|
||||
group = m_Settings.DefaultGroup;
|
||||
}
|
||||
|
||||
var entry = m_Settings.CreateOrMoveEntry(guid, group, false, false);
|
||||
entry.address = address == null ? entry.AssetPath : address;
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
[TestCase(AddressableAssetSettings.PlayerBuildOption.DoNotBuildWithPlayer, false)]
|
||||
[TestCase(AddressableAssetSettings.PlayerBuildOption.BuildWithPlayer, false)]
|
||||
[TestCase(AddressableAssetSettings.PlayerBuildOption.PreferencesValue, false)]
|
||||
[TestCase(AddressableAssetSettings.PlayerBuildOption.PreferencesValue, true)]
|
||||
public void PrepareAddressableBuildForPlayerBuild_ShouldBuildAddressables_CorrectForSettings(int settingValue, bool preferencesValue)
|
||||
{
|
||||
// Setup
|
||||
m_Settings.BuildAddressablesWithPlayerBuild = (AddressableAssetSettings.PlayerBuildOption)settingValue;
|
||||
bool deleteKey = !EditorPrefs.HasKey(AddressablesPreferences.kBuildAddressablesWithPlayerBuildKey);
|
||||
bool previousPrefValue = EditorPrefs.GetBool(AddressablesPreferences.kBuildAddressablesWithPlayerBuildKey, true);
|
||||
EditorPrefs.SetBool(AddressablesPreferences.kBuildAddressablesWithPlayerBuildKey, preferencesValue);
|
||||
|
||||
try
|
||||
{
|
||||
bool result = AddressablesPlayerBuildProcessor.ShouldBuildAddressablesForPlayerBuild(m_Settings);
|
||||
if (m_Settings.BuildAddressablesWithPlayerBuild == AddressableAssetSettings.PlayerBuildOption.BuildWithPlayer)
|
||||
Assert.IsTrue(result, "Addressables build was expected to set to build when preparing a Player Build");
|
||||
else if (m_Settings.BuildAddressablesWithPlayerBuild == AddressableAssetSettings.PlayerBuildOption.DoNotBuildWithPlayer)
|
||||
Assert.IsFalse(result, "Addressables build is not expected to set be build when preparing a Player Build");
|
||||
else if (m_Settings.BuildAddressablesWithPlayerBuild == AddressableAssetSettings.PlayerBuildOption.DoNotBuildWithPlayer)
|
||||
{
|
||||
if (preferencesValue)
|
||||
Assert.IsTrue(result, "Addressables build was expected to set to build when preparing a Player Build");
|
||||
else
|
||||
Assert.IsFalse(result, "Addressables build is not expected to set be build when preparing a Player Build");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Assert.Fail("Unhandled Exception in Preparing for Addressables - With Exception: " + e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (deleteKey)
|
||||
EditorPrefs.DeleteKey(AddressablesPreferences.kBuildAddressablesWithPlayerBuildKey);
|
||||
else
|
||||
EditorPrefs.SetBool(AddressablesPreferences.kBuildAddressablesWithPlayerBuildKey, previousPrefValue);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PrepareAddressableBuildForPlayerBuild_LinkXML_CopiedCorrectly()
|
||||
{
|
||||
string buildPath = Addressables.BuildPath + "/AddressablesLink/link.xml";
|
||||
Directory.CreateDirectory(Addressables.BuildPath + "/AddressablesLink");
|
||||
bool preexistingFile = File.Exists(buildPath);
|
||||
|
||||
if (!preexistingFile)
|
||||
{
|
||||
var textStream = File.CreateText(buildPath);
|
||||
textStream.Write("link test file");
|
||||
textStream.Close();
|
||||
}
|
||||
|
||||
// do the test
|
||||
string projectPath = Path.Combine(m_Settings.ConfigFolder, "link.xml");
|
||||
try
|
||||
{
|
||||
AddressablesPlayerBuildProcessor.PrepareForPlayerbuild(m_Settings, null, false);
|
||||
Assert.IsTrue(File.Exists(projectPath), "Link.xml file not found at project path when preparing for build");
|
||||
}
|
||||
// clean up
|
||||
finally
|
||||
{
|
||||
AddressablesPlayerBuildProcessor.RemovePlayerBuildLinkXML(m_Settings);
|
||||
if (!preexistingFile)
|
||||
File.Delete(buildPath);
|
||||
Assert.IsFalse(File.Exists(projectPath), "Link.xml file remains at the ProjectPath, link.xml expected to be deleted");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 41f1a51b4873d473d81bc70abb55d198
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,719 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AddressableAssets.Build.BuildPipelineTasks;
|
||||
using UnityEditor.AddressableAssets.Build.DataBuilders;
|
||||
using UnityEditor.AddressableAssets.Build.Layout;
|
||||
using UnityEditor.AddressableAssets.Settings;
|
||||
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
|
||||
using UnityEditor.AddressableAssets.Tests;
|
||||
using UnityEditor.Build.Pipeline.Utilities;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.U2D;
|
||||
using UnityEditor.U2D;
|
||||
using UnityEditor.Presets;
|
||||
|
||||
public class BuildLayoutGenerationTaskTests
|
||||
{
|
||||
AddressableAssetSettings m_Settings;
|
||||
|
||||
AddressableAssetSettings Settings
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Settings == null)
|
||||
{
|
||||
var path = Path.Combine(TempPath, "Settings", "/AddressableAssetSettings.Tests.asset");
|
||||
m_Settings = AssetDatabase.LoadAssetAtPath<AddressableAssetSettings>(path);
|
||||
}
|
||||
|
||||
return m_Settings;
|
||||
}
|
||||
}
|
||||
|
||||
static string kTempPath = "Assets/BuildLayoutGenerationTaskTestsData";
|
||||
static string TempPath;
|
||||
static int ExecCount;
|
||||
bool m_PrevGenerateBuildLayout;
|
||||
ProjectConfigData.ReportFileFormat m_PrevFileFormat;
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void OneTimeSetup()
|
||||
{
|
||||
ExecCount = 0;
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
TempPath = kTempPath + (ExecCount++).ToString();
|
||||
foreach (var fileFormat in Enum.GetValues(typeof(ProjectConfigData.ReportFileFormat)))
|
||||
{
|
||||
string layoutFile = BuildLayoutGenerationTask.GetLayoutFilePathForFormat((ProjectConfigData.ReportFileFormat)fileFormat);
|
||||
if (File.Exists(layoutFile))
|
||||
File.Delete(layoutFile);
|
||||
}
|
||||
|
||||
m_PrevGenerateBuildLayout = ProjectConfigData.GenerateBuildLayout;
|
||||
m_PrevFileFormat = ProjectConfigData.BuildLayoutReportFileFormat;
|
||||
BuildScriptPackedMode.s_SkipCompilePlayerScripts = true;
|
||||
ProjectConfigData.GenerateBuildLayout = true;
|
||||
if (Directory.Exists(TempPath))
|
||||
Directory.Delete(TempPath, true);
|
||||
Directory.CreateDirectory(TempPath);
|
||||
|
||||
m_Settings = AddressableAssetSettings.Create(Path.Combine(TempPath, "Settings"), "AddressableAssetSettings.Tests", false, true);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void Teardown()
|
||||
{
|
||||
BuildScriptPackedMode.s_SkipCompilePlayerScripts = false;
|
||||
ProjectConfigData.GenerateBuildLayout = m_PrevGenerateBuildLayout;
|
||||
ProjectConfigData.BuildLayoutReportFileFormat = m_PrevFileFormat;
|
||||
// Many of the tests keep recreating assets in the same path, so we need to unload them completely so they don't get reused by the next test
|
||||
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(Settings));
|
||||
Resources.UnloadAsset(Settings);
|
||||
|
||||
FileUtil.DeleteFileOrDirectory(TempPath);
|
||||
FileUtil.DeleteFileOrDirectory(TempPath + ".meta");
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
string MakeAddressable(AddressableAssetGroup group, string guid, string address = null)
|
||||
{
|
||||
var entry = Settings.CreateOrMoveEntry(guid, group, false, false);
|
||||
entry.address = address == null ? Path.GetFileNameWithoutExtension(entry.AssetPath) : address;
|
||||
entry.BundleFileId = "GenericFileId";
|
||||
return guid;
|
||||
}
|
||||
|
||||
// Prefab asset emthods
|
||||
|
||||
static string CreatePrefabAsset(string name)
|
||||
{
|
||||
return CreatePrefabAsset($"{TempPath}/{name}.prefab", name);
|
||||
}
|
||||
|
||||
static string CreatePrefabAsset(string assetPath, string objectName)
|
||||
{
|
||||
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;
|
||||
PrefabUtility.SaveAsPrefabAsset(go, assetPath);
|
||||
UnityEngine.Object.DestroyImmediate(go, false);
|
||||
return AssetDatabase.AssetPathToGUID(assetPath);
|
||||
}
|
||||
|
||||
static string CreateScriptableObjectAsset(string assetPath, string objectName)
|
||||
{
|
||||
TestObject.Create(objectName, assetPath);
|
||||
return AssetDatabase.AssetPathToGUID(assetPath);
|
||||
}
|
||||
|
||||
string CreateAddressablePrefab(string name, AddressableAssetGroup group)
|
||||
{
|
||||
string guid = CreatePrefabAsset($"{TempPath}/{name}.prefab", name);
|
||||
return MakeAddressable(group, guid);
|
||||
}
|
||||
|
||||
string CreateAddressableScriptableObject(string name, AddressableAssetGroup group)
|
||||
{
|
||||
string guid = CreateScriptableObjectAsset($"{TempPath}/{name}.asset", name);
|
||||
return MakeAddressable(group, guid);
|
||||
}
|
||||
|
||||
bool DeletePrefab(string name)
|
||||
{
|
||||
string path = $"{TempPath}/{name}.prefab";
|
||||
return AssetDatabase.DeleteAsset(path);
|
||||
}
|
||||
|
||||
bool DeleteScriptableObject(string name)
|
||||
{
|
||||
string path = $"{TempPath}/{name}.asset";
|
||||
return AssetDatabase.DeleteAsset(path);
|
||||
}
|
||||
|
||||
// Texture asset creation
|
||||
|
||||
static string CreateTexture(string name, int size = 32)
|
||||
{
|
||||
string assetPath = $"{TempPath}/{name}.png";
|
||||
var texture = new Texture2D(size, size);
|
||||
var data = ImageConversion.EncodeToPNG(texture);
|
||||
UnityEngine.Object.DestroyImmediate(texture);
|
||||
File.WriteAllBytes(assetPath, data);
|
||||
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate);
|
||||
return AssetDatabase.AssetPathToGUID(assetPath);
|
||||
}
|
||||
|
||||
string CreateAddressableTexture(string name, AddressableAssetGroup group, int size = 32)
|
||||
{
|
||||
string guid = CreateTexture(name, size);
|
||||
TextureImporter ti = (TextureImporter)AssetImporter.GetAtPath(AssetDatabase.GUIDToAssetPath(guid));
|
||||
ti.isReadable = false;
|
||||
ti.SaveAndReimport();
|
||||
return MakeAddressable(group, guid);
|
||||
}
|
||||
|
||||
static string CreateSpriteAtlas(string name, string guidTargetTexture)
|
||||
{
|
||||
var sa = new SpriteAtlas();
|
||||
var targetObjects = new UnityEngine.Object[] {AssetDatabase.LoadAssetAtPath<Texture>(AssetDatabase.GUIDToAssetPath(guidTargetTexture))};
|
||||
sa.Add(targetObjects);
|
||||
string saPath = $"{TempPath}/{name}.spriteAtlas";
|
||||
AssetDatabase.CreateAsset(sa, saPath);
|
||||
AssetDatabase.Refresh();
|
||||
return AssetDatabase.AssetPathToGUID(saPath);
|
||||
}
|
||||
|
||||
bool DeleteSpriteAtlas(string name)
|
||||
{
|
||||
string assetPath = $"{TempPath}/{name}.spriteAtlas";
|
||||
return AssetDatabase.DeleteAsset(assetPath);
|
||||
}
|
||||
|
||||
static string CreateSpriteTexture(string name, int size, bool includesSource)
|
||||
{
|
||||
string guid = CreateTexture(name, size);
|
||||
string texturePath = AssetDatabase.GUIDToAssetPath(guid);
|
||||
TextureImporter importer = (TextureImporter)AssetImporter.GetAtPath(AssetDatabase.GUIDToAssetPath(guid));
|
||||
importer.textureType = TextureImporterType.Sprite; // creates a sprite subobject
|
||||
importer.spriteImportMode = SpriteImportMode.Single;
|
||||
importer.SaveAndReimport();
|
||||
return guid;
|
||||
}
|
||||
|
||||
bool DeleteTexture(string name)
|
||||
{
|
||||
string assetPath = $"{TempPath}/{name}.png";
|
||||
return AssetDatabase.DeleteAsset(assetPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a component to Prefab that references assetToReference
|
||||
/// </summary>
|
||||
/// <param name="prefabGUID"></param>
|
||||
/// <param name="assetToReferenceGUID"></param>
|
||||
void MakePefabReference(string prefabGUID, string assetToReferenceGUID)
|
||||
{
|
||||
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(AssetDatabase.GUIDToAssetPath(prefabGUID));
|
||||
UnityEngine.Object target = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(AssetDatabase.GUIDToAssetPath(assetToReferenceGUID));
|
||||
prefab.AddComponent<TestBehaviourWithReference>().Reference = target;
|
||||
}
|
||||
|
||||
AddressableAssetGroup CreateGroup(string name)
|
||||
{
|
||||
return Settings.CreateGroup(name, false, false, false, null, typeof(BundledAssetGroupSchema));
|
||||
}
|
||||
|
||||
void PrintText(BuildLayout layout)
|
||||
{
|
||||
MemoryStream stream = new MemoryStream();
|
||||
BuildLayoutPrinter.WriteBundleLayout(stream, layout);
|
||||
string report = Encoding.ASCII.GetString(stream.ToArray());
|
||||
Debug.Log(report);
|
||||
}
|
||||
|
||||
internal BuildLayout BuildAndExtractLayout()
|
||||
{
|
||||
try
|
||||
{
|
||||
BuildLayout layout = null;
|
||||
BuildLayoutGenerationTask.s_LayoutCompleteCallback = (x, y) => layout = y;
|
||||
Settings.BuildPlayerContentImpl();
|
||||
return layout;
|
||||
}
|
||||
finally
|
||||
{
|
||||
BuildLayoutGenerationTask.s_LayoutCompleteCallback = null;
|
||||
}
|
||||
}
|
||||
|
||||
class WebExtractSession : IDisposable
|
||||
{
|
||||
public string DataDirectory;
|
||||
public string[] Files;
|
||||
|
||||
public WebExtractSession(string filePath)
|
||||
{
|
||||
DataDirectory = filePath + "_data";
|
||||
if (Directory.Exists(DataDirectory))
|
||||
throw new Exception("Bundle data directory already exists");
|
||||
|
||||
var baseDir = Path.GetDirectoryName(EditorApplication.applicationPath);
|
||||
var webExtractFiles = Directory.GetFiles(baseDir, "WebExtract*", SearchOption.AllDirectories);
|
||||
string webExtractPath = webExtractFiles[0];
|
||||
|
||||
Assert.IsTrue(File.Exists(filePath), "Param filePath does not point to an existing file.");
|
||||
|
||||
var process = new System.Diagnostics.Process
|
||||
{
|
||||
StartInfo =
|
||||
{
|
||||
FileName = webExtractPath,
|
||||
Arguments = string.Format(@"""{0}""", filePath),
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true
|
||||
}
|
||||
};
|
||||
process.Start();
|
||||
|
||||
var output = process.StandardOutput.ReadToEnd();
|
||||
process.WaitForExit();
|
||||
|
||||
var exitCode = process.ExitCode;
|
||||
process.Close();
|
||||
|
||||
Assert.AreEqual(0, exitCode);
|
||||
Files = Directory.GetFiles(DataDirectory);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Directory.Delete(DataDirectory, true);
|
||||
}
|
||||
}
|
||||
|
||||
internal void AssertEditorBundleDetailsMatchPhysicalBundle(string bundlePath, BuildLayout.Bundle bundle)
|
||||
{
|
||||
Assert.AreEqual(new FileInfo(bundlePath).Length, bundle.FileSize);
|
||||
using (var wes = new WebExtractSession(bundlePath))
|
||||
{
|
||||
Assert.AreEqual(bundle.Files.Sum(x => x.SubFiles.Count), wes.Files.Length);
|
||||
foreach (BuildLayout.SubFile sf in bundle.Files.SelectMany(x => x.SubFiles))
|
||||
{
|
||||
string filename = Path.Combine(wes.DataDirectory, sf.Name);
|
||||
Assert.AreEqual(sf.Size, new FileInfo(filename).Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenBundleReferencesAnotherBundle_ExternalReferenceExists()
|
||||
{
|
||||
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
|
||||
AddressableAssetGroup group = null;
|
||||
AddressableAssetGroup group2 = null;
|
||||
|
||||
try
|
||||
{
|
||||
// setup
|
||||
group = CreateGroup("Group1");
|
||||
string prefabGUID = CreateAddressablePrefab("p1", group);
|
||||
group2 = CreateGroup("Group2");
|
||||
string g2p1GUID = CreateAddressablePrefab("g2p1", group2);
|
||||
MakePefabReference(prefabGUID, g2p1GUID);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
BuildLayout layout = BuildAndExtractLayout();
|
||||
|
||||
// Test
|
||||
CollectionAssert.Contains(layout.Groups[0].Bundles[0].Dependencies, layout.Groups[1].Bundles[0]);
|
||||
Assert.AreEqual(layout.Groups[0].Bundles[0].Files[0].Assets[0].ExternallyReferencedAssets[0], layout.Groups[1].Bundles[0].Files[0].Assets[0]);
|
||||
}
|
||||
finally // cleanup
|
||||
{
|
||||
if (group != null)
|
||||
Settings.RemoveGroup(group);
|
||||
if (group2 != null)
|
||||
Settings.RemoveGroup(group2);
|
||||
if (File.Exists(layoutFilePath))
|
||||
File.Delete(layoutFilePath);
|
||||
DeletePrefab("p1");
|
||||
DeletePrefab("g2p1");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenAssetImplicitlyPulledIntoBundle_ImplicitEntryAndReferencesCreated()
|
||||
{
|
||||
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
|
||||
AddressableAssetGroup group = null;
|
||||
|
||||
try
|
||||
{
|
||||
// setup
|
||||
group = CreateGroup("Group1");
|
||||
string prefabGUID = CreateAddressablePrefab("p1", group);
|
||||
string aGUID = CreatePrefabAsset("p2");
|
||||
MakePefabReference(prefabGUID, aGUID);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
BuildLayout layout = BuildAndExtractLayout();
|
||||
|
||||
// Test
|
||||
BuildLayout.DataFromOtherAsset oa = layout.Groups[0].Bundles[0].Files[0].OtherAssets.First(x => x.AssetPath.Contains("p2.prefab"));
|
||||
Assert.AreEqual(aGUID, oa.AssetGuid);
|
||||
}
|
||||
finally // cleanup
|
||||
{
|
||||
if (group != null)
|
||||
Settings.RemoveGroup(group);
|
||||
if (File.Exists(layoutFilePath))
|
||||
File.Delete(layoutFilePath);
|
||||
DeletePrefab("p1");
|
||||
DeletePrefab("p2");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenBundleContainsMultipleFiles_FilesAndSizesMatchArchiveContent()
|
||||
{
|
||||
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
|
||||
string scenePath = $"{TempPath}/scene.unity";
|
||||
AddressableAssetGroup groupScenes = null;
|
||||
AddressableAssetGroup textureGroup = null;
|
||||
|
||||
try
|
||||
{
|
||||
// setup
|
||||
groupScenes = CreateGroup("SceneGroup");
|
||||
textureGroup = CreateGroup("TextureGroup");
|
||||
|
||||
Scene scene1 = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
|
||||
new GameObject().AddComponent<TestBehaviourWithReference>();
|
||||
EditorSceneManager.SaveScene(scene1, scenePath);
|
||||
Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(scenePath), groupScenes);
|
||||
EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
|
||||
CreateAddressableTexture("t1", textureGroup, 256);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
BuildLayout layout = BuildAndExtractLayout();
|
||||
|
||||
// Test
|
||||
BundledAssetGroupSchema schema = Settings.groups.First(x => x.HasSchema<BundledAssetGroupSchema>()).GetSchema<BundledAssetGroupSchema>();
|
||||
string path = schema.BuildPath.GetValue(Settings);
|
||||
foreach (BuildLayout.Bundle bundle in layout.Groups.SelectMany(x => x.Bundles))
|
||||
AssertEditorBundleDetailsMatchPhysicalBundle(Path.Combine(path, bundle.Name), bundle);
|
||||
}
|
||||
finally // cleanup
|
||||
{
|
||||
if (groupScenes != null)
|
||||
Settings.RemoveGroup(groupScenes);
|
||||
if (textureGroup != null)
|
||||
Settings.RemoveGroup(textureGroup);
|
||||
if (File.Exists(layoutFilePath))
|
||||
File.Delete(layoutFilePath);
|
||||
AssetDatabase.DeleteAsset(scenePath);
|
||||
DeleteTexture("t1");
|
||||
}
|
||||
}
|
||||
|
||||
// Even though slim writes is true, the system will enable it if it needs to generate a build layout report
|
||||
[Test]
|
||||
public void WhenSlimWriteResultsIsTrue_LayoutStillGenerated()
|
||||
{
|
||||
ProjectConfigData.ReportFileFormat fileFormat = ProjectConfigData.ReportFileFormat.TXT;
|
||||
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(fileFormat);
|
||||
AddressableAssetGroup group = null;
|
||||
bool prevSlim = ScriptableBuildPipeline.slimWriteResults;
|
||||
ProjectConfigData.ReportFileFormat prevFileFormat = ProjectConfigData.BuildLayoutReportFileFormat;
|
||||
|
||||
try
|
||||
{
|
||||
// setup
|
||||
ScriptableBuildPipeline.slimWriteResults = true;
|
||||
ProjectConfigData.BuildLayoutReportFileFormat = fileFormat;
|
||||
group = CreateGroup("Group1");
|
||||
CreateAddressablePrefab("p1", group);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
BuildAndExtractLayout();
|
||||
|
||||
FileAssert.Exists(layoutFilePath);
|
||||
}
|
||||
finally // cleanup
|
||||
{
|
||||
ScriptableBuildPipeline.slimWriteResults = prevSlim;
|
||||
ProjectConfigData.BuildLayoutReportFileFormat = prevFileFormat;
|
||||
if (group != null)
|
||||
Settings.RemoveGroup(group);
|
||||
if (File.Exists(layoutFilePath))
|
||||
File.Delete(layoutFilePath);
|
||||
DeletePrefab("p1");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenBuildLayoutIsDisabled_BuildLayoutIsNotGenerated()
|
||||
{
|
||||
ProjectConfigData.ReportFileFormat fileFormat = ProjectConfigData.ReportFileFormat.TXT;
|
||||
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(fileFormat);
|
||||
AddressableAssetGroup group = null;
|
||||
bool prevGenerateBuildLayout = ProjectConfigData.GenerateBuildLayout;
|
||||
ProjectConfigData.ReportFileFormat prevFileFormat = ProjectConfigData.BuildLayoutReportFileFormat;
|
||||
|
||||
try
|
||||
{
|
||||
// setup
|
||||
ProjectConfigData.GenerateBuildLayout = false;
|
||||
ProjectConfigData.BuildLayoutReportFileFormat = fileFormat;
|
||||
group = CreateGroup("Group1");
|
||||
CreateAddressablePrefab("p1", group);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
BuildAndExtractLayout();
|
||||
|
||||
// Test
|
||||
FileAssert.DoesNotExist(layoutFilePath);
|
||||
}
|
||||
finally // cleanup
|
||||
{
|
||||
ProjectConfigData.GenerateBuildLayout = prevGenerateBuildLayout;
|
||||
ProjectConfigData.BuildLayoutReportFileFormat = prevFileFormat;
|
||||
if (group != null)
|
||||
Settings.RemoveGroup(group);
|
||||
if (File.Exists(layoutFilePath))
|
||||
File.Delete(layoutFilePath);
|
||||
DeletePrefab("p1");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase(ProjectConfigData.ReportFileFormat.TXT)]
|
||||
[TestCase(ProjectConfigData.ReportFileFormat.JSON)]
|
||||
public void WhenBuildLayoutIsEnabled_BuildLayoutIsGenerated(ProjectConfigData.ReportFileFormat format)
|
||||
{
|
||||
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(format);
|
||||
AddressableAssetGroup group = null;
|
||||
bool prevGenerateBuildLayout = ProjectConfigData.GenerateBuildLayout;
|
||||
ProjectConfigData.ReportFileFormat prevFileFormat = ProjectConfigData.BuildLayoutReportFileFormat;
|
||||
|
||||
try
|
||||
{
|
||||
// setup
|
||||
ProjectConfigData.GenerateBuildLayout = true;
|
||||
ProjectConfigData.BuildLayoutReportFileFormat = format;
|
||||
group = CreateGroup("Group1");
|
||||
CreateAddressablePrefab("p1", group);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
BuildAndExtractLayout();
|
||||
|
||||
// Test
|
||||
FileAssert.Exists(layoutFilePath);
|
||||
if (format == ProjectConfigData.ReportFileFormat.JSON)
|
||||
{
|
||||
string text = File.ReadAllText(layoutFilePath);
|
||||
var layout = JsonUtility.FromJson<BuildLayout>(text);
|
||||
Assert.IsNotNull(layout);
|
||||
}
|
||||
}
|
||||
finally // cleanup
|
||||
{
|
||||
ProjectConfigData.GenerateBuildLayout = prevGenerateBuildLayout;
|
||||
ProjectConfigData.BuildLayoutReportFileFormat = prevFileFormat;
|
||||
if (group != null)
|
||||
Settings.RemoveGroup(group);
|
||||
if (File.Exists(layoutFilePath))
|
||||
File.Delete(layoutFilePath);
|
||||
DeletePrefab("p1");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenAssetHasStreamedData_IsReportedCorrectly()
|
||||
{
|
||||
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
|
||||
AddressableAssetGroup group = null;
|
||||
|
||||
try
|
||||
{
|
||||
// setup
|
||||
group = CreateGroup("Group1");
|
||||
CreateAddressableTexture("t1", group, 256);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
BuildLayout layout = BuildAndExtractLayout();
|
||||
|
||||
// Test
|
||||
Assert.IsTrue(layout.Groups[0].Bundles[0].Files[0].Assets[0].StreamedSize != 0);
|
||||
BuildLayout.SubFile f = layout.Groups[0].Bundles[0].Files[0].SubFiles.First(x => x.Name.EndsWith(".resS"));
|
||||
Assert.IsFalse(f.IsSerializedFile);
|
||||
}
|
||||
finally // cleanup
|
||||
{
|
||||
if (group != null)
|
||||
Settings.RemoveGroup(group);
|
||||
if (File.Exists(layoutFilePath))
|
||||
File.Delete(layoutFilePath);
|
||||
DeleteTexture("t1");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenAllContentsOfAnAssetAreStripped_ExplicitAssetHasNoObjects()
|
||||
{
|
||||
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
|
||||
AddressableAssetGroup group = null;
|
||||
string assetPath = $"{TempPath}/testpreset.preset";
|
||||
|
||||
try
|
||||
{
|
||||
// setup
|
||||
Material obj = new Material(Shader.Find("Transparent/Diffuse"));
|
||||
Preset myPreset = new Preset(obj);
|
||||
AssetDatabase.CreateAsset(myPreset, assetPath);
|
||||
GameObject.DestroyImmediate(obj);
|
||||
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate);
|
||||
string guid = AssetDatabase.AssetPathToGUID(assetPath);
|
||||
group = CreateGroup("Group1");
|
||||
MakeAddressable(group, guid);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
BuildLayout layout = BuildAndExtractLayout();
|
||||
|
||||
// Test
|
||||
Assert.AreEqual(0, layout.Groups[0].Bundles[0].Files[0].Assets[0].SerializedSize);
|
||||
}
|
||||
finally // cleanup
|
||||
{
|
||||
if (group != null)
|
||||
Settings.RemoveGroup(group);
|
||||
if (File.Exists(layoutFilePath))
|
||||
File.Delete(layoutFilePath);
|
||||
AssetDatabase.DeleteAsset(assetPath);
|
||||
}
|
||||
}
|
||||
|
||||
class SpritePackerScope : IDisposable
|
||||
{
|
||||
SpritePackerMode m_PrevMode;
|
||||
|
||||
public SpritePackerScope(SpritePackerMode mode)
|
||||
{
|
||||
m_PrevMode = EditorSettings.spritePackerMode;
|
||||
EditorSettings.spritePackerMode = mode;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
EditorSettings.spritePackerMode = m_PrevMode;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenReferencedObjectIdentifiedWithFilename_ObjectRepresentedInDataFromOtherAssets()
|
||||
{
|
||||
using (new SpritePackerScope(SpritePackerMode.BuildTimeOnlyAtlas))
|
||||
{
|
||||
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
|
||||
AddressableAssetGroup group = null;
|
||||
|
||||
try
|
||||
{
|
||||
// setup
|
||||
BuildCache.PurgeCache(false);
|
||||
group = CreateGroup("Group1");
|
||||
string textureGUID = CreateSpriteTexture("spritetexture", 256, false);
|
||||
MakeAddressable(group, CreateSpriteAtlas("atlas", textureGUID));
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
BuildLayout layout = BuildAndExtractLayout();
|
||||
|
||||
// Test
|
||||
BuildLayout.DataFromOtherAsset otherAssets = layout.Groups[0].Bundles[0].Files[0].Assets[0].InternalReferencedOtherAssets[0];
|
||||
Assert.AreEqual(2, layout.Groups[0].Bundles[0].Files[0].Assets[0].InternalReferencedOtherAssets.Count);
|
||||
CollectionAssert.Contains(otherAssets.ReferencingAssets, layout.Groups[0].Bundles[0].Files[0].Assets[0]);
|
||||
}
|
||||
finally // cleanup
|
||||
{
|
||||
if (group != null)
|
||||
Settings.RemoveGroup(group);
|
||||
if (File.Exists(layoutFilePath))
|
||||
File.Delete(layoutFilePath);
|
||||
DeleteSpriteAtlas("atlas");
|
||||
DeleteTexture("spritetexture");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenBuildRemoteCatalogIsDisabled_BuildLayoutContainsCatalogHash()
|
||||
{
|
||||
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
|
||||
AddressableAssetGroup group = null;
|
||||
bool prevBuildRemoteCatalog = Settings.BuildRemoteCatalog;
|
||||
|
||||
try
|
||||
{
|
||||
// setup
|
||||
group = CreateGroup("Group1");
|
||||
CreateAddressablePrefab("p1", group);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
BuildLayout layout = BuildAndExtractLayout();
|
||||
|
||||
// Test
|
||||
Assert.IsFalse(string.IsNullOrEmpty(layout.AddressablesRuntimeSettings.CatalogHash), "Catalog Hash was not correctly written to the Layout");
|
||||
Assert.AreEqual(32, layout.AddressablesRuntimeSettings.CatalogHash.Length, "Catalog Hash was not correctly written to the Layout, incorrect size for hash");
|
||||
Assert.AreEqual(32, layout.BuildResultHash.Length, "Build is expected to have a result hash for the build");
|
||||
}
|
||||
finally // cleanup
|
||||
{
|
||||
Settings.BuildRemoteCatalog = prevBuildRemoteCatalog;
|
||||
if (group != null)
|
||||
Settings.RemoveGroup(group);
|
||||
if (File.Exists(layoutFilePath))
|
||||
File.Delete(layoutFilePath);
|
||||
DeletePrefab("p1");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenBuildContainsMonoScripts_LayoutDoesNotHaveReferencesToMonoScriptAssets()
|
||||
{
|
||||
string layoutFilePath = BuildLayoutGenerationTask.GetLayoutFilePathForFormat(ProjectConfigData.BuildLayoutReportFileFormat);
|
||||
AddressableAssetGroup group = null;
|
||||
bool prevBuildRemoteCatalog = Settings.BuildRemoteCatalog;
|
||||
|
||||
try
|
||||
{
|
||||
// setup
|
||||
group = CreateGroup("Group1");
|
||||
CreateAddressableScriptableObject("so1", group);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
BuildLayout layout = BuildAndExtractLayout();
|
||||
|
||||
// Test
|
||||
foreach (BuildLayout.ExplicitAsset explicitAsset in BuildLayoutHelpers.EnumerateAssets(layout))
|
||||
{
|
||||
foreach (var referencedAsset in explicitAsset.InternalReferencedExplicitAssets)
|
||||
{
|
||||
Assert.IsNotNull(referencedAsset, "Referenced Asset was null, this was likely a stripped MonoScript");
|
||||
Assert.IsTrue(!referencedAsset.AssetPath.EndsWith(".cs") && referencedAsset.AssetPath.EndsWith(".dll"));
|
||||
}
|
||||
foreach (var referencedAsset in explicitAsset.ExternallyReferencedAssets)
|
||||
{
|
||||
Assert.IsNotNull(referencedAsset, "Referenced Asset was null, this was likely a stripped MonoScript");
|
||||
Assert.IsTrue(!referencedAsset.AssetPath.EndsWith(".cs") && referencedAsset.AssetPath.EndsWith(".dll"));
|
||||
}
|
||||
foreach (var referencedAsset in explicitAsset.InternalReferencedOtherAssets)
|
||||
{
|
||||
Assert.IsNotNull(referencedAsset, "Referenced Asset was null, this was likely a stripped MonoScript");
|
||||
Assert.IsTrue(!referencedAsset.AssetPath.EndsWith(".cs") && referencedAsset.AssetPath.EndsWith(".dll"));
|
||||
}
|
||||
}
|
||||
}
|
||||
finally // cleanup
|
||||
{
|
||||
Settings.BuildRemoteCatalog = prevBuildRemoteCatalog;
|
||||
if (group != null)
|
||||
Settings.RemoveGroup(group);
|
||||
if (File.Exists(layoutFilePath))
|
||||
File.Delete(layoutFilePath);
|
||||
DeleteScriptableObject("so1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 041ea21fa30a4a34fa6cfe55505b452c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor.AddressableAssets.Build;
|
||||
using UnityEditor.AddressableAssets.GUI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using static UnityEditor.AddressableAssets.GUI.AddressableAssetsSettingsGroupEditor;
|
||||
|
||||
namespace UnityEditor.AddressableAssets.Tests
|
||||
{
|
||||
public class BuildMenuTests : AddressableAssetTestBase
|
||||
{
|
||||
[HideBuildMenuInUI]
|
||||
public class BaseTestBuildMenu : AddressableAssetsSettingsGroupEditor.IAddressablesBuildMenu
|
||||
{
|
||||
public virtual string BuildMenuPath
|
||||
{
|
||||
get => "";
|
||||
}
|
||||
|
||||
public virtual bool SelectableBuildScript
|
||||
{
|
||||
get => true;
|
||||
}
|
||||
|
||||
public virtual int Order
|
||||
{
|
||||
get => 0;
|
||||
}
|
||||
|
||||
public virtual bool OnPrebuild(AddressablesDataBuilderInput input)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool OnPostbuild(AddressablesDataBuilderInput input, AddressablesPlayerBuildResult result)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class TestBuildMenu : BaseTestBuildMenu
|
||||
{
|
||||
public override bool OnPrebuild(AddressablesDataBuilderInput input)
|
||||
{
|
||||
Debug.Log("Pre Invoked");
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnPostbuild(AddressablesDataBuilderInput input, AddressablesPlayerBuildResult result)
|
||||
{
|
||||
Debug.Log("Post Invoked");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class TestBuildMenuOrderZero : BaseTestBuildMenu
|
||||
{
|
||||
public override string BuildMenuPath => "Zero";
|
||||
public override int Order => 0;
|
||||
}
|
||||
|
||||
public class TestBuildMenuOrderMinusOne : BaseTestBuildMenu
|
||||
{
|
||||
public override string BuildMenuPath => "MinusOne";
|
||||
public override int Order => -1;
|
||||
}
|
||||
|
||||
public class TestBuildMenuOrderOne : BaseTestBuildMenu
|
||||
{
|
||||
public override string BuildMenuPath => "One";
|
||||
public override int Order => 1;
|
||||
}
|
||||
|
||||
public class TestBuildMenu1_BuildPathTest : BaseTestBuildMenu
|
||||
{
|
||||
public override string BuildMenuPath => "Test";
|
||||
}
|
||||
|
||||
public class TestBuildMenu2_BuildPathTest : BaseTestBuildMenu
|
||||
{
|
||||
public override string BuildMenuPath => "Test";
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildMenu_BuildCorrectlyCallPreAndPost()
|
||||
{
|
||||
AddressableAssetsSettingsGroupEditor.BuildMenuContext context =
|
||||
new AddressableAssetsSettingsGroupEditor.BuildMenuContext();
|
||||
context.BuildMenu = new TestBuildMenu();
|
||||
context.buildScriptIndex = -1;
|
||||
context.Settings = Settings;
|
||||
|
||||
// Test
|
||||
LogAssert.Expect(LogType.Log, "Pre Invoked");
|
||||
LogAssert.Expect(LogType.Log, "Post Invoked");
|
||||
AddressableAssetsSettingsGroupEditor.OnBuildAddressables(context);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildMenu_CreateBuildMenus_CorrectOrder()
|
||||
{
|
||||
List<Type> menuTypes = new List<Type>();
|
||||
// 1, -1, 0
|
||||
menuTypes.Add(typeof(TestBuildMenuOrderOne));
|
||||
menuTypes.Add(typeof(TestBuildMenuOrderMinusOne));
|
||||
menuTypes.Add(typeof(TestBuildMenuOrderZero));
|
||||
var menus = AddressableAssetsSettingsGroupEditor.CreateBuildMenus(menuTypes, true);
|
||||
|
||||
Assert.AreEqual(3, menus.Count, "Failed to get the correct number of build menus");
|
||||
string orderStr = menus[0].Order.ToString();
|
||||
orderStr += "," + menus[1].Order.ToString();
|
||||
orderStr += "," + menus[2].Order.ToString();
|
||||
Assert.AreEqual("-1,0,1", orderStr, "Menus not in the correct order");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildMenu_RemovesConflictingBuildPaths()
|
||||
{
|
||||
List<Type> menuTypes = new List<Type>();
|
||||
menuTypes.Add(typeof(TestBuildMenu1_BuildPathTest));
|
||||
menuTypes.Add(typeof(TestBuildMenu2_BuildPathTest));
|
||||
LogAssert.Expect(LogType.Warning,
|
||||
"Trying to new build menu [UnityEditor.AddressableAssets.Tests.BuildMenuTests+TestBuildMenu2_BuildPathTest] with path \"Test\". But an existing type already exists with that path, [UnityEditor.AddressableAssets.Tests.BuildMenuTests+TestBuildMenu1_BuildPathTest].");
|
||||
var menus = AddressableAssetsSettingsGroupEditor.CreateBuildMenus(menuTypes, true);
|
||||
|
||||
Assert.AreEqual(1, menus.Count, "Failed to get the correct number of build menus");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3331e5d5506b4b59975f5b7aee249b67
|
||||
timeCreated: 1649164850
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor.AddressableAssets.Build;
|
||||
using UnityEditor.AddressableAssets.Build.DataBuilders;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.AddressableAssets.Tests
|
||||
{
|
||||
public class BuildScriptFastTests : AddressableAssetTestBase
|
||||
{
|
||||
[Test]
|
||||
public void FastModeScript_CannotBuildPlayerContent()
|
||||
{
|
||||
var buildScript = ScriptableObject.CreateInstance<BuildScriptFastMode>();
|
||||
|
||||
Assert.IsFalse(buildScript.CanBuildData<AddressablesPlayerBuildResult>());
|
||||
|
||||
Assert.IsTrue(buildScript.CanBuildData<AddressableAssetBuildResult>());
|
||||
Assert.IsTrue(buildScript.CanBuildData<AddressablesPlayModeBuildResult>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f1a1c0162fa02cb42ae827251833e0bb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AddressableAssets.Build;
|
||||
using UnityEditor.AddressableAssets.Build.DataBuilders;
|
||||
using UnityEditor.AddressableAssets.Settings;
|
||||
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
|
||||
using UnityEditor.Build.Pipeline.Utilities;
|
||||
using UnityEngine;
|
||||
|
||||
public class BuildScriptPackedIntegrationTests
|
||||
{
|
||||
string CreateTexture(string path)
|
||||
{
|
||||
var data = ImageConversion.EncodeToPNG(new Texture2D(32, 32));
|
||||
File.WriteAllBytes(path, data);
|
||||
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate);
|
||||
return AssetDatabase.AssetPathToGUID(path);
|
||||
}
|
||||
|
||||
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 string m_SingleTestBuildFolder;
|
||||
protected string m_SingleTestAssetFolder;
|
||||
|
||||
void DeleteSingleTestDirectories()
|
||||
{
|
||||
if (Directory.Exists(m_SingleTestBuildFolder))
|
||||
Directory.Delete(m_SingleTestBuildFolder, true);
|
||||
|
||||
if (Directory.Exists(m_SingleTestAssetFolder))
|
||||
Directory.Delete(m_SingleTestAssetFolder, true);
|
||||
}
|
||||
|
||||
string m_SettingsPath;
|
||||
AddressableAssetSettings m_Settings;
|
||||
|
||||
AddressableAssetSettings Settings
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Settings == null)
|
||||
m_Settings = AssetDatabase.LoadAssetAtPath<AddressableAssetSettings>(m_SettingsPath);
|
||||
return m_Settings;
|
||||
}
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
m_SingleTestBuildFolder = "Temp/TestBuild";
|
||||
m_SingleTestAssetFolder = "Assets/SingleTestFolder";
|
||||
DeleteSingleTestDirectories();
|
||||
Directory.CreateDirectory(m_SingleTestBuildFolder);
|
||||
Directory.CreateDirectory(m_SingleTestAssetFolder);
|
||||
AddressableAssetSettings settings = AddressableAssetSettings.Create(Path.Combine(m_SingleTestAssetFolder, "Settings"), "AddressableAssetSettings.Tests", false, true);
|
||||
m_SettingsPath = settings.AssetPath;
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
DeleteSingleTestDirectories();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IncrementalBuild_WhenBundleTimestampUnchanged_DoesNotCopy()
|
||||
{
|
||||
AddressableAssetBuildResult result;
|
||||
var group = Settings.CreateGroup("MyTestGroup", true, false, false, null, typeof(BundledAssetGroupSchema));
|
||||
|
||||
var spriteEntry = Settings.CreateOrMoveEntry(CreateTexture($"{m_SingleTestAssetFolder}/testTexture.png"), group, false, false);
|
||||
Settings.profileSettings.SetValue(Settings.activeProfileId, AddressableAssetSettings.kLocalBuildPath, m_SingleTestBuildFolder);
|
||||
Settings.profileSettings.SetValue(Settings.activeProfileId, AddressableAssetSettings.kLocalLoadPath, "Library/LocalLoadPath");
|
||||
|
||||
IDataBuilder b = GetBuilderOfType(Settings, typeof(BuildScriptPackedMode));
|
||||
b.BuildData<AddressableAssetBuildResult>(new AddressablesDataBuilderInput(Settings));
|
||||
|
||||
string[] buildFiles = Directory.GetFiles(m_SingleTestBuildFolder);
|
||||
|
||||
// Build again with a lock on the output bundle. This is how we ensure that the bundle is not written again
|
||||
using (File.Open(buildFiles[0], FileMode.Open, FileAccess.ReadWrite, FileShare.None))
|
||||
result = b.BuildData<AddressableAssetBuildResult>(new AddressablesDataBuilderInput(Settings));
|
||||
|
||||
Assert.AreEqual(1, buildFiles.Length, "There should only be one bundle file in the build output folder");
|
||||
Assert.IsTrue(string.IsNullOrEmpty(result.Error));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IncrementalBuild_WhenBundleTimestampChanges_CopiesNewFile()
|
||||
{
|
||||
var group = Settings.CreateGroup("MyTestGroup", true, false, false, null, typeof(BundledAssetGroupSchema));
|
||||
|
||||
var spriteEntry = Settings.CreateOrMoveEntry(CreateTexture($"{m_SingleTestAssetFolder}/testTexture.png"), group, false, false);
|
||||
Settings.profileSettings.SetValue(Settings.activeProfileId, AddressableAssetSettings.kLocalBuildPath, m_SingleTestBuildFolder);
|
||||
Settings.profileSettings.SetValue(Settings.activeProfileId, AddressableAssetSettings.kLocalLoadPath, "Library/LocalLoadPath");
|
||||
|
||||
IDataBuilder b = GetBuilderOfType(Settings, typeof(BuildScriptPackedMode));
|
||||
b.BuildData<AddressableAssetBuildResult>(new AddressablesDataBuilderInput(Settings));
|
||||
|
||||
string[] buildFiles = Directory.GetFiles(m_SingleTestBuildFolder);
|
||||
|
||||
byte[] initialBundleBytes = File.ReadAllBytes(buildFiles[0]);
|
||||
File.Delete(buildFiles[0]);
|
||||
File.WriteAllText(buildFiles[0], "content");
|
||||
File.SetLastWriteTime(buildFiles[0], new DateTime(2019, 1, 1));
|
||||
|
||||
b.BuildData<AddressableAssetBuildResult>(new AddressablesDataBuilderInput(Settings));
|
||||
|
||||
Assert.AreEqual(1, buildFiles.Length, "There should only be one bundle file in the build output folder");
|
||||
CollectionAssert.AreEqual(initialBundleBytes, File.ReadAllBytes(buildFiles[0]));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b47f3ece14ba6b74e883481b6ef86d53
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor.AddressableAssets.Build;
|
||||
using UnityEditor.AddressableAssets.Build.DataBuilders;
|
||||
using UnityEditor.AddressableAssets.Settings;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.AddressableAssets.Initialization;
|
||||
|
||||
namespace UnityEditor.AddressableAssets.Tests
|
||||
{
|
||||
public class BuildScriptPackedPlayTests : AddressableAssetTestBase
|
||||
{
|
||||
protected override void OnInit()
|
||||
{
|
||||
//Player data must be built before PackPlaymode can be used.
|
||||
var input = new AddressablesDataBuilderInput(Settings);
|
||||
ScriptableObject.CreateInstance<BuildScriptPackedMode>().BuildData<AddressableAssetBuildResult>(input);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PackedPlayModeScript_CannotBuildPlayerContent()
|
||||
{
|
||||
var buildScript = ScriptableObject.CreateInstance<BuildScriptPackedPlayMode>();
|
||||
|
||||
Assert.IsFalse(buildScript.CanBuildData<AddressablesPlayerBuildResult>());
|
||||
|
||||
Assert.IsTrue(buildScript.CanBuildData<AddressableAssetBuildResult>());
|
||||
Assert.IsTrue(buildScript.CanBuildData<AddressablesPlayModeBuildResult>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PackedPlayModeScript_AppendsBuildLog_ForNonStandaloneBuildTarget()
|
||||
{
|
||||
//Setup
|
||||
BuildScriptPackedPlayMode buildScript = ScriptableObject.CreateInstance<BuildScriptPackedPlayMode>();
|
||||
AddressablesDataBuilderInput input = new AddressablesDataBuilderInput(Settings);
|
||||
input.SetAllValues(Settings, BuildTargetGroup.Android, BuildTarget.Android, "");
|
||||
ScriptableObject.CreateInstance<BuildScriptPackedMode>().BuildData<AddressableAssetBuildResult>(input);
|
||||
|
||||
//Test
|
||||
buildScript.BuildData<AddressablesPlayModeBuildResult>(input);
|
||||
var buildLogPath = Addressables.BuildPath + "/buildLogs.json";
|
||||
var logs = JsonUtility.FromJson<PackedPlayModeBuildLogs>(File.ReadAllText(buildLogPath));
|
||||
|
||||
//Cleanup (done early in case of test failure)
|
||||
File.Delete(buildLogPath);
|
||||
|
||||
//Assert
|
||||
Assert.AreEqual(1, logs.RuntimeBuildLogs.Count);
|
||||
Assert.AreEqual(LogType.Warning, logs.RuntimeBuildLogs[0].Type);
|
||||
Assert.AreEqual($"Asset bundles built with build target {input.Target} may not be compatible with running in the Editor.", logs.RuntimeBuildLogs[0].Message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PackedPlayModeScript_AppendsBuildLog_ForInvalidBuildTarget()
|
||||
{
|
||||
//Setup
|
||||
BuildScriptPackedPlayMode buildScript = ScriptableObject.CreateInstance<BuildScriptPackedPlayMode>();
|
||||
AddressablesDataBuilderInput input = new AddressablesDataBuilderInput(Settings);
|
||||
var settingsPath = Addressables.BuildPath + "/settings.json";
|
||||
var rtd = JsonUtility.FromJson<ResourceManagerRuntimeData>(File.ReadAllText(settingsPath));
|
||||
var buildLogPath = Addressables.BuildPath + "/buildLogs.json";
|
||||
|
||||
string storedBuildTarget = rtd.BuildTarget;
|
||||
string invalidTarget = rtd.BuildTarget = "NotAValidBuildTarget";
|
||||
File.WriteAllText(settingsPath, JsonUtility.ToJson(rtd));
|
||||
|
||||
//Test
|
||||
buildScript.BuildData<AddressablesPlayModeBuildResult>(input);
|
||||
var logs = JsonUtility.FromJson<PackedPlayModeBuildLogs>(File.ReadAllText(buildLogPath));
|
||||
|
||||
//Cleanup (done early in case of test failure)
|
||||
File.Delete(buildLogPath);
|
||||
rtd.BuildTarget = storedBuildTarget;
|
||||
File.WriteAllText(settingsPath, JsonUtility.ToJson(rtd));
|
||||
|
||||
//Assert
|
||||
Assert.AreEqual(1, logs.RuntimeBuildLogs.Count);
|
||||
Assert.AreEqual(LogType.Warning, logs.RuntimeBuildLogs[0].Type);
|
||||
Assert.AreEqual($"Unable to parse build target from initialization data: '{invalidTarget}'.", logs.RuntimeBuildLogs[0].Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 49c2c229315d04249b13bbf17069f486
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1f2eff97e91ec624b8d35cecfb1ccf38
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,632 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor.AddressableAssets.Build;
|
||||
using UnityEditor.AddressableAssets.Build.DataBuilders;
|
||||
using UnityEditor.AddressableAssets.Settings;
|
||||
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
|
||||
using UnityEditor.Build.Pipeline.Utilities;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEditor.AddressableAssets.Tests
|
||||
{
|
||||
public class BuildScriptTests : AddressableAssetTestBase
|
||||
{
|
||||
[TestFixture]
|
||||
class StreamingAssetTests : AddressableAssetTestBase
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
DirectoryUtility.DeleteDirectory(Application.streamingAssetsPath, recursiveDelete: true);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
DirectoryUtility.DeleteDirectory(Application.streamingAssetsPath, recursiveDelete: true);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ClearCachedData_CleansStreamingAssetFolder()
|
||||
{
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
|
||||
int builderCount = 0;
|
||||
for (int i = 0; i < Settings.DataBuilders.Count; i++)
|
||||
{
|
||||
var builder = Settings.DataBuilders[i] as IDataBuilder;
|
||||
if (builder.CanBuildData<AddressablesPlayerBuildResult>())
|
||||
{
|
||||
builderCount++;
|
||||
var existingFiles = new HashSet<string>();
|
||||
if (System.IO.Directory.Exists("Assets/StreamingAssets"))
|
||||
{
|
||||
foreach (var f in System.IO.Directory.GetFiles("Assets/StreamingAssets"))
|
||||
existingFiles.Add(f);
|
||||
}
|
||||
|
||||
builder.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
builder.ClearCachedData();
|
||||
if (System.IO.Directory.Exists("Assets/StreamingAssets"))
|
||||
{
|
||||
foreach (var f in System.IO.Directory.GetFiles("Assets/StreamingAssets"))
|
||||
Assert.IsTrue(existingFiles.Contains(f), string.Format("Data Builder {0} did not clean up file {1}", builder.Name, f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Assert.IsTrue(builderCount > 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Folder_WithSubAssets_GetsBundleFileIdAssigned_DuringBuild()
|
||||
{
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
string folderGuid = AssetDatabase.CreateFolder(TestFolder, "FolderAsset");
|
||||
string folderPath = $"{TestFolder}/FolderAsset";
|
||||
PrefabUtility.SaveAsPrefabAsset(new GameObject(), $"{folderPath}/subfolderprefab.prefab");
|
||||
|
||||
AddressableAssetEntry folderEntry = Settings.CreateOrMoveEntry(folderGuid, Settings.DefaultGroup);
|
||||
|
||||
Assert.IsTrue(string.IsNullOrEmpty(folderEntry.BundleFileId));
|
||||
|
||||
Settings.ActivePlayerDataBuilder.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
|
||||
Assert.IsTrue(folderEntry.IsFolder);
|
||||
Assert.IsFalse(string.IsNullOrEmpty(folderEntry.BundleFileId));
|
||||
|
||||
//Cleanup
|
||||
AssetDatabase.DeleteAsset(folderPath);
|
||||
Settings.RemoveAssetEntry(folderEntry);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Folder_WithNoSubAssets_DoesNotThrowErrorDuringBuild()
|
||||
{
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
string folderGuid = AssetDatabase.CreateFolder(TestFolder, "FolderAsset");
|
||||
string folderPath = $"{TestFolder}/FolderAsset";
|
||||
|
||||
AddressableAssetEntry folderEntry = Settings.CreateOrMoveEntry(folderGuid, Settings.DefaultGroup);
|
||||
|
||||
Assert.IsTrue(string.IsNullOrEmpty(folderEntry.BundleFileId));
|
||||
|
||||
Settings.ActivePlayerDataBuilder.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
|
||||
Assert.IsTrue(folderEntry.IsFolder);
|
||||
Assert.IsTrue(string.IsNullOrEmpty(folderEntry.BundleFileId));
|
||||
|
||||
//Cleanup
|
||||
AssetDatabase.DeleteAsset(folderPath);
|
||||
Settings.RemoveAssetEntry(folderEntry);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Folder_DoesNotAssignBundleFileId_ForDynamicallyCreatedSubEntries()
|
||||
{
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
string folderGuid = AssetDatabase.CreateFolder(TestFolder, "FolderAsset");
|
||||
string folderPath = $"{TestFolder}/FolderAsset";
|
||||
PrefabUtility.SaveAsPrefabAsset(new GameObject(), $"{folderPath}/subfolderprefab.prefab");
|
||||
|
||||
AddressableAssetEntry folderEntry = Settings.CreateOrMoveEntry(folderGuid, Settings.DefaultGroup);
|
||||
|
||||
Settings.ActivePlayerDataBuilder.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
|
||||
Assert.True(string.IsNullOrEmpty(folderEntry.SubAssets[0].BundleFileId));
|
||||
|
||||
//Cleanup
|
||||
AssetDatabase.DeleteAsset(folderPath);
|
||||
Settings.RemoveAssetEntry(folderEntry);
|
||||
}
|
||||
|
||||
#if !UNITY_2021_2_OR_NEWER
|
||||
[Test]
|
||||
public void CopiedStreamingAssetAreCorrectlyDeleted_DirectoriesWithoutImport()
|
||||
{
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
|
||||
int builderCount = 0;
|
||||
for (int i = 0; i < Settings.DataBuilders.Count; i++)
|
||||
{
|
||||
var builder = Settings.DataBuilders[i] as IDataBuilder;
|
||||
if (builder.CanBuildData<AddressablesPlayerBuildResult>())
|
||||
{
|
||||
builderCount++;
|
||||
|
||||
// confirm that StreamingAssets does not exists before the test
|
||||
Assert.IsFalse(Directory.Exists("Assets/StreamingAssets"));
|
||||
builder.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
|
||||
Assert.IsTrue(Directory.Exists(Addressables.BuildPath));
|
||||
AddressablesPlayerBuildProcessor.CopyTemporaryPlayerBuildData();
|
||||
builder.ClearCachedData();
|
||||
|
||||
Assert.IsTrue(Directory.Exists(Addressables.PlayerBuildDataPath));
|
||||
AddressablesPlayerBuildProcessor.CleanTemporaryPlayerBuildData();
|
||||
Assert.IsFalse(Directory.Exists(Addressables.PlayerBuildDataPath));
|
||||
Assert.IsFalse(Directory.Exists("Assets/StreamingAssets"));
|
||||
}
|
||||
}
|
||||
|
||||
Assert.IsTrue(builderCount > 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopiedStreamingAssetAreCorrectlyDeleted_MetaFilesWithImport()
|
||||
{
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
|
||||
int builderCount = 0;
|
||||
for (int i = 0; i < Settings.DataBuilders.Count; i++)
|
||||
{
|
||||
var builder = Settings.DataBuilders[i] as IDataBuilder;
|
||||
if (builder.CanBuildData<AddressablesPlayerBuildResult>())
|
||||
{
|
||||
builderCount++;
|
||||
|
||||
// confirm that StreamingAssets does not exists before the test
|
||||
DirectoryUtility.DeleteDirectory(Application.streamingAssetsPath, recursiveDelete: true);
|
||||
Assert.IsFalse(Directory.Exists("Assets/StreamingAssets"));
|
||||
builder.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
|
||||
Assert.IsTrue(Directory.Exists(Addressables.BuildPath));
|
||||
AddressablesPlayerBuildProcessor.CopyTemporaryPlayerBuildData();
|
||||
builder.ClearCachedData();
|
||||
|
||||
// confirm that PlayerBuildDataPath is imported to AssetDatabase
|
||||
AssetDatabase.Refresh();
|
||||
Assert.IsTrue(Directory.Exists(Addressables.PlayerBuildDataPath));
|
||||
Assert.IsTrue(File.Exists(Addressables.PlayerBuildDataPath + ".meta"));
|
||||
string relativePath = Addressables.PlayerBuildDataPath.Replace(Application.dataPath, "Assets");
|
||||
Assert.IsTrue(AssetDatabase.IsValidFolder(relativePath), "Copied StreamingAssets folder was not importer as expected");
|
||||
|
||||
AddressablesPlayerBuildProcessor.CleanTemporaryPlayerBuildData();
|
||||
Assert.IsFalse(Directory.Exists(Addressables.PlayerBuildDataPath));
|
||||
Assert.IsFalse(Directory.Exists("Assets/StreamingAssets"));
|
||||
}
|
||||
}
|
||||
|
||||
Assert.IsTrue(builderCount > 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopiedStreamingAssetAreCorrectlyDeleted_WithExistingFiles()
|
||||
{
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
|
||||
int builderCount = 0;
|
||||
for (int i = 0; i < Settings.DataBuilders.Count; i++)
|
||||
{
|
||||
var builder = Settings.DataBuilders[i] as IDataBuilder;
|
||||
if (builder.CanBuildData<AddressablesPlayerBuildResult>())
|
||||
{
|
||||
builderCount++;
|
||||
|
||||
// confirm that StreamingAssets does not exists before the test
|
||||
DirectoryUtility.DeleteDirectory(Application.streamingAssetsPath, recursiveDelete: true);
|
||||
Assert.IsFalse(Directory.Exists("Assets/StreamingAssets"));
|
||||
|
||||
// create StreamingAssets and an extra folder as existing content
|
||||
AssetDatabase.CreateFolder("Assets", "StreamingAssets");
|
||||
AssetDatabase.CreateFolder("Assets/StreamingAssets", "extraFolder");
|
||||
|
||||
builder.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
|
||||
Assert.IsTrue(Directory.Exists(Addressables.BuildPath));
|
||||
AddressablesPlayerBuildProcessor.CopyTemporaryPlayerBuildData();
|
||||
builder.ClearCachedData();
|
||||
|
||||
Assert.IsTrue(Directory.Exists(Addressables.PlayerBuildDataPath));
|
||||
AddressablesPlayerBuildProcessor.CleanTemporaryPlayerBuildData();
|
||||
Assert.IsFalse(Directory.Exists(Addressables.PlayerBuildDataPath));
|
||||
Assert.IsTrue(Directory.Exists("Assets/StreamingAssets"));
|
||||
Assert.IsTrue(Directory.Exists("Assets/StreamingAssets/extraFolder"));
|
||||
|
||||
AssetDatabase.DeleteAsset("Assets/StreamingAssets");
|
||||
}
|
||||
}
|
||||
|
||||
Assert.IsTrue(builderCount > 0);
|
||||
}
|
||||
|
||||
#else
|
||||
[Test]
|
||||
public void AddressablesBuildPlayerProcessor_IncludeAdditionalStreamingAssetsWhenExist()
|
||||
{
|
||||
string path = Addressables.BuildPath;
|
||||
Directory.CreateDirectory(path);
|
||||
var paths = AddressablesPlayerBuildProcessor.GetStreamingAssetPaths();
|
||||
Assert.AreEqual(1, paths.Count, "StreamingAssets paths expected to include Addressables.BuildPath");
|
||||
|
||||
// cleanup
|
||||
Directory.Delete(path);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddressablesBuildPlayerProcessor_DoesntIncludeAdditionalStreamingAssetsWhenDontExist()
|
||||
{
|
||||
if (Directory.Exists(Addressables.BuildPath))
|
||||
DirectoryUtility.DeleteDirectory(Addressables.BuildPath, false);
|
||||
var paths = AddressablesPlayerBuildProcessor.GetStreamingAssetPaths();
|
||||
Assert.AreEqual(0, paths.Count, "StreamingAssets paths are expected to be empty");
|
||||
|
||||
// cleanup
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildScriptBase_FailsCanBuildData()
|
||||
{
|
||||
var buildScript = ScriptableObject.CreateInstance<BuildScriptBase>();
|
||||
Assert.IsFalse(buildScript.CanBuildData<IDataBuilderResult>());
|
||||
Assert.IsFalse(buildScript.CanBuildData<AddressableAssetBuildResult>());
|
||||
Assert.IsFalse(buildScript.CanBuildData<AddressablesPlayModeBuildResult>());
|
||||
Assert.IsFalse(buildScript.CanBuildData<AddressablesPlayerBuildResult>());
|
||||
}
|
||||
|
||||
internal class BuildScriptTestClass : BuildScriptBase
|
||||
{
|
||||
public override string Name
|
||||
{
|
||||
get { return "Test Script"; }
|
||||
}
|
||||
|
||||
public override bool CanBuildData<T>()
|
||||
{
|
||||
return typeof(T).IsAssignableFrom(typeof(AddressablesPlayModeBuildResult));
|
||||
}
|
||||
|
||||
protected override TResult BuildDataImplementation<TResult>(AddressablesDataBuilderInput builderInput)
|
||||
{
|
||||
Debug.LogError("Inside BuildDataInternal for test script!");
|
||||
return base.BuildDataImplementation<TResult>(builderInput);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildScript_DoesNotBuildWrongDataType()
|
||||
{
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
|
||||
var baseScript = ScriptableObject.CreateInstance<BuildScriptTestClass>();
|
||||
baseScript.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
LogAssert.Expect(LogType.Error, new Regex("Data builder Test Script cannot build requested type.*"));
|
||||
|
||||
baseScript.BuildData<AddressablesPlayModeBuildResult>(context);
|
||||
LogAssert.Expect(LogType.Error, "Inside BuildDataInternal for test script!");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetNameWithHashNaming_ReturnsNoChangeIfNoHash()
|
||||
{
|
||||
string source = "x/y.bundle";
|
||||
string hash = "123abc";
|
||||
string expected = "x/y.bundle";
|
||||
|
||||
var actual = BuildUtility.GetNameWithHashNaming(BundledAssetGroupSchema.BundleNamingStyle.NoHash, hash, source);
|
||||
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetNameWithHashNaming_CanAppendHash()
|
||||
{
|
||||
string source = "x/y.bundle";
|
||||
string hash = "123abc";
|
||||
string expected = "x/y_123abc.bundle";
|
||||
|
||||
var actual = BuildUtility.GetNameWithHashNaming(BundledAssetGroupSchema.BundleNamingStyle.AppendHash, hash, source);
|
||||
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetNameWithHashNaming_CanReplaceFileNameWithHash()
|
||||
{
|
||||
string source = "x/y.bundle";
|
||||
string hash = "123abc";
|
||||
string expected = "123abc.bundle";
|
||||
|
||||
var actual = BuildUtility.GetNameWithHashNaming(BundledAssetGroupSchema.BundleNamingStyle.OnlyHash, hash, source);
|
||||
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetNameWithHashNaming_CanReplaceFileNameWithFileNameHash()
|
||||
{
|
||||
string source = "x/y.bundle";
|
||||
string hash = HashingMethods.Calculate(source).ToString();
|
||||
string expected = hash + ".bundle";
|
||||
|
||||
var actual = BuildUtility.GetNameWithHashNaming(BundledAssetGroupSchema.BundleNamingStyle.FileNameHash, hash, source);
|
||||
|
||||
Assert.AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
// regression test for https://jira.unity3d.com/browse/ADDR-1292
|
||||
[Test]
|
||||
public void BuildScriptBaseWriteBuildLog_WhenDirectoryDoesNotExist_DirectoryCreated()
|
||||
{
|
||||
string dirName = "SomeTestDir";
|
||||
string logFile = Path.Combine(dirName, "AddressablesBuildTEP.json");
|
||||
try
|
||||
{
|
||||
BuildLog log = new BuildLog();
|
||||
BuildScriptBase.WriteBuildLog(log, dirName);
|
||||
FileAssert.Exists(logFile);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.Delete(dirName, true);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Building_CreatesPerformanceReportWithMetaData()
|
||||
{
|
||||
Settings.BuildPlayerContentImpl();
|
||||
string path = Addressables.LibraryPath + "AddressablesBuildTEP.json";
|
||||
FileAssert.Exists(path);
|
||||
string text = File.ReadAllText(path);
|
||||
StringAssert.Contains("com.unity.addressables", text);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Build_WithInvalidAssetInResourcesFolder_Succeeds()
|
||||
{
|
||||
var path = GetAssetPath("Resources/unknownAsset.plist");
|
||||
if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(path)))
|
||||
System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(path));
|
||||
System.IO.File.WriteAllText(path, "nothing");
|
||||
AssetDatabase.ImportAsset(path);
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
foreach (IDataBuilder db in Settings.DataBuilders)
|
||||
if (db.CanBuildData<AddressablesPlayerBuildResult>())
|
||||
db.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Build_GroupWithPlayerDataGroupSchemaAndBundledAssetGroupSchema_LogsError()
|
||||
{
|
||||
const string groupName = "NewGroup";
|
||||
var schemas = new List<AddressableAssetGroupSchema> {ScriptableObject.CreateInstance<PlayerDataGroupSchema>(), ScriptableObject.CreateInstance<BundledAssetGroupSchema>()};
|
||||
AddressableAssetGroup group = Settings.CreateGroup(groupName, false, false, false, schemas);
|
||||
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
foreach (IDataBuilder db in Settings.DataBuilders)
|
||||
{
|
||||
if (db.CanBuildData<AddressablesPlayerBuildResult>())
|
||||
{
|
||||
AddressablesPlayerBuildResult result = db.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
Assert.AreEqual(result.Error, $"Addressable group {groupName} cannot have both a {typeof(PlayerDataGroupSchema).Name} and a {typeof(BundledAssetGroupSchema).Name}");
|
||||
}
|
||||
}
|
||||
|
||||
Settings.RemoveGroup(group);
|
||||
}
|
||||
|
||||
// ADDR-1755
|
||||
[Test]
|
||||
public void WhenBundleLocalCatalogEnabled_BuildScriptPacked_DoesNotCreatePerformanceLogReport()
|
||||
{
|
||||
string logPath = $"Library/com.unity.addressables/aa/{PlatformMappingService.GetPlatformPathSubFolder()}/buildlogtep.json";
|
||||
|
||||
if (File.Exists(logPath))
|
||||
File.Delete(logPath);
|
||||
|
||||
Settings.BundleLocalCatalog = true;
|
||||
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
BuildScriptBase db = (BuildScriptBase)Settings.DataBuilders.Find(x => x.GetType() == typeof(BuildScriptPackedMode));
|
||||
|
||||
Assert.IsFalse(File.Exists(logPath)); // make sure file does not exist before build
|
||||
|
||||
var res = db.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
Assert.IsFalse(File.Exists(logPath));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Build_WithDeletedAsset_Succeeds()
|
||||
{
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
|
||||
//make an entry with no actual AssetPath
|
||||
Settings.CreateOrMoveEntry("abcde", Settings.DefaultGroup);
|
||||
Settings.CreateOrMoveEntry(m_AssetGUID, Settings.DefaultGroup);
|
||||
foreach (BuildScriptBase db in Settings.DataBuilders.OfType<BuildScriptBase>())
|
||||
{
|
||||
if (db is BuildScriptPackedPlayMode)
|
||||
continue;
|
||||
|
||||
if (db.CanBuildData<AddressablesPlayerBuildResult>())
|
||||
{
|
||||
var res = db.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
Assert.IsTrue(db.IsDataBuilt());
|
||||
Assert.IsTrue(string.IsNullOrEmpty(res.Error));
|
||||
}
|
||||
else if (db.CanBuildData<AddressablesPlayModeBuildResult>())
|
||||
{
|
||||
var res = db.BuildData<AddressablesPlayModeBuildResult>(context);
|
||||
Assert.IsTrue(db.IsDataBuilt());
|
||||
Assert.IsTrue(string.IsNullOrEmpty(res.Error));
|
||||
}
|
||||
}
|
||||
|
||||
Settings.RemoveAssetEntry("abcde", false);
|
||||
Settings.RemoveAssetEntry(m_AssetGUID, false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenAddressHasSquareBrackets_AndContentCatalogsAreCreated_BuildFails()
|
||||
{
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
|
||||
AddressableAssetEntry entry = Settings.CreateOrMoveEntry(m_AssetGUID, Settings.DefaultGroup);
|
||||
entry.address = "[test]";
|
||||
LogAssert.Expect(LogType.Error, $"Address '{entry.address}' cannot contain '[ ]'.");
|
||||
foreach (IDataBuilder db in Settings.DataBuilders)
|
||||
{
|
||||
if (db.GetType() == typeof(BuildScriptFastMode) || db.GetType() == typeof(BuildScriptPackedPlayMode))
|
||||
continue;
|
||||
|
||||
if (db.CanBuildData<AddressablesPlayerBuildResult>())
|
||||
db.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
else if (db.CanBuildData<AddressablesPlayModeBuildResult>())
|
||||
db.BuildData<AddressablesPlayModeBuildResult>(context);
|
||||
LogAssert.Expect(LogType.Error, "Address '[test]' cannot contain '[ ]'.");
|
||||
}
|
||||
|
||||
Settings.RemoveAssetEntry(m_AssetGUID, false);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenFileTypeIsInvalid_AndContentCatalogsAreCreated_BuildFails()
|
||||
{
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
|
||||
string path = GetAssetPath("fake.file");
|
||||
FileStream fs = File.Create(path);
|
||||
fs.Close();
|
||||
AssetDatabase.ImportAsset(path);
|
||||
string guid = AssetDatabase.AssetPathToGUID(path);
|
||||
|
||||
AddressableAssetEntry entry = Settings.CreateOrMoveEntry(guid, Settings.DefaultGroup);
|
||||
|
||||
foreach (IDataBuilder db in Settings.DataBuilders)
|
||||
{
|
||||
if (db.GetType() == typeof(BuildScriptFastMode) ||
|
||||
db.GetType() == typeof(BuildScriptPackedPlayMode))
|
||||
continue;
|
||||
|
||||
if (db.CanBuildData<AddressablesPlayerBuildResult>())
|
||||
db.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
else if (db.CanBuildData<AddressablesPlayModeBuildResult>())
|
||||
db.BuildData<AddressablesPlayModeBuildResult>(context);
|
||||
LogAssert.Expect(LogType.Error,
|
||||
"Cannot recognize file type for entry located at 'Assets/UnityEditor.AddressableAssets.Tests.BuildScriptTests_Tests/fake.file'. Asset import failed for using an unsupported file type.");
|
||||
}
|
||||
|
||||
Settings.RemoveAssetEntry(guid, false);
|
||||
AssetDatabase.DeleteAsset(path);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenFileTypeIsInvalid_AndContentCatalogsAreCreated_IgnoreUnsupportedFilesInBuildIsSet_BuildSucceedWithWarning()
|
||||
{
|
||||
bool oldValue = Settings.IgnoreUnsupportedFilesInBuild;
|
||||
Settings.IgnoreUnsupportedFilesInBuild = true;
|
||||
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
|
||||
string path = GetAssetPath("fake.file");
|
||||
FileStream fs = File.Create(path);
|
||||
fs.Close();
|
||||
AssetDatabase.ImportAsset(path);
|
||||
string guid = AssetDatabase.AssetPathToGUID(path);
|
||||
|
||||
AddressableAssetEntry entry = Settings.CreateOrMoveEntry(guid, Settings.DefaultGroup);
|
||||
|
||||
foreach (BuildScriptBase db in Settings.DataBuilders.OfType<BuildScriptBase>())
|
||||
{
|
||||
if (db.GetType() == typeof(BuildScriptFastMode) || db.GetType() == typeof(BuildScriptPackedPlayMode))
|
||||
continue;
|
||||
|
||||
if (db.CanBuildData<AddressablesPlayerBuildResult>())
|
||||
{
|
||||
var res = db.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
Assert.IsTrue(db.IsDataBuilt());
|
||||
Assert.IsTrue(string.IsNullOrEmpty(res.Error));
|
||||
}
|
||||
else if (db.CanBuildData<AddressablesPlayModeBuildResult>())
|
||||
{
|
||||
var res = db.BuildData<AddressablesPlayModeBuildResult>(context);
|
||||
Assert.IsTrue(db.IsDataBuilt());
|
||||
Assert.IsTrue(string.IsNullOrEmpty(res.Error));
|
||||
}
|
||||
|
||||
LogAssert.Expect(LogType.Warning, new Regex($".*{path}.*ignored"));
|
||||
LogAssert.Expect(LogType.Warning, new Regex($".*{path}.*stripped"));
|
||||
}
|
||||
|
||||
Settings.RemoveAssetEntry(guid, false);
|
||||
AssetDatabase.DeleteAsset(path);
|
||||
Settings.IgnoreUnsupportedFilesInBuild = oldValue;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenLoadPathUsesHttp_AndInsecureHttpNotAllowed_BuildLogsWarning()
|
||||
{
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
InsecureHttpOption oldHttpOption = PlayerSettings.insecureHttpOption;
|
||||
PlayerSettings.insecureHttpOption = InsecureHttpOption.NotAllowed;
|
||||
|
||||
string remoteLoadPathId = Settings.profileSettings.GetProfileDataByName(AddressableAssetSettings.kRemoteLoadPath).Id;
|
||||
string oldRemoteLoadPath = Settings.profileSettings.GetValueById(Settings.activeProfileId, remoteLoadPathId);
|
||||
Settings.profileSettings.SetValue(Settings.activeProfileId, AddressableAssetSettings.kRemoteLoadPath, "http://insecureconnection/");
|
||||
|
||||
AddressableAssetGroup assetGroup = Settings.CreateGroup("InsecureConnections", false, false, false, null, typeof(BundledAssetGroupSchema));
|
||||
assetGroup.GetSchema<BundledAssetGroupSchema>().BuildPath.SetVariableById(Settings, Settings.profileSettings.GetProfileDataByName(AddressableAssetSettings.kRemoteBuildPath).Id);
|
||||
assetGroup.GetSchema<BundledAssetGroupSchema>().LoadPath.SetVariableById(Settings, Settings.profileSettings.GetProfileDataByName(AddressableAssetSettings.kRemoteLoadPath).Id);
|
||||
|
||||
string assetPath = Path.Combine(TestFolder, "insecureConnectionsTest.prefab");
|
||||
PrefabUtility.SaveAsPrefabAsset(new GameObject(), assetPath);
|
||||
Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(assetPath), assetGroup, false, false);
|
||||
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
BuildScriptBase db = (BuildScriptBase)Settings.DataBuilders.Find(x => x.GetType() == typeof(BuildScriptPackedMode));
|
||||
db.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
LogAssert.Expect(LogType.Warning, $"Addressable group {assetGroup.Name} uses insecure http for its load path. To allow http connections for UnityWebRequests, change your settings in Edit > Project Settings > Player > Other Settings > Configuration > Allow downloads over HTTP.");
|
||||
|
||||
Settings.RemoveGroup(assetGroup);
|
||||
Settings.profileSettings.SetValue(Settings.activeProfileId, AddressableAssetSettings.kRemoteLoadPath, oldRemoteLoadPath);
|
||||
AssetDatabase.DeleteAsset(assetPath);
|
||||
PlayerSettings.insecureHttpOption = oldHttpOption;
|
||||
#else
|
||||
Assert.Ignore($"Skipping test {nameof(WhenLoadPathUsesHttp_AndInsecureHttpNotAllowed_BuildLogsWarning)}.");
|
||||
#endif
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenLoadPathUsesHttp_AndInsecureHttpAllowed_BuildSucceeds()
|
||||
{
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
InsecureHttpOption oldHttpOption = PlayerSettings.insecureHttpOption;
|
||||
PlayerSettings.insecureHttpOption = InsecureHttpOption.AlwaysAllowed;
|
||||
|
||||
string remoteLoadPathId = Settings.profileSettings.GetProfileDataByName(AddressableAssetSettings.kRemoteLoadPath).Id;
|
||||
string oldRemoteLoadPath = Settings.profileSettings.GetValueById(Settings.activeProfileId, remoteLoadPathId);
|
||||
Settings.profileSettings.SetValue(Settings.activeProfileId, AddressableAssetSettings.kRemoteLoadPath, "http://insecureconnection/");
|
||||
|
||||
AddressableAssetGroup assetGroup = Settings.CreateGroup("InsecureConnections", false, false, false, null, typeof(BundledAssetGroupSchema));
|
||||
assetGroup.GetSchema<BundledAssetGroupSchema>().BuildPath.SetVariableById(Settings, Settings.profileSettings.GetProfileDataByName(AddressableAssetSettings.kRemoteBuildPath).Id);
|
||||
assetGroup.GetSchema<BundledAssetGroupSchema>().LoadPath.SetVariableById(Settings, Settings.profileSettings.GetProfileDataByName(AddressableAssetSettings.kRemoteLoadPath).Id);
|
||||
|
||||
string assetPath = Path.Combine(TestFolder, "insecureConnectionsTest.prefab");
|
||||
PrefabUtility.SaveAsPrefabAsset(new GameObject(), assetPath);
|
||||
Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(assetPath), assetGroup, false, false);
|
||||
|
||||
var context = new AddressablesDataBuilderInput(Settings);
|
||||
BuildScriptBase db = (BuildScriptBase)Settings.DataBuilders.Find(x => x.GetType() == typeof(BuildScriptPackedMode));
|
||||
db.BuildData<AddressablesPlayerBuildResult>(context);
|
||||
LogAssert.NoUnexpectedReceived();
|
||||
|
||||
Settings.RemoveGroup(assetGroup);
|
||||
Settings.profileSettings.SetValue(Settings.activeProfileId, AddressableAssetSettings.kRemoteLoadPath, oldRemoteLoadPath);
|
||||
AssetDatabase.DeleteAsset(assetPath);
|
||||
PlayerSettings.insecureHttpOption = oldHttpOption;
|
||||
#else
|
||||
Assert.Ignore($"Skipping test {nameof(WhenLoadPathUsesHttp_AndInsecureHttpAllowed_BuildSucceeds)}.");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e3e97670d537e784e9f104552b533056
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor.AddressableAssets.Build;
|
||||
using UnityEditor.AddressableAssets.Build.DataBuilders;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.AddressableAssets.Tests
|
||||
{
|
||||
public class BuildScriptVirtualTests : AddressableAssetTestBase
|
||||
{
|
||||
[Test]
|
||||
public void VirtualModeScript_CannotBuildPlayerContent()
|
||||
{
|
||||
var buildScript = ScriptableObject.CreateInstance<BuildScriptVirtualMode>();
|
||||
|
||||
Assert.IsFalse(buildScript.CanBuildData<AddressablesPlayerBuildResult>());
|
||||
|
||||
Assert.IsTrue(buildScript.CanBuildData<AddressableAssetBuildResult>());
|
||||
Assert.IsTrue(buildScript.CanBuildData<AddressablesPlayModeBuildResult>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b644b787231a1784ab6bbb39217a63b9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor.AddressableAssets.Build;
|
||||
using UnityEditor.AddressableAssets.Settings;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace UnityEditor.AddressableAssets.Tests
|
||||
{
|
||||
public class DataBuilderInputTests : AddressableAssetTestBase
|
||||
{
|
||||
[Test]
|
||||
public void BuildInput_FailsWithNullSettings()
|
||||
{
|
||||
var input = new AddressablesDataBuilderInput(null);
|
||||
LogAssert.Expect(LogType.Error, "Attempting to set up AddressablesDataBuilderInput with null settings.");
|
||||
Assert.AreEqual(string.Empty, input.PlayerVersion);
|
||||
input = new AddressablesDataBuilderInput(null, "123");
|
||||
LogAssert.Expect(LogType.Error, "Attempting to set up AddressablesDataBuilderInput with null settings.");
|
||||
Assert.AreEqual("123", input.PlayerVersion);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildInput_CreatesProperBuildData()
|
||||
{
|
||||
var input = new AddressablesDataBuilderInput(Settings);
|
||||
Assert.AreEqual(EditorUserBuildSettings.activeBuildTarget, input.Target);
|
||||
Assert.AreEqual(BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget), input.TargetGroup);
|
||||
Assert.AreEqual(Settings.PlayerBuildVersion, input.PlayerVersion);
|
||||
|
||||
|
||||
input = new AddressablesDataBuilderInput(Settings, "1234");
|
||||
Assert.AreEqual(EditorUserBuildSettings.activeBuildTarget, input.Target);
|
||||
Assert.AreEqual(BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget), input.TargetGroup);
|
||||
Assert.AreEqual("1234", input.PlayerVersion);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BuildInput_ReadsProfilerEventState()
|
||||
{
|
||||
var oldState = ProjectConfigData.PostProfilerEvents;
|
||||
ProjectConfigData.PostProfilerEvents = true;
|
||||
var input = new AddressablesDataBuilderInput(Settings);
|
||||
Assert.AreEqual(true, input.ProfilerEventsEnabled);
|
||||
|
||||
ProjectConfigData.PostProfilerEvents = false;
|
||||
input = new AddressablesDataBuilderInput(Settings);
|
||||
Assert.AreEqual(false, input.ProfilerEventsEnabled);
|
||||
|
||||
|
||||
ProjectConfigData.PostProfilerEvents = oldState;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateResult_AssignsAllCorrectData()
|
||||
{
|
||||
string settingsPath = "Settings/Path";
|
||||
int locCount = 2;
|
||||
string error = "Test Error";
|
||||
|
||||
var result = AddressableAssetBuildResult.CreateResult<AddressableAssetBuildResult>(settingsPath, locCount, error);
|
||||
|
||||
Assert.AreEqual(result.OutputPath, settingsPath);
|
||||
Assert.AreEqual(result.LocationCount, locCount);
|
||||
Assert.AreEqual(result.Error, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1575d1c3656610c40ad50c15e8f5855a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,314 @@
|
|||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AddressableAssets.Build.BuildPipelineTasks;
|
||||
using UnityEditor.AddressableAssets.Build.DataBuilders;
|
||||
using UnityEditor.AddressableAssets.Settings;
|
||||
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
|
||||
using UnityEditor.Build.Pipeline;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets.ResourceLocators;
|
||||
using UnityEngine.ResourceManagement.ResourceProviders;
|
||||
|
||||
public class GenerateLocationListsTaskTests : AddressableBuildTaskTestBase
|
||||
{
|
||||
GenerateLocationListsTask.Input GenerateDefaultInput()
|
||||
{
|
||||
var input = new GenerateLocationListsTask.Input();
|
||||
input.AssetToFiles = new Dictionary<GUID, List<string>>();
|
||||
input.FileToBundle = new Dictionary<string, string>();
|
||||
input.Settings = m_Settings;
|
||||
input.BundleToAssetGroup = new Dictionary<string, string>();
|
||||
input.Target = EditorUserBuildSettings.activeBuildTarget;
|
||||
return input;
|
||||
}
|
||||
|
||||
private bool FindLocationEntry(List<ContentCatalogDataEntry> locations, string key, out ContentCatalogDataEntry entry)
|
||||
{
|
||||
foreach (ContentCatalogDataEntry e in locations)
|
||||
if (e.Keys.Contains(key))
|
||||
{
|
||||
entry = e;
|
||||
return true;
|
||||
}
|
||||
|
||||
entry = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
static K GetKeyForValue<K, V>(Dictionary<K, V> dict, V value) where V : class
|
||||
{
|
||||
foreach (var kvp in dict)
|
||||
{
|
||||
if (kvp.Value == value)
|
||||
return kvp.Key;
|
||||
}
|
||||
|
||||
throw new System.Exception("Couldn't find value");
|
||||
}
|
||||
|
||||
string CreateAddressablePrefab(GenerateLocationListsTask.Input input, string name, AddressableAssetGroup group, params string[] depFiles)
|
||||
{
|
||||
string guid = CreateAsset($"{TempPath}/{name}.prefab", name);
|
||||
var entry = m_Settings.CreateOrMoveEntry(guid, group, false, false);
|
||||
entry.address = Path.GetFileNameWithoutExtension(entry.AssetPath);
|
||||
input.AssetToFiles[new GUID(guid)] = new List<string>(depFiles);
|
||||
return guid;
|
||||
}
|
||||
|
||||
AddressableAssetGroup CreateGroupMappedToBundle(GenerateLocationListsTask.Input input, string postfix)
|
||||
{
|
||||
AddressableAssetGroup group = m_Settings.CreateGroup($"testGroup{postfix}", false, false, false, null, typeof(BundledAssetGroupSchema));
|
||||
input.BundleToAssetGroup[$"bundle{postfix}"] = group.Guid;
|
||||
input.FileToBundle[$"file{postfix}"] = $"bundle{postfix}";
|
||||
return group;
|
||||
}
|
||||
|
||||
void AssertLocationDependencies(GenerateLocationListsTask.Output output, string location, params string[] deps)
|
||||
{
|
||||
FindLocationEntry(output.Locations, location, out ContentCatalogDataEntry e1);
|
||||
CollectionAssert.AreEquivalent(e1.Dependencies, deps);
|
||||
}
|
||||
|
||||
static List<AddressableAssetEntry> BuildAddressableAssetEntryList(AddressableAssetSettings settings)
|
||||
{
|
||||
List<AddressableAssetEntry> entries = new List<AddressableAssetEntry>();
|
||||
foreach (AddressableAssetGroup group in settings.groups)
|
||||
{
|
||||
group.GatherAllAssets(entries, true, true, false);
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenAssetLoadsFromBundle_ProviderTypesIncludesBundledAssetProvider()
|
||||
{
|
||||
GenerateLocationListsTask.Input input = GenerateDefaultInput();
|
||||
AddressableAssetGroup groupX = CreateGroupMappedToBundle(input, "X");
|
||||
CreateAddressablePrefab(input, "p1", groupX, "fileX");
|
||||
input.AddressableAssetEntries = BuildAddressableAssetEntryList(input.Settings);
|
||||
GenerateLocationListsTask.Output output = GenerateLocationListsTask.ProcessInput(input);
|
||||
CollectionAssert.Contains(output.ProviderTypes, typeof(BundledAssetProvider));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenIncludeGUIDInCatalog_SetFalse_GUIDSNotIncluded()
|
||||
{
|
||||
GenerateLocationListsTask.Input input = GenerateDefaultInput();
|
||||
AddressableAssetGroup groupX = CreateGroupMappedToBundle(input, "X");
|
||||
var schema = groupX.GetSchema<BundledAssetGroupSchema>();
|
||||
var guid = CreateAddressablePrefab(input, "p1", groupX, "fileX");
|
||||
input.AddressableAssetEntries = BuildAddressableAssetEntryList(input.Settings);
|
||||
schema.IncludeGUIDInCatalog = true;
|
||||
foreach (var l in GenerateLocationListsTask.ProcessInput(input).Locations)
|
||||
if (l.Provider == typeof(BundledAssetProvider).FullName)
|
||||
CollectionAssert.Contains(l.Keys, guid);
|
||||
|
||||
schema.IncludeGUIDInCatalog = false;
|
||||
foreach (var l in GenerateLocationListsTask.ProcessInput(input).Locations)
|
||||
if (l.Provider == typeof(BundledAssetProvider).FullName)
|
||||
CollectionAssert.DoesNotContain(l.Keys, guid);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CollectsGuidMapping_WhenCatalogKeysNotIncluded()
|
||||
{
|
||||
GenerateLocationListsTask.Input input = GenerateDefaultInput();
|
||||
AddressableAssetGroup groupX = CreateGroupMappedToBundle(input, "X");
|
||||
var schema = groupX.GetSchema<BundledAssetGroupSchema>();
|
||||
schema.IncludeAddressInCatalog = false;
|
||||
schema.IncludeGUIDInCatalog = false;
|
||||
schema.IncludeLabelsInCatalog = false;
|
||||
|
||||
var guid = CreateAddressablePrefab(input, "p1", groupX, "fileX");
|
||||
if (!GUID.TryParse(guid, out GUID g))
|
||||
Assert.IsFalse(g.Empty());
|
||||
|
||||
input.AddressableAssetEntries = BuildAddressableAssetEntryList(input.Settings);
|
||||
schema.IncludeGUIDInCatalog = true;
|
||||
var output = GenerateLocationListsTask.ProcessInput(input);
|
||||
Assert.AreEqual(1, output.GuidToLocation.Count, "Did not gather guid to catalog mapping");
|
||||
Assert.AreEqual(1, output.GuidToLocation[g].Count);
|
||||
|
||||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
Assert.AreEqual(path, output.GuidToLocation[g][0].InternalId);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenIncludeAddressOptionChanged_LocationsKeysAreSetCorrectly()
|
||||
{
|
||||
GenerateLocationListsTask.Input input = GenerateDefaultInput();
|
||||
AddressableAssetGroup groupX = CreateGroupMappedToBundle(input, "X");
|
||||
var schema = groupX.GetSchema<BundledAssetGroupSchema>();
|
||||
var guid = CreateAddressablePrefab(input, "p1", groupX, "fileX");
|
||||
input.AddressableAssetEntries = BuildAddressableAssetEntryList(input.Settings);
|
||||
|
||||
schema.IncludeAddressInCatalog = true;
|
||||
foreach (var l in GenerateLocationListsTask.ProcessInput(input).Locations)
|
||||
if (l.Provider == typeof(BundledAssetProvider).FullName)
|
||||
CollectionAssert.Contains(l.Keys, "p1");
|
||||
|
||||
schema.IncludeAddressInCatalog = false;
|
||||
foreach (var l in GenerateLocationListsTask.ProcessInput(input).Locations)
|
||||
if (l.Provider == typeof(BundledAssetProvider).FullName)
|
||||
CollectionAssert.DoesNotContain(l.Keys, "p1");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenIncludeLabelsOptionChanged_LocationsKeysAreSetCorrectly()
|
||||
{
|
||||
GenerateLocationListsTask.Input input = GenerateDefaultInput();
|
||||
AddressableAssetGroup groupX = CreateGroupMappedToBundle(input, "X");
|
||||
var schema = groupX.GetSchema<BundledAssetGroupSchema>();
|
||||
var guid = CreateAddressablePrefab(input, "p1", groupX, "fileX");
|
||||
groupX.GetAssetEntry(guid).SetLabel("LABEL1", true, true, true);
|
||||
input.AddressableAssetEntries = BuildAddressableAssetEntryList(input.Settings);
|
||||
|
||||
schema.IncludeLabelsInCatalog = true;
|
||||
foreach (var l in GenerateLocationListsTask.ProcessInput(input).Locations)
|
||||
if (l.Provider == typeof(BundledAssetProvider).FullName)
|
||||
CollectionAssert.Contains(l.Keys, "LABEL1");
|
||||
|
||||
schema.IncludeLabelsInCatalog = false;
|
||||
foreach (var l in GenerateLocationListsTask.ProcessInput(input).Locations)
|
||||
if (l.Provider == typeof(BundledAssetProvider).FullName)
|
||||
CollectionAssert.DoesNotContain(l.Keys, "LABEL1");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenGroupCreatesMultipleBundles_AllBundlesInAssetGroupToBundlesMap()
|
||||
{
|
||||
GenerateLocationListsTask.Input input = GenerateDefaultInput();
|
||||
AddressableAssetGroup group = m_Settings.CreateGroup($"groupX", false, false, false, null, typeof(BundledAssetGroupSchema));
|
||||
input.BundleToAssetGroup["bundleX"] = group.Guid;
|
||||
input.BundleToAssetGroup["bundleY"] = group.Guid;
|
||||
input.FileToBundle["fileX"] = "bundle1";
|
||||
input.FileToBundle["fileY"] = "bundle2";
|
||||
CreateAddressablePrefab(input, "p1", group, "fileX");
|
||||
CreateAddressablePrefab(input, "p2", group, "fileY");
|
||||
input.AddressableAssetEntries = BuildAddressableAssetEntryList(input.Settings);
|
||||
GenerateLocationListsTask.Output output = GenerateLocationListsTask.ProcessInput(input);
|
||||
CollectionAssert.AreEquivalent(new string[] {"bundle1", "bundle2"}, output.AssetGroupToBundles[group]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WhenAssetHasDependencyOnBundle_AssetLocationIncludesRecursiveBundleDependencies()
|
||||
{
|
||||
GenerateLocationListsTask.Input input = GenerateDefaultInput();
|
||||
|
||||
AddressableAssetGroup groupX = CreateGroupMappedToBundle(input, "X");
|
||||
AddressableAssetGroup groupY = CreateGroupMappedToBundle(input, "Y");
|
||||
AddressableAssetGroup groupZ = CreateGroupMappedToBundle(input, "Z");
|
||||
AddressableAssetGroup groupW = CreateGroupMappedToBundle(input, "W");
|
||||
|
||||
CreateAddressablePrefab(input, "p1", groupX, "fileX", "fileY");
|
||||
CreateAddressablePrefab(input, "p2", groupY, "fileY");
|
||||
CreateAddressablePrefab(input, "p3", groupY, "fileY", "fileZ");
|
||||
CreateAddressablePrefab(input, "p4", groupZ, "fileZ");
|
||||
CreateAddressablePrefab(input, "p5", groupZ, "fileZ", "fileW");
|
||||
CreateAddressablePrefab(input, "p6", groupW, "fileW");
|
||||
|
||||
input.AddressableAssetEntries = BuildAddressableAssetEntryList(input.Settings);
|
||||
GenerateLocationListsTask.Output output = GenerateLocationListsTask.ProcessInput(input);
|
||||
|
||||
AssertLocationDependencies(output, "p1", "bundleX", "bundleY", "bundleZ", "bundleW");
|
||||
AssertLocationDependencies(output, "p2", "bundleY", "bundleZ", "bundleW");
|
||||
AssertLocationDependencies(output, "p3", "bundleY", "bundleZ", "bundleW");
|
||||
AssertLocationDependencies(output, "p4", "bundleZ", "bundleW");
|
||||
AssertLocationDependencies(output, "p5", "bundleZ", "bundleW");
|
||||
AssertLocationDependencies(output, "p6", "bundleW");
|
||||
}
|
||||
|
||||
//static
|
||||
[Test]
|
||||
[TestCase("abc", BuildTarget.XboxOne, @"\abc")]
|
||||
[TestCase("abc", BuildTarget.StandaloneWindows64, @"\abc")]
|
||||
[TestCase("abc", BuildTarget.iOS, @"/abc")]
|
||||
[TestCase("abc", BuildTarget.Android, @"/abc")]
|
||||
[TestCase("abc", BuildTarget.StandaloneLinux64, @"/abc")]
|
||||
[TestCase("abc", BuildTarget.Switch, @"/abc")]
|
||||
[TestCase("abc", BuildTarget.StandaloneOSX, @"/abc")]
|
||||
public void WhenBuildTargetIsWindowsOrXBox_BackSlashUsedInLoadPath(string id, BuildTarget target, string expected)
|
||||
{
|
||||
AddressableAssetGroup group = m_Settings.CreateGroup($"xyz", false, false, false, null, typeof(BundledAssetGroupSchema));
|
||||
var bag = group.GetSchema<BundledAssetGroupSchema>();
|
||||
var expectedPath = $"{bag.LoadPath.GetValue(m_Settings)}{expected}".Replace('/', GenerateLocationListsTask.PathSeparatorForPlatform(target));
|
||||
var path = GenerateLocationListsTask.GetLoadPath(group, id, target);
|
||||
Assert.AreEqual(expectedPath, path);
|
||||
m_Settings.RemoveGroup(group);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("abc", BuildTarget.XboxOne)]
|
||||
[TestCase("abc", BuildTarget.StandaloneWindows64)]
|
||||
[TestCase("abc", BuildTarget.iOS)]
|
||||
[TestCase("abc", BuildTarget.Android)]
|
||||
[TestCase("abc", BuildTarget.StandaloneLinux64)]
|
||||
[TestCase("abc", BuildTarget.Switch)]
|
||||
[TestCase("abc", BuildTarget.StandaloneOSX)]
|
||||
public void WhenPathIsRemote_WithTrailingSlash_PathIsNotMalformed(string id, BuildTarget target)
|
||||
{
|
||||
//Setup
|
||||
string baseId = m_Settings.profileSettings.Reset();
|
||||
string profileId = m_Settings.profileSettings.AddProfile("remote", baseId);
|
||||
m_Settings.profileSettings.SetValue(profileId, AddressableAssetSettings.kRemoteLoadPath, "http://127.0.0.1:80/");
|
||||
m_Settings.activeProfileId = profileId;
|
||||
AddressableAssetGroup group = m_Settings.CreateGroup($"xyz", false, false, false, null, typeof(BundledAssetGroupSchema));
|
||||
var bag = group.GetSchema<BundledAssetGroupSchema>();
|
||||
bag.LoadPath.Id = m_Settings.profileSettings.GetVariableId(AddressableAssetSettings.kRemoteLoadPath);
|
||||
|
||||
//Test
|
||||
var path = GenerateLocationListsTask.GetLoadPath(group, id, target);
|
||||
string pahWithoutHttp = path.Replace("http://", "");
|
||||
|
||||
//Assert
|
||||
Assert.IsFalse(path.Contains("/\\"));
|
||||
Assert.IsFalse(pahWithoutHttp.Contains("//"));
|
||||
|
||||
//Cleanup
|
||||
m_Settings.RemoveGroup(group);
|
||||
m_Settings.activeProfileId = baseId;
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("abc", BuildTarget.XboxOne)]
|
||||
[TestCase("abc", BuildTarget.StandaloneWindows64)]
|
||||
[TestCase("abc", BuildTarget.iOS)]
|
||||
[TestCase("abc", BuildTarget.Android)]
|
||||
[TestCase("abc", BuildTarget.StandaloneLinux64)]
|
||||
[TestCase("abc", BuildTarget.Switch)]
|
||||
[TestCase("abc", BuildTarget.StandaloneOSX)]
|
||||
public void WhenPathIsRemote_WithoutTrailingSlash_PathIsNotMalformed(string id, BuildTarget target)
|
||||
{
|
||||
//Setup
|
||||
string baseId = m_Settings.profileSettings.Reset();
|
||||
string profileId = m_Settings.profileSettings.AddProfile("remote", baseId);
|
||||
m_Settings.profileSettings.SetValue(profileId, AddressableAssetSettings.kRemoteLoadPath, "http://127.0.0.1:80");
|
||||
m_Settings.activeProfileId = profileId;
|
||||
AddressableAssetGroup group = m_Settings.CreateGroup($"xyz", false, false, false, null, typeof(BundledAssetGroupSchema));
|
||||
var bag = group.GetSchema<BundledAssetGroupSchema>();
|
||||
bag.LoadPath.Id = m_Settings.profileSettings.GetVariableId(AddressableAssetSettings.kRemoteLoadPath);
|
||||
|
||||
//Test
|
||||
var path = GenerateLocationListsTask.GetLoadPath(group, id, target);
|
||||
string pahWithoutHttp = path.Replace("http://", "");
|
||||
|
||||
//Assert
|
||||
Assert.IsFalse(path.Contains("/\\"));
|
||||
Assert.IsFalse(pahWithoutHttp.Contains("//"));
|
||||
|
||||
//Cleanup
|
||||
m_Settings.RemoveGroup(group);
|
||||
m_Settings.activeProfileId = baseId;
|
||||
}
|
||||
|
||||
//[Test]
|
||||
//public void WhenEntryAddressContainsBrackets_ExceptionIsThrown()
|
||||
//{
|
||||
// TODO:
|
||||
//}
|
||||
//}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 28e27e70c0f8cee45a62f86887957a0f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
Add table
Add a link
Reference in a new issue