WuhuIslandTesting/Library/PackageCache/com.unity.addressables@1.21.12/Tests/Editor/ContentUpdateTests.cs
2025-01-07 02:06:59 +01:00

1372 lines
75 KiB
C#

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using AddressableAssetsIntegrationTests;
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;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.TestTools;
namespace UnityEditor.AddressableAssets.Tests
{
public class ContentUpdateTests : AddressableAssetTestBase
{
protected override bool PersistSettings
{
get { return true; }
}
[Test]
public void CanCreateContentStateData()
{
var group = Settings.CreateGroup("LocalStuff", false, false, false, null);
var schema = group.AddSchema<BundledAssetGroupSchema>();
schema.BuildPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalBuildPath);
schema.LoadPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalLoadPath);
schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
group.AddSchema<ContentUpdateGroupSchema>().StaticContent = true;
Settings.CreateOrMoveEntry(m_AssetGUID, group);
var context = new AddressablesDataBuilderInput(Settings);
var op = Settings.ActivePlayerDataBuilder.BuildData<AddressablesPlayerBuildResult>(context);
Assert.IsTrue(string.IsNullOrEmpty(op.Error), op.Error);
var tempPath = Path.GetDirectoryName(Application.dataPath) + "/" + Addressables.LibraryPath + PlatformMappingService.GetPlatformPathSubFolder() + "/addressables_content_state.bin";
var cacheData = ContentUpdateScript.LoadContentState(tempPath);
Assert.NotNull(cacheData);
Settings.RemoveGroup(group);
}
[Test]
public void ContentState_WithDisabledGroups_DoesNotInclude_EntriesFromGroup()
{
var group = Settings.CreateGroup("RemoteStuff", false, false, false, null);
var schema = group.AddSchema<BundledAssetGroupSchema>();
schema.BuildPath.SetVariableByName(Settings, AddressableAssetSettings.kRemoteBuildPath);
schema.LoadPath.SetVariableByName(Settings, AddressableAssetSettings.kRemoteLoadPath);
schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
group.AddSchema<ContentUpdateGroupSchema>().StaticContent = true;
Settings.CreateOrMoveEntry(m_AssetGUID, group);
var group2 = Settings.CreateGroup("LocalStuff", false, false, false, null);
var schema2 = group2.AddSchema<BundledAssetGroupSchema>();
schema2.BuildPath.SetVariableByName(Settings, AddressableAssetSettings.kRemoteBuildPath);
schema2.LoadPath.SetVariableByName(Settings, AddressableAssetSettings.kRemoteLoadPath);
schema2.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
group2.AddSchema<ContentUpdateGroupSchema>().StaticContent = true;
Settings.CreateOrMoveEntry(m_SceneGuids[0], group2);
var context = new AddressablesDataBuilderInput(Settings);
var op = Settings.ActivePlayerDataBuilder.BuildData<AddressablesPlayerBuildResult>(context);
Assert.IsTrue(string.IsNullOrEmpty(op.Error), op.Error);
var tempPath = Path.GetDirectoryName(Application.dataPath) + "/" + Addressables.LibraryPath + PlatformMappingService.GetPlatformPathSubFolder() + "/addressables_content_state.bin";
var cacheData = ContentUpdateScript.LoadContentState(tempPath);
Assert.NotNull(cacheData);
Assert.NotNull(cacheData.cachedInfos.FirstOrDefault(s => s.asset.guid.ToString() == m_AssetGUID));
schema.IncludeInBuild = false;
context = new AddressablesDataBuilderInput(Settings);
op = Settings.ActivePlayerDataBuilder.BuildData<AddressablesPlayerBuildResult>(context);
Assert.IsTrue(string.IsNullOrEmpty(op.Error), op.Error);
tempPath = Path.GetDirectoryName(Application.dataPath) + "/" + Addressables.LibraryPath + PlatformMappingService.GetPlatformPathSubFolder() + "/addressables_content_state.bin";
cacheData = ContentUpdateScript.LoadContentState(tempPath);
Assert.NotNull(cacheData);
Assert.IsNull(cacheData.cachedInfos.FirstOrDefault(s => s.asset.guid.ToString() == m_AssetGUID));
Settings.RemoveGroup(group);
Settings.RemoveGroup(group2);
}
[Test]
public void CreateCustomLocator_ReturnsLocatorWithUniqueId()
{
ContentCatalogData ccd = new ContentCatalogData();
ccd.SetData(new List<ContentCatalogDataEntry>());
IResourceLocator map = ccd.CreateCustomLocator("test");
Assert.AreEqual("test", map.LocatorId);
}
[Test]
public void DownloadBinFileToTempLocation_DoesNotThrowError_WhenDownloadFails()
{
Assert.DoesNotThrow(() =>
{
var returnValue = ContentUpdateScript.DownloadBinFileToTempLocation("http://notarealurl.com/addressable_state.bin");
Assert.AreEqual(ContentUpdateScript.PreviousContentStateFileCachePath, returnValue);
});
}
[Test]
public void PrepareContentUpdate()
{
var group = Settings.CreateGroup("LocalStuff2", false, false, false, null);
var schema = group.AddSchema<BundledAssetGroupSchema>();
schema.BuildPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalBuildPath);
schema.LoadPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalLoadPath);
schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
group.AddSchema<ContentUpdateGroupSchema>().StaticContent = true;
var entry = Settings.CreateOrMoveEntry(m_AssetGUID, group);
entry.address = "test";
var context = new AddressablesDataBuilderInput(Settings);
Settings.ActivePlayerDataBuilder.BuildData<AddressablesPlayerBuildResult>(context);
var path = AssetDatabase.GUIDToAssetPath(m_AssetGUID);
var obj = AssetDatabase.LoadAssetAtPath<GameObject>(path);
obj.GetComponent<Transform>().SetPositionAndRotation(new Vector3(10, 10, 10), Quaternion.identity);
PrefabUtility.SavePrefabAsset(obj);
AssetDatabase.SaveAssets();
var tempPath = Path.GetDirectoryName(Application.dataPath) + "/" + Addressables.LibraryPath + PlatformMappingService.GetPlatformPathSubFolder() + "/addressables_content_state.bin";
var modifiedEntries = ContentUpdateScript.GatherModifiedEntries(Settings, tempPath);
Assert.IsNotNull(modifiedEntries);
Assert.GreaterOrEqual(modifiedEntries.Count, 1);
ContentUpdateScript.CreateContentUpdateGroup(Settings, modifiedEntries, "Content Update");
var contentGroup = Settings.FindGroup("Content Update");
Assert.IsNotNull(contentGroup);
var movedEntry = contentGroup.GetAssetEntry(m_AssetGUID);
Assert.AreSame(movedEntry, entry);
Settings.RemoveGroup(group);
}
[Test]
public void GatherModifiedEntries_WhenDependencyBundleNameIsSame_DependencyIsNotFlaggedAsModified()
{
// Create assets
GameObject mainObject = new GameObject("mainObject");
Material mat = new Material(Shader.Find("Transparent/Diffuse"));
mainObject.AddComponent<MeshRenderer>().material = mat;
string mainAssetPath = GetAssetPath("mainObject.prefab");
string staticAssetPath = GetAssetPath("staticObject.mat");
AssetDatabase.CreateAsset(mat, staticAssetPath);
PrefabUtility.SaveAsPrefabAsset(mainObject, mainAssetPath);
AssetDatabase.SaveAssets();
// Create addressables
AddressableAssetGroup mainAssetGroup = Settings.CreateGroup("PrefabGroup", false, false, false, null);
AddressableAssetGroup staticContentGroup = Settings.CreateGroup("MatGroup", false, false, false, null);
var schema = mainAssetGroup.AddSchema<BundledAssetGroupSchema>();
schema.BuildPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalBuildPath);
schema.LoadPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalLoadPath);
schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
mainAssetGroup.AddSchema<ContentUpdateGroupSchema>().StaticContent = true;
schema = staticContentGroup.AddSchema<BundledAssetGroupSchema>();
schema.BuildPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalBuildPath);
schema.LoadPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalLoadPath);
schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
staticContentGroup.AddSchema<ContentUpdateGroupSchema>().StaticContent = true;
AddressableAssetEntry mainEntry = Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(mainAssetPath), mainAssetGroup);
AddressableAssetEntry staticEntry = Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(staticAssetPath), staticContentGroup);
// Build
var context = new AddressablesDataBuilderInput(Settings);
Settings.ActivePlayerDataBuilder.BuildData<AddressablesPlayerBuildResult>(context);
// Modify assets
var mainAsset = AssetDatabase.LoadAssetAtPath<GameObject>(mainAssetPath);
mainAsset.GetComponent<Transform>().SetPositionAndRotation(new Vector3(10, 10, 10), Quaternion.identity);
PrefabUtility.SavePrefabAsset(mainAsset);
AssetDatabase.SaveAssets();
// Test
var tempPath = Path.GetDirectoryName(Application.dataPath) + "/Library/com.unity.addressables/" + PlatformMappingService.GetPlatformPathSubFolder() + "/addressables_content_state.bin";
var modifiedEntries = ContentUpdateScript.GatherModifiedEntries(Settings, tempPath);
Assert.AreEqual(1, modifiedEntries.Count);
Assert.AreSame(modifiedEntries[0], mainEntry);
// Cleanup
GameObject.DestroyImmediate(mainObject);
Settings.RemoveGroup(mainAssetGroup);
Settings.RemoveGroup(staticContentGroup);
AssetDatabase.DeleteAsset(mainAssetPath);
AssetDatabase.DeleteAsset(staticAssetPath);
}
[Test]
public void GatherModifiedEntries_WhenDependencyBundleNameIsChanged_DependencyIsFlaggedAsModified()
{
// Create assets
GameObject mainObject = new GameObject("mainObject");
Material mat = new Material(Shader.Find("Transparent/Diffuse"));
mainObject.AddComponent<MeshRenderer>().material = mat;
string mainAssetPath = GetAssetPath("mainObject.prefab");
string staticAssetPath = GetAssetPath("staticObject.mat");
AssetDatabase.CreateAsset(mat, staticAssetPath);
PrefabUtility.SaveAsPrefabAsset(mainObject, mainAssetPath);
AssetDatabase.SaveAssets();
// Create addressables
AddressableAssetGroup mainAssetGroup = Settings.CreateGroup("PrefabGroup2", false, false, false, null);
AddressableAssetGroup staticContentGroup = Settings.CreateGroup("MatGroup2", false, false, false, null);
var schema = mainAssetGroup.AddSchema<BundledAssetGroupSchema>();
schema.BuildPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalBuildPath);
schema.LoadPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalLoadPath);
schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
mainAssetGroup.AddSchema<ContentUpdateGroupSchema>().StaticContent = true;
schema = staticContentGroup.AddSchema<BundledAssetGroupSchema>();
schema.BuildPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalBuildPath);
schema.LoadPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalLoadPath);
schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
staticContentGroup.AddSchema<ContentUpdateGroupSchema>().StaticContent = true;
AddressableAssetEntry mainEntry = Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(mainAssetPath), mainAssetGroup);
AddressableAssetEntry staticEntry = Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(staticAssetPath), staticContentGroup);
// Build
var context = new AddressablesDataBuilderInput(Settings);
Settings.ActivePlayerDataBuilder.BuildData<AddressablesPlayerBuildResult>(context);
// Modify assets
var mainAsset = AssetDatabase.LoadAssetAtPath<GameObject>(mainAssetPath);
mainAsset.GetComponent<Transform>().SetPositionAndRotation(new Vector3(10, 10, 10), Quaternion.identity);
PrefabUtility.SavePrefabAsset(mainAsset);
staticContentGroup.GetSchema<BundledAssetGroupSchema>().InternalBundleIdMode = BundledAssetGroupSchema.BundleInternalIdMode.GroupGuidProjectIdEntriesHash;
AssetDatabase.SaveAssets();
// Test
var tempPath = Path.GetDirectoryName(Application.dataPath) + "/Library/com.unity.addressables/" + PlatformMappingService.GetPlatformPathSubFolder() + "/addressables_content_state.bin";
var modifiedEntries = ContentUpdateScript.GatherModifiedEntries(Settings, tempPath);
Assert.AreEqual(2, modifiedEntries.Count);
Assert.IsTrue(modifiedEntries.Contains(staticEntry));
// Cleanup
GameObject.DestroyImmediate(mainObject);
Settings.RemoveGroup(mainAssetGroup);
Settings.RemoveGroup(staticContentGroup);
AssetDatabase.DeleteAsset(mainAssetPath);
AssetDatabase.DeleteAsset(staticAssetPath);
}
[Test]
public void GetStaticContentDependenciesOfModifiedEntries_FlagsEntryDependencies_WithStaticContentEnabled()
{
var mainAssetGroup = Settings.CreateGroup("MainAssetGroup", false, false, false, null,
typeof(ContentUpdateGroupSchema), typeof(BundledAssetGroupSchema));
var staticContentGroup = Settings.CreateGroup("StaticContentGroup", false, false, false, null,
typeof(ContentUpdateGroupSchema), typeof(BundledAssetGroupSchema));
mainAssetGroup.GetSchema<ContentUpdateGroupSchema>().StaticContent = true;
staticContentGroup.GetSchema<ContentUpdateGroupSchema>().StaticContent = true;
GameObject mainObject = new GameObject("mainObject");
Material mat = new Material(Shader.Find("Transparent/Diffuse"));
mainObject.AddComponent<MeshRenderer>().material = mat;
string mainAssetPath = GetAssetPath("mainObject.prefab");
string staticAssetPath = GetAssetPath("staticObject.mat");
AssetDatabase.CreateAsset(mat, staticAssetPath);
PrefabUtility.SaveAsPrefabAsset(mainObject, mainAssetPath);
AssetDatabase.SaveAssets();
var mainEntry = Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(mainAssetPath), mainAssetGroup);
var staticEntry = Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(staticAssetPath), staticContentGroup);
List<AddressableAssetEntry> modifiedEntries = new List<AddressableAssetEntry>()
{
mainEntry
};
Dictionary<AddressableAssetEntry, List<AddressableAssetEntry>> staticDependencies = new Dictionary<AddressableAssetEntry, List<AddressableAssetEntry>>()
{
{mainEntry, new List<AddressableAssetEntry>()}
};
ContentUpdateScript.GetStaticContentDependenciesForEntries(Settings, ref staticDependencies, null);
Assert.AreEqual(1, staticDependencies.Count);
Assert.AreEqual(1, staticDependencies[mainEntry].Count);
Assert.IsTrue(staticDependencies[mainEntry].Contains(staticEntry));
//Cleanup
GameObject.DestroyImmediate(mainObject);
Settings.RemoveGroup(mainAssetGroup);
Settings.RemoveGroup(staticContentGroup);
AssetDatabase.DeleteAsset(mainAssetPath);
AssetDatabase.DeleteAsset(staticAssetPath);
}
[Test]
public void GetStaticContentDependenciesOfModifiedEntries_DoesNotFlagEntryDependencies_WithStaticContentDisabled()
{
var mainAssetGroup = Settings.CreateGroup("MainAssetGroup", false, false, false, null,
typeof(ContentUpdateGroupSchema), typeof(BundledAssetGroupSchema));
var dynamicContentGroup = Settings.CreateGroup("DynamicContentGroup", false, false, false, null,
typeof(ContentUpdateGroupSchema), typeof(BundledAssetGroupSchema));
mainAssetGroup.GetSchema<ContentUpdateGroupSchema>().StaticContent = true;
dynamicContentGroup.GetSchema<ContentUpdateGroupSchema>().StaticContent = false;
GameObject mainObject = new GameObject("mainObject");
Material mat = new Material(Shader.Find("Transparent/Diffuse"));
mainObject.AddComponent<MeshRenderer>().material = mat;
string mainAssetPath = GetAssetPath("mainObject.prefab");
string dynamicAssetPath = GetAssetPath("dynamicObject.mat");
AssetDatabase.CreateAsset(mat, dynamicAssetPath);
PrefabUtility.SaveAsPrefabAsset(mainObject, mainAssetPath);
AssetDatabase.SaveAssets();
var mainEntry = Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(mainAssetPath), mainAssetGroup);
Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(dynamicAssetPath), dynamicContentGroup);
List<AddressableAssetEntry> modifiedEntries = new List<AddressableAssetEntry>()
{
mainEntry
};
Dictionary<AddressableAssetEntry, List<AddressableAssetEntry>> staticDependencies = new Dictionary<AddressableAssetEntry, List<AddressableAssetEntry>>()
{
{mainEntry, new List<AddressableAssetEntry>()}
};
ContentUpdateScript.GetStaticContentDependenciesForEntries(Settings, ref staticDependencies, null);
Assert.AreEqual(1, staticDependencies.Count);
Assert.AreEqual(0, staticDependencies[mainEntry].Count);
//Cleanup
GameObject.DestroyImmediate(mainObject);
Settings.RemoveGroup(mainAssetGroup);
Settings.RemoveGroup(dynamicContentGroup);
AssetDatabase.DeleteAsset(mainAssetPath);
AssetDatabase.DeleteAsset(dynamicAssetPath);
}
[Test]
public void GetStaticContentDependenciesOfModifiedEntries_WhenFolderHasModifiedImplicitAsset_DependenciesFlaggedAsModified()
{
var mainAssetGroup = Settings.CreateGroup("MainAssetGroup", false, false, false, null,
typeof(ContentUpdateGroupSchema), typeof(BundledAssetGroupSchema));
mainAssetGroup.GetSchema<ContentUpdateGroupSchema>().StaticContent = true;
mainAssetGroup.GetSchema<BundledAssetGroupSchema>().InternalBundleIdMode = BundledAssetGroupSchema.BundleInternalIdMode.GroupGuidProjectIdEntriesHash;
GameObject mainObject = new GameObject("mainObject");
Material mat = new Material(Shader.Find("Transparent/Diffuse"));
mainObject.AddComponent<MeshRenderer>().material = mat;
string folderName = "ContentUpdateFolder";
string folderGuid = AssetDatabase.CreateFolder(ConfigFolder, folderName);
string folderPath = Path.Combine(ConfigFolder, folderName).Replace("\\", "/");
string mainAssetPath = Path.Combine(folderPath, "mainAsset.prefab").Replace("\\", "/");
string subAssetPath = Path.Combine(folderPath, "subAsset.mat").Replace("\\", "/");
AssetDatabase.CreateAsset(mat, subAssetPath);
PrefabUtility.SaveAsPrefabAsset(mainObject, mainAssetPath);
AssetDatabase.SaveAssets();
string mainAssetGuid = AssetDatabase.AssetPathToGUID(mainAssetPath);
string subAssetGuid = AssetDatabase.AssetPathToGUID(subAssetPath);
var folderEntry = Settings.CreateOrMoveEntry(folderGuid, mainAssetGroup);
var entries = new List<AddressableAssetEntry>();
folderEntry.GatherAllAssets(entries, false, false, true);
AddressableAssetEntry mainAssetEntry = entries.Find(x => x.guid == mainAssetGuid);
var staticDependencies = new Dictionary<AddressableAssetEntry, List<AddressableAssetEntry>>()
{
{mainAssetEntry, new List<AddressableAssetEntry>()}
};
string cachedBundleName = "cachedBundleName";
var groupGuidToCacheBundleName = new Dictionary<string, string>()
{
{folderGuid, cachedBundleName},
{mainAssetGuid, cachedBundleName},
{subAssetGuid, cachedBundleName},
};
ContentUpdateScript.GetStaticContentDependenciesForEntries(Settings, ref staticDependencies, groupGuidToCacheBundleName);
Assert.AreEqual(1, staticDependencies.Count);
Assert.AreEqual(2, staticDependencies[mainAssetEntry].Count);
//Cleanup
GameObject.DestroyImmediate(mainObject);
Settings.RemoveGroup(mainAssetGroup);
AssetDatabase.DeleteAsset(folderPath);
}
static IResourceLocator GetLocatorFromCatalog(IEnumerable<string> paths)
{
foreach (var p in paths)
{
if(Path.GetFileNameWithoutExtension(p).EndsWith("catalog"))
return ContentCatalogData.LoadFromFile(p).CreateCustomLocator();
}
return null;
}
#if !ENABLE_BINARY_CATALOG
[Test]
public void WhenContentUpdated_NewCatalogRetains_OldCatalogBundleLoadData()
{
var group = Settings.CreateGroup("LocalStuff3", false, false, false, null);
Settings.BuildRemoteCatalog = true;
Settings.RemoteCatalogBuildPath = new ProfileValueReference();
Settings.RemoteCatalogBuildPath.SetVariableByName(Settings, AddressableAssetSettings.kRemoteBuildPath);
Settings.RemoteCatalogLoadPath = new ProfileValueReference();
Settings.RemoteCatalogLoadPath.SetVariableByName(Settings, AddressableAssetSettings.kRemoteLoadPath);
var schema = group.AddSchema<BundledAssetGroupSchema>();
schema.BuildPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalBuildPath);
schema.LoadPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalLoadPath);
schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
schema.UseAssetBundleCrc = true;
schema.UseAssetBundleCache = true;
group.AddSchema<ContentUpdateGroupSchema>().StaticContent = true;
Settings.CreateOrMoveEntry(m_AssetGUID, group);
var context = new AddressablesDataBuilderInput(Settings);
var op = Settings.ActivePlayerDataBuilder.BuildData<AddressablesPlayerBuildResult>(context);
Assert.IsTrue(string.IsNullOrEmpty(op.Error), op.Error);
var origLocator = GetLocatorFromCatalog(op.FileRegistry.GetFilePaths());
Assert.NotNull(origLocator);
var tempPath = Path.GetDirectoryName(Application.dataPath) + "/" + Addressables.LibraryPath + PlatformMappingService.GetPlatformPathSubFolder() + "/addressables_content_state.bin";
var contentState = ContentUpdateScript.LoadContentState(tempPath);
Assert.NotNull(contentState);
Assert.NotNull(contentState.cachedBundles);
Assert.AreEqual(1, contentState.cachedBundles.Length);
var buildOp = ContentUpdateScript.BuildContentUpdate(Settings, tempPath);
Assert.IsNotNull(buildOp);
Assert.IsTrue(string.IsNullOrEmpty(buildOp.Error));
var updatedLocator = GetLocatorFromCatalog(buildOp.FileRegistry.GetFilePaths());
Assert.IsNotNull(updatedLocator);
foreach (var k in updatedLocator.Keys)
{
if (origLocator.Locate(k, typeof(IAssetBundleResource), out var origLocs))
{
Assert.IsTrue(updatedLocator.Locate(k, typeof(IAssetBundleResource), out var updatedLocs));
Assert.AreEqual(1, origLocs.Count);
Assert.AreEqual(1, updatedLocs.Count);
var oLoc = origLocs[0];
var uLoc = updatedLocs[0];
Assert.NotNull(oLoc.Data);
Assert.NotNull(uLoc.Data);
var oData = oLoc.Data as AssetBundleRequestOptions;
var uData = uLoc.Data as AssetBundleRequestOptions;
Assert.NotNull(oData);
Assert.NotNull(uData);
Assert.AreEqual(oData.Hash, uData.Hash);
Assert.AreEqual(oData.Crc, uData.Crc);
}
}
Settings.RemoveGroup(group);
}
#endif
[Test]
public void IsCacheDataValid_WhenNoPreviousRemoteCatalogPath_ReturnsFalseWithError()
{
AddressablesContentState cacheData = new AddressablesContentState();
cacheData.editorVersion = Application.unityVersion;
Assert.IsFalse(ContentUpdateScript.IsCacheDataValid(Settings, cacheData));
LogAssert.Expect(LogType.Error, new Regex("Previous build had 'Build Remote Catalog' disabled.*"));
}
[Test]
public void IsCacheDataValid_WhenRemoteCatalogDisabled_ReturnsFalseWithError()
{
AddressablesContentState cacheData = new AddressablesContentState();
cacheData.editorVersion = Application.unityVersion;
cacheData.remoteCatalogLoadPath = "somePath";
var oldSetting = Settings.BuildRemoteCatalog;
Settings.BuildRemoteCatalog = false;
Assert.IsFalse(ContentUpdateScript.IsCacheDataValid(Settings, cacheData));
LogAssert.Expect(LogType.Error, new Regex("Current settings have 'Build Remote Catalog' disabled.*"));
Settings.BuildRemoteCatalog = oldSetting;
}
[Test]
public void IsCacheDataValid_WhenMismatchedCatalogPaths_ReturnsFalseWithError()
{
AddressablesContentState cacheData = new AddressablesContentState();
cacheData.editorVersion = Application.unityVersion;
cacheData.remoteCatalogLoadPath = "somePath";
var oldSetting = Settings.BuildRemoteCatalog;
Settings.BuildRemoteCatalog = true;
Assert.IsFalse(ContentUpdateScript.IsCacheDataValid(Settings, cacheData));
LogAssert.Expect(LogType.Error, new Regex("Current 'Remote Catalog Load Path' does not match load path of original player.*"));
Settings.BuildRemoteCatalog = oldSetting;
}
[Test]
public void IsCacheDataValid_WhenMismatchedEditorVersions_LogsWarning()
{
AddressablesContentState cacheData = new AddressablesContentState();
cacheData.editorVersion = "invalid";
Assert.IsFalse(ContentUpdateScript.IsCacheDataValid(Settings, cacheData));
LogAssert.Expect(LogType.Warning, new Regex(".*with version `" + cacheData.editorVersion + "`.*"));
LogAssert.Expect(LogType.Error, new Regex("Previous.*"));
}
[Test]
public void BuildContentUpdate_DoesNotDeleteBuiltData()
{
var oldSetting = Settings.BuildRemoteCatalog;
Settings.BuildRemoteCatalog = true;
var group = Settings.CreateGroup("LocalStuff3", false, false, false, null);
var schema = group.AddSchema<BundledAssetGroupSchema>();
schema.BuildPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalBuildPath);
schema.LoadPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalLoadPath);
schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
group.AddSchema<ContentUpdateGroupSchema>().StaticContent = true;
Settings.CreateOrMoveEntry(m_AssetGUID, group);
var context = new AddressablesDataBuilderInput(Settings);
var op = Settings.ActivePlayerDataBuilder.BuildData<AddressablesPlayerBuildResult>(context);
Assert.IsTrue(string.IsNullOrEmpty(op.Error), op.Error);
var tempPath = Path.GetDirectoryName(Application.dataPath) + "/" + Addressables.LibraryPath + PlatformMappingService.GetPlatformPathSubFolder() + "/addressables_content_state.bin";
ContentUpdateScript.BuildContentUpdate(Settings, tempPath);
Assert.IsTrue(Directory.Exists(Addressables.BuildPath));
Settings.BuildRemoteCatalog = oldSetting;
}
[Test]
public void ContentUpdateScenes_PackedTogether_MarksAllScenesModified()
{
AddressableAssetGroup group = Settings.CreateGroup("SceneGroup", false, false, false, null, typeof(BundledAssetGroupSchema));
group.GetSchema<BundledAssetGroupSchema>().BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
AddressableAssetEntry scene1 = new AddressableAssetEntry(m_SceneGuids[0], "scene1", group, false);
AddressableAssetEntry scene2 = new AddressableAssetEntry(m_SceneGuids[1], "scene2", group, false);
AddressableAssetEntry scene3 = new AddressableAssetEntry(m_SceneGuids[2], "scene3", group, false);
group.AddAssetEntry(scene1, false);
group.AddAssetEntry(scene2, false);
group.AddAssetEntry(scene3, false);
List<AddressableAssetEntry> modifedEnteries = new List<AddressableAssetEntry>()
{
scene1
};
ContentUpdateScript.AddAllDependentScenesFromModifiedEntries(modifedEnteries);
Assert.AreEqual(3, modifedEnteries.Count);
Assert.AreEqual(scene1, modifedEnteries[0]);
Assert.AreEqual(scene2, modifedEnteries[1]);
Assert.AreEqual(scene3, modifedEnteries[2]);
Settings.RemoveGroup(group);
}
[Test]
public void ContentUpdateScenes_PackedTogetherByLabel_MarksAllScenesModifiedWithSharedLabel()
{
AddressableAssetGroup group = Settings.CreateGroup("SceneGroup", false, false, false, null, typeof(BundledAssetGroupSchema));
group.GetSchema<BundledAssetGroupSchema>().BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogetherByLabel;
AddressableAssetEntry scene1 = new AddressableAssetEntry(m_SceneGuids[0], "scene1", group, false);
AddressableAssetEntry scene2 = new AddressableAssetEntry(m_SceneGuids[1], "scene2", group, false);
AddressableAssetEntry scene3 = new AddressableAssetEntry(m_SceneGuids[2], "scene3", group, false);
group.AddAssetEntry(scene1, false);
group.AddAssetEntry(scene2, false);
group.AddAssetEntry(scene3, false);
scene1.SetLabel("label", true, true);
scene3.SetLabel("label", true, true);
List<AddressableAssetEntry> modifedEnteries = new List<AddressableAssetEntry>()
{
scene1
};
ContentUpdateScript.AddAllDependentScenesFromModifiedEntries(modifedEnteries);
Assert.AreEqual(2, modifedEnteries.Count);
Assert.AreEqual(scene1, modifedEnteries[0]);
Assert.AreEqual(scene3, modifedEnteries[1]);
Settings.RemoveGroup(group);
}
[Test]
public void ContentUpdateScenes_PackedSeperately_MarksNoAdditionalScenes()
{
AddressableAssetGroup group = Settings.CreateGroup("SceneGroup", false, false, false, null, typeof(BundledAssetGroupSchema));
group.GetSchema<BundledAssetGroupSchema>().BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackSeparately;
AddressableAssetEntry scene1 = new AddressableAssetEntry(m_SceneGuids[0], "scene1", group, false);
AddressableAssetEntry scene2 = new AddressableAssetEntry(m_SceneGuids[1], "scene2", group, false);
AddressableAssetEntry scene3 = new AddressableAssetEntry(m_SceneGuids[2], "scene3", group, false);
group.AddAssetEntry(scene1, false);
group.AddAssetEntry(scene2, false);
group.AddAssetEntry(scene3, false);
List<AddressableAssetEntry> modifedEnteries = new List<AddressableAssetEntry>()
{
scene1
};
ContentUpdateScript.AddAllDependentScenesFromModifiedEntries(modifedEnteries);
Assert.AreEqual(1, modifedEnteries.Count);
Assert.AreEqual(scene1, modifedEnteries[0]);
Settings.RemoveGroup(group);
}
private ContentUpdateScript.ContentUpdateContext GetContentUpdateContext(string contentUpdateTestAssetGUID, string contentUpdateTestCachedAssetHash,
string contentUpdateTestNewInternalBundleName, string contentUpdateTestNewBundleName, string contentUpdateTestCachedBundlePath, string contentUpdateTestGroupGuid,
string contentUpdateTestFileName)
{
var context = new ContentUpdateScript.ContentUpdateContext()
{
WriteData = new BundleWriteData(),
BundleToInternalBundleIdMap = new Dictionary<string, string>(),
GuidToPreviousAssetStateMap = new Dictionary<string, CachedAssetState>(),
IdToCatalogDataEntryMap = new Dictionary<string, ContentCatalogDataEntry>(),
ContentState = new AddressablesContentState(),
PreviousAssetStateCarryOver = new List<CachedAssetState>(),
Registry = new FileRegistry()
};
AddToContentUpdateContext(context, contentUpdateTestAssetGUID, contentUpdateTestCachedAssetHash,
contentUpdateTestNewInternalBundleName, contentUpdateTestNewBundleName, contentUpdateTestCachedBundlePath, contentUpdateTestGroupGuid, contentUpdateTestFileName);
return context;
}
private void AddToContentUpdateContext(ContentUpdateScript.ContentUpdateContext context, string contentUpdateTestAssetGUID, string contentUpdateTestCachedAssetHash,
string contentUpdateTestNewInternalBundleName, string contentUpdateTestNewBundleName, string contentUpdateTestCachedBundlePath, string contentUpdateTestGroupGuid,
string contentUpdateTestFileName)
{
context.BundleToInternalBundleIdMap.Add(contentUpdateTestNewInternalBundleName, contentUpdateTestNewBundleName);
context.GuidToPreviousAssetStateMap.Add(contentUpdateTestAssetGUID,
new CachedAssetState()
{
bundleFileId = contentUpdateTestCachedBundlePath,
asset = new AssetState()
{
guid = new GUID(contentUpdateTestAssetGUID),
hash = Hash128.Parse(contentUpdateTestCachedAssetHash)
},
dependencies = new AssetState[] { },
data = null,
groupGuid = contentUpdateTestGroupGuid
}
);
context.IdToCatalogDataEntryMap.Add(contentUpdateTestNewBundleName,
new ContentCatalogDataEntry(typeof(IAssetBundleResource), contentUpdateTestNewBundleName, typeof(AssetBundleProvider).FullName, new[] {contentUpdateTestNewBundleName}));
context.IdToCatalogDataEntryMap.Add(contentUpdateTestAssetGUID,
new ContentCatalogDataEntry(typeof(IAssetBundleResource), contentUpdateTestAssetGUID, typeof(AssetBundleProvider).FullName, new[] {contentUpdateTestAssetGUID}));
context.WriteData.AssetToFiles.Add(new GUID(contentUpdateTestAssetGUID), new List<string>() {contentUpdateTestFileName});
context.WriteData.FileToBundle.Add(contentUpdateTestFileName, contentUpdateTestNewInternalBundleName);
}
private AddressableAssetEntry CreateAssetEntry(string guid, AddressableAssetGroup group)
{
return new AddressableAssetEntry(guid, guid, group, false);
}
readonly string m_ContentUpdateTestAssetGUID = GUID.Generate().ToString();
const string k_ContentUpdateTestCachedAssetHash = "8888888888888888888";
const string k_ContentUpdateTestNewInternalBundleName = "bundle";
const string k_ContentUpdateTestNewBundleName = "fullbundlepath";
const string k_ContentUpdateTestCachedBundlePath = "cachedBundle";
const string k_ContentUpdateTestFileName = "testfile";
[Test]
public void DetermineRequiredAssetEntryUpdates_AssetWithoutDependenciesAndChangedHashInStaticGroup_ReturnsOnlyRevertToCachedState()
{
File.WriteAllText(k_ContentUpdateTestCachedBundlePath, "TestCachedAssetBundle");
File.WriteAllText(k_ContentUpdateTestNewBundleName, "TestNewBundle");
var group = Settings.CreateGroup("ContentUpdateTests", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
string contentUpdateTestGroupGuid = group.Guid;
group.GetSchema<ContentUpdateGroupSchema>().StaticContent = true;
var assetEntry = CreateAssetEntry(m_ContentUpdateTestAssetGUID, group);
assetEntry.m_cachedAssetPath = "path";
group.AddAssetEntry(assetEntry);
var context = GetContentUpdateContext(m_ContentUpdateTestAssetGUID, k_ContentUpdateTestCachedAssetHash,
k_ContentUpdateTestNewInternalBundleName, k_ContentUpdateTestNewBundleName,
k_ContentUpdateTestCachedBundlePath, contentUpdateTestGroupGuid, k_ContentUpdateTestFileName);
var ops = RevertUnchangedAssetsToPreviousAssetState.DetermineRequiredAssetEntryUpdates(group, context);
Assert.AreEqual(assetEntry, ops[0].AssetEntry);
Assert.AreEqual(k_ContentUpdateTestNewBundleName, ops[0].CurrentBuildPath);
Assert.AreEqual(k_ContentUpdateTestCachedBundlePath, ops[0].PreviousBuildPath);
File.Delete(k_ContentUpdateTestCachedBundlePath);
File.Delete(k_ContentUpdateTestNewBundleName);
Settings.RemoveGroup(group);
}
[Test]
public void DetermineRequiredAssetEntryUpdates_AssetWithDependenciesAndChangedHashInStaticGroup_ReturnsRevertToCachedStateAndDependencies()
{
File.WriteAllText(k_ContentUpdateTestCachedBundlePath, "TestCachedAssetBundle");
File.WriteAllText(k_ContentUpdateTestNewBundleName, "TestNewBundle");
var group = Settings.CreateGroup("ContentUpdateTests", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
string contentUpdateTestGroupGuid = group.Guid;
group.GetSchema<ContentUpdateGroupSchema>().StaticContent = true;
var assetEntry = CreateAssetEntry(m_ContentUpdateTestAssetGUID, group);
assetEntry.m_cachedAssetPath = "path";
group.AddAssetEntry(assetEntry);
var context = GetContentUpdateContext(m_ContentUpdateTestAssetGUID, k_ContentUpdateTestCachedAssetHash,
k_ContentUpdateTestNewInternalBundleName, k_ContentUpdateTestNewBundleName,
k_ContentUpdateTestCachedBundlePath, contentUpdateTestGroupGuid, k_ContentUpdateTestFileName);
context.GuidToPreviousAssetStateMap[m_ContentUpdateTestAssetGUID].dependencies = new AssetState[]
{
new AssetState()
{
guid = GUID.Generate(),
hash = Hash128.Parse("00000000000000")
}
};
var ops = RevertUnchangedAssetsToPreviousAssetState.DetermineRequiredAssetEntryUpdates(group, context);
Assert.AreEqual(assetEntry, ops[0].AssetEntry);
Assert.AreEqual(k_ContentUpdateTestNewBundleName, ops[0].CurrentBuildPath);
Assert.AreEqual(k_ContentUpdateTestCachedBundlePath, ops[0].PreviousBuildPath);
File.Delete(k_ContentUpdateTestCachedBundlePath);
File.Delete(k_ContentUpdateTestNewBundleName);
Settings.RemoveGroup(group);
}
[Test]
public void DetermineRequiredAssetEntryUpdates_AssetWithChangedGroup_TakesNoAction()
{
File.WriteAllText(k_ContentUpdateTestCachedBundlePath, "TestCachedAssetBundle");
var group = Settings.CreateGroup("ContentUpdateTests", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
string contentUpdateTestGroupGuid = GUID.Generate().ToString();
group.GetSchema<ContentUpdateGroupSchema>().StaticContent = true;
var assetEntry = CreateAssetEntry(m_ContentUpdateTestAssetGUID, group);
group.AddAssetEntry(assetEntry);
var context = GetContentUpdateContext(m_ContentUpdateTestAssetGUID, k_ContentUpdateTestCachedAssetHash,
k_ContentUpdateTestNewInternalBundleName, k_ContentUpdateTestNewBundleName,
k_ContentUpdateTestCachedBundlePath, contentUpdateTestGroupGuid, k_ContentUpdateTestFileName);
var ops = RevertUnchangedAssetsToPreviousAssetState.DetermineRequiredAssetEntryUpdates(group, context);
Assert.IsTrue(ops.Count == 0);
File.Delete(k_ContentUpdateTestCachedBundlePath);
Settings.RemoveGroup(group);
}
[Test]
public void DetermineRequiredAssetEntryUpdates_AssetWithChangedHashInNonStaticGroup_TakesNoAction()
{
File.WriteAllText(k_ContentUpdateTestCachedBundlePath, "TestCachedAssetBundle");
var group = Settings.CreateGroup("ContentUpdateTests", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
string contentUpdateTestGroupGuid = GUID.Generate().ToString();
group.GetSchema<ContentUpdateGroupSchema>().StaticContent = false;
var assetEntry = CreateAssetEntry(m_ContentUpdateTestAssetGUID, group);
group.AddAssetEntry(assetEntry);
var context = GetContentUpdateContext(m_ContentUpdateTestAssetGUID, k_ContentUpdateTestCachedAssetHash,
k_ContentUpdateTestNewInternalBundleName, k_ContentUpdateTestNewBundleName,
k_ContentUpdateTestCachedBundlePath, contentUpdateTestGroupGuid, k_ContentUpdateTestFileName);
var ops = RevertUnchangedAssetsToPreviousAssetState.DetermineRequiredAssetEntryUpdates(group, context);
Assert.IsTrue(ops.Count == 0);
File.Delete(k_ContentUpdateTestCachedBundlePath);
Settings.RemoveGroup(group);
}
[Test]
public void DetermineRequiredAssetEntryUpdates_EntriesThatTakeNoAction_StillSetBundleFileId()
{
File.WriteAllText(k_ContentUpdateTestCachedBundlePath, "TestCachedAssetBundle");
var group = Settings.CreateGroup("ContentUpdateTests", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
string contentUpdateTestGroupGuid = GUID.Generate().ToString();
group.GetSchema<ContentUpdateGroupSchema>().StaticContent = false;
var assetEntry = CreateAssetEntry(m_ContentUpdateTestAssetGUID, group);
assetEntry.m_cachedAssetPath = "path";
group.AddAssetEntry(assetEntry);
var context = GetContentUpdateContext(m_ContentUpdateTestAssetGUID, k_ContentUpdateTestCachedAssetHash,
k_ContentUpdateTestNewInternalBundleName, k_ContentUpdateTestNewBundleName,
k_ContentUpdateTestCachedBundlePath, contentUpdateTestGroupGuid, k_ContentUpdateTestFileName);
var ops = RevertUnchangedAssetsToPreviousAssetState.DetermineRequiredAssetEntryUpdates(group, context);
Assert.IsTrue(ops.Count == 0);
Assert.AreEqual(k_ContentUpdateTestNewBundleName, assetEntry.BundleFileId);
File.Delete(k_ContentUpdateTestCachedBundlePath);
Settings.RemoveGroup(group);
}
[Test]
public void DetermineRequiredAssetEntryUpdates_WithMissingBundleFileId_LogsErrorAndTakesNoAction()
{
File.WriteAllText(k_ContentUpdateTestCachedBundlePath, "TestCachedAssetBundle");
var group = Settings.CreateGroup("ContentUpdateTests", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
string contentUpdateTestGroupGuid = group.Guid;
group.GetSchema<ContentUpdateGroupSchema>().StaticContent = true;
var assetEntry = CreateAssetEntry(m_ContentUpdateTestAssetGUID, group);
assetEntry.m_cachedAssetPath = "path";
group.AddAssetEntry(assetEntry);
var context = GetContentUpdateContext(m_ContentUpdateTestAssetGUID, k_ContentUpdateTestCachedAssetHash,
k_ContentUpdateTestNewInternalBundleName, k_ContentUpdateTestNewBundleName,
"", contentUpdateTestGroupGuid, k_ContentUpdateTestFileName);
var ops = RevertUnchangedAssetsToPreviousAssetState.DetermineRequiredAssetEntryUpdates(group, context);
LogAssert.Expect(LogType.Error, $"CachedAssetState found for {assetEntry.AssetPath} but the bundleFileId was never set on the previous build.");
Assert.IsTrue(ops.Count == 0);
File.Delete(k_ContentUpdateTestCachedBundlePath);
Settings.RemoveGroup(group);
}
[Test]
public void DetermineRequiredAssetEntryUpdates_WithMissingPreviousBundle_LogsWarningAndReturnsRevertOperation()
{
var group = Settings.CreateGroup("ContentUpdateTests", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
string contentUpdateTestGroupGuid = group.Guid;
group.GetSchema<ContentUpdateGroupSchema>().StaticContent = true;
var assetEntry = CreateAssetEntry(m_ContentUpdateTestAssetGUID, group);
assetEntry.m_cachedAssetPath = "path";
group.AddAssetEntry(assetEntry);
var context = GetContentUpdateContext(m_ContentUpdateTestAssetGUID, k_ContentUpdateTestCachedAssetHash,
k_ContentUpdateTestNewInternalBundleName, k_ContentUpdateTestNewBundleName,
k_ContentUpdateTestCachedBundlePath, contentUpdateTestGroupGuid, k_ContentUpdateTestFileName);
var ops = RevertUnchangedAssetsToPreviousAssetState.DetermineRequiredAssetEntryUpdates(group, context);
LogAssert.Expect(LogType.Warning, $"CachedAssetState found for {assetEntry.AssetPath} but the previous bundle at {k_ContentUpdateTestCachedBundlePath} cannot be found. " +
$"This will not affect loading the bundle in previously built players, but loading the missing bundle in Play Mode using the play mode script " +
$"\"Use Existing Build (requires built groups)\" will fail. This most often occurs because you are running a content update on a build where you " +
$"made changes to a group marked with \"Prevent Updates\"");
Assert.IsTrue(ops.Count == 1);
Settings.RemoveGroup(group);
}
[Test]
public void DetermineRequiredAssetEntryUpdates_WithIdenticalBundleId_LogsWarningAndReturnsRevertOperation()
{
var group = Settings.CreateGroup("ContentUpdateTests", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
string contentUpdateTestGroupGuid = group.Guid;
group.GetSchema<ContentUpdateGroupSchema>().StaticContent = true;
var assetEntry = CreateAssetEntry(m_ContentUpdateTestAssetGUID, group);
assetEntry.m_cachedAssetPath = "path";
group.AddAssetEntry(assetEntry);
var context = GetContentUpdateContext(m_ContentUpdateTestAssetGUID, k_ContentUpdateTestCachedAssetHash,
k_ContentUpdateTestNewInternalBundleName, k_ContentUpdateTestNewBundleName,
k_ContentUpdateTestNewBundleName, contentUpdateTestGroupGuid, k_ContentUpdateTestFileName);
var ops = RevertUnchangedAssetsToPreviousAssetState.DetermineRequiredAssetEntryUpdates(group, context);
LogAssert.Expect(LogType.Warning, $"CachedAssetState found for {assetEntry.AssetPath} but the previous bundle at {k_ContentUpdateTestNewBundleName} cannot be found. " +
$"This will not affect loading the bundle in previously built players, but loading the missing bundle in Play Mode using the play mode script " +
$"\"Use Existing Build (requires built groups)\" will fail. This most often occurs because you are running a content update on a build where you " +
$"made changes to a group marked with \"Prevent Updates\"");
Assert.IsTrue(ops.Count == 1);
Settings.RemoveGroup(group);
}
[Test]
public void DetermineRequiredAssetEntryUpdates_AssetWithMatchingCachedInternalBundleId_TakesNoAction()
{
File.WriteAllText(k_ContentUpdateTestCachedBundlePath, "TestCachedAssetBundle");
var group = Settings.CreateGroup("ContentUpdateTests", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
string contentUpdateTestGroupGuid = group.Guid;
group.GetSchema<ContentUpdateGroupSchema>().StaticContent = true;
var assetEntry = CreateAssetEntry(m_ContentUpdateTestAssetGUID, group);
group.AddAssetEntry(assetEntry);
var context = GetContentUpdateContext(m_ContentUpdateTestAssetGUID, k_ContentUpdateTestCachedAssetHash,
k_ContentUpdateTestNewInternalBundleName, k_ContentUpdateTestNewBundleName,
k_ContentUpdateTestNewBundleName, contentUpdateTestGroupGuid, k_ContentUpdateTestFileName);
var ops = RevertUnchangedAssetsToPreviousAssetState.DetermineRequiredAssetEntryUpdates(group, context);
Assert.IsTrue(ops.Count == 0);
File.Delete(k_ContentUpdateTestCachedBundlePath);
Settings.RemoveGroup(group);
}
[Test]
public void ApplyAssetEntryUpdates_InvalidKeyForGuidToPreviousAssetStateMap_DoesNotThrow()
{
File.WriteAllText(k_ContentUpdateTestCachedBundlePath, "TestCachedAssetBundle");
var group = Settings.CreateGroup("ContentUpdateTests", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
string contentUpdateTestGroupGuid = GUID.Generate().ToString();
group.GetSchema<ContentUpdateGroupSchema>().StaticContent = false;
var assetEntry = CreateAssetEntry(m_ContentUpdateTestAssetGUID, group);
group.AddAssetEntry(assetEntry);
var context = GetContentUpdateContext(m_ContentUpdateTestAssetGUID, k_ContentUpdateTestCachedAssetHash,
k_ContentUpdateTestNewInternalBundleName, k_ContentUpdateTestNewBundleName,
k_ContentUpdateTestCachedBundlePath, contentUpdateTestGroupGuid, k_ContentUpdateTestFileName);
context.GuidToPreviousAssetStateMap[m_ContentUpdateTestAssetGUID].dependencies = new AssetState[]
{
new AssetState()
{
guid = GUID.Generate(),
hash = Hash128.Parse("9823749283742")
}
};
var ops = new List<RevertUnchangedAssetsToPreviousAssetState.AssetEntryRevertOperation>()
{
new RevertUnchangedAssetsToPreviousAssetState.AssetEntryRevertOperation()
{
PreviousBuildPath = k_ContentUpdateTestCachedBundlePath,
AssetEntry = assetEntry,
BundleCatalogEntry = context.IdToCatalogDataEntryMap[m_ContentUpdateTestAssetGUID],
CurrentBuildPath = k_ContentUpdateTestNewBundleName,
PreviousAssetState = context.GuidToPreviousAssetStateMap[m_ContentUpdateTestAssetGUID]
}
};
context.ContentState.cachedBundles = new CachedBundleState[] {new CachedBundleState() {bundleFileId = "cachedBundle", data = "string"}};
Assert.DoesNotThrow(() => RevertUnchangedAssetsToPreviousAssetState.ApplyAssetEntryUpdates(ops, context));
File.Delete(k_ContentUpdateTestCachedBundlePath);
Settings.RemoveGroup(group);
}
[Test]
public void ApplyAssetEntryUpdates_DeletesCorrectBundle()
{
File.WriteAllText(k_ContentUpdateTestCachedBundlePath, "TestCachedAssetBundle");
File.WriteAllText(k_ContentUpdateTestNewBundleName, "TestAssetBundle");
var group = Settings.CreateGroup("ContentUpdateTests", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
string contentUpdateTestGroupGuid = GUID.Generate().ToString();
group.GetSchema<ContentUpdateGroupSchema>().StaticContent = false;
var assetEntry = CreateAssetEntry(m_ContentUpdateTestAssetGUID, group);
group.AddAssetEntry(assetEntry);
var context = GetContentUpdateContext(m_ContentUpdateTestAssetGUID, k_ContentUpdateTestCachedAssetHash,
k_ContentUpdateTestNewInternalBundleName, k_ContentUpdateTestNewBundleName,
k_ContentUpdateTestCachedBundlePath, contentUpdateTestGroupGuid, k_ContentUpdateTestFileName);
var ops = new List<RevertUnchangedAssetsToPreviousAssetState.AssetEntryRevertOperation>()
{
new RevertUnchangedAssetsToPreviousAssetState.AssetEntryRevertOperation()
{
PreviousBuildPath = k_ContentUpdateTestCachedBundlePath,
AssetEntry = assetEntry,
BundleCatalogEntry = context.IdToCatalogDataEntryMap[m_ContentUpdateTestAssetGUID],
CurrentBuildPath = k_ContentUpdateTestNewBundleName,
PreviousAssetState = context.GuidToPreviousAssetStateMap[m_ContentUpdateTestAssetGUID]
},
new RevertUnchangedAssetsToPreviousAssetState.AssetEntryRevertOperation()
{
PreviousBuildPath = k_ContentUpdateTestCachedBundlePath,
AssetEntry = assetEntry,
BundleCatalogEntry = context.IdToCatalogDataEntryMap[m_ContentUpdateTestAssetGUID],
CurrentBuildPath = k_ContentUpdateTestNewBundleName,
PreviousAssetState = context.GuidToPreviousAssetStateMap[m_ContentUpdateTestAssetGUID]
}
};
context.ContentState.cachedBundles = new CachedBundleState[] {new CachedBundleState() {bundleFileId = "cachedBundle", data = "string"}};
RevertUnchangedAssetsToPreviousAssetState.ApplyAssetEntryUpdates(ops, context);
Assert.IsTrue(File.Exists(k_ContentUpdateTestCachedBundlePath));
Assert.IsFalse(File.Exists(k_ContentUpdateTestNewBundleName));
File.Delete(k_ContentUpdateTestCachedBundlePath);
Settings.RemoveGroup(group);
}
[Test]
public void ApplyAssetEntryUpdates_RegistryOnlyContainsCachedBundleEntry()
{
var group = Settings.CreateGroup("ContentUpdateTests", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
string contentUpdateTestGroupGuid = GUID.Generate().ToString();
group.GetSchema<ContentUpdateGroupSchema>().StaticContent = false;
var assetEntry = CreateAssetEntry(m_ContentUpdateTestAssetGUID, group);
group.AddAssetEntry(assetEntry);
var context = GetContentUpdateContext(m_ContentUpdateTestAssetGUID, k_ContentUpdateTestCachedAssetHash,
k_ContentUpdateTestNewInternalBundleName, k_ContentUpdateTestNewBundleName,
k_ContentUpdateTestCachedBundlePath, contentUpdateTestGroupGuid, k_ContentUpdateTestFileName);
var ops = new List<RevertUnchangedAssetsToPreviousAssetState.AssetEntryRevertOperation>()
{
new RevertUnchangedAssetsToPreviousAssetState.AssetEntryRevertOperation()
{
PreviousBuildPath = k_ContentUpdateTestCachedBundlePath,
AssetEntry = assetEntry,
BundleCatalogEntry = context.IdToCatalogDataEntryMap[m_ContentUpdateTestAssetGUID],
CurrentBuildPath = k_ContentUpdateTestNewBundleName,
PreviousAssetState = context.GuidToPreviousAssetStateMap[m_ContentUpdateTestAssetGUID]
},
new RevertUnchangedAssetsToPreviousAssetState.AssetEntryRevertOperation()
{
PreviousBuildPath = k_ContentUpdateTestCachedBundlePath,
AssetEntry = assetEntry,
BundleCatalogEntry = context.IdToCatalogDataEntryMap[m_ContentUpdateTestAssetGUID],
CurrentBuildPath = k_ContentUpdateTestNewBundleName,
PreviousAssetState = context.GuidToPreviousAssetStateMap[m_ContentUpdateTestAssetGUID]
}
};
context.ContentState.cachedBundles = new CachedBundleState[] {new CachedBundleState() {bundleFileId = "cachedBundle", data = "string"}};
RevertUnchangedAssetsToPreviousAssetState.ApplyAssetEntryUpdates(ops, context);
var registryPaths = context.Registry.GetFilePaths();
Assert.AreEqual(1, registryPaths.Count());
Assert.AreEqual(k_ContentUpdateTestCachedBundlePath, registryPaths.ElementAt(0));
Settings.RemoveGroup(group);
}
[Test]
public void ApplyAssetEntryUpdates_WhenAssetAndDependencyAreModifiedAndInSeparateGroups_SetCatalogEntryToCachedBundles()
{
GUID depAssetGuid = GUID.Generate();
string oldDepGroupCachedAssetHash = "1888888888888888888";
string newDepGroupCachedAssetHash = "1188888888888888888";
string depGroupNewInternalBundleName = "bundle2";
string depGroupNewBundleName = "fullbundlepath2";
string depGroupCachedBundlePath = "cachedBundle2";
string depGroupFileName = "testfile2";
AddressableAssetGroup group = Settings.CreateGroup("ContentUpdateTests", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
string contentUpdateTestGroupGuid = GUID.Generate().ToString();
AddressableAssetGroup depGroup = Settings.CreateGroup("ContentUpdateTests2", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
GUID depGroupGuid = GUID.Generate();
group.GetSchema<ContentUpdateGroupSchema>().StaticContent = false;
AddressableAssetEntry assetEntry = CreateAssetEntry(m_ContentUpdateTestAssetGUID, group);
group.AddAssetEntry(assetEntry);
depGroup.GetSchema<ContentUpdateGroupSchema>().StaticContent = false;
AddressableAssetEntry depAssetEntry = CreateAssetEntry(depAssetGuid.ToString(), depGroup);
depGroup.AddAssetEntry(assetEntry);
ContentUpdateScript.ContentUpdateContext context = GetContentUpdateContext(m_ContentUpdateTestAssetGUID, k_ContentUpdateTestCachedAssetHash,
k_ContentUpdateTestNewInternalBundleName, k_ContentUpdateTestNewBundleName,
k_ContentUpdateTestCachedBundlePath, contentUpdateTestGroupGuid, k_ContentUpdateTestFileName);
AddToContentUpdateContext(context, depAssetGuid.ToString(), oldDepGroupCachedAssetHash,
depGroupNewInternalBundleName, depGroupNewBundleName,
depGroupCachedBundlePath, depGroupGuid.ToString(), depGroupFileName);
var previousDep = new AssetState()
{
guid = depAssetGuid,
hash = Hash128.Parse(oldDepGroupCachedAssetHash)
};
var currentDep = new AssetState()
{
guid = GUID.Generate(),
hash = Hash128.Parse(newDepGroupCachedAssetHash)
};
context.GuidToPreviousAssetStateMap[m_ContentUpdateTestAssetGUID].dependencies = new AssetState[]
{
previousDep
};
context.IdToCatalogDataEntryMap[m_ContentUpdateTestAssetGUID].Dependencies.Add(currentDep);
var ops = new List<RevertUnchangedAssetsToPreviousAssetState.AssetEntryRevertOperation>()
{
new RevertUnchangedAssetsToPreviousAssetState.AssetEntryRevertOperation()
{
PreviousBuildPath = k_ContentUpdateTestCachedBundlePath,
AssetEntry = assetEntry,
BundleCatalogEntry = context.IdToCatalogDataEntryMap[m_ContentUpdateTestAssetGUID],
CurrentBuildPath = k_ContentUpdateTestNewBundleName,
PreviousAssetState = context.GuidToPreviousAssetStateMap[m_ContentUpdateTestAssetGUID]
},
new RevertUnchangedAssetsToPreviousAssetState.AssetEntryRevertOperation()
{
PreviousBuildPath = depGroupCachedBundlePath,
AssetEntry = depAssetEntry,
BundleCatalogEntry = context.IdToCatalogDataEntryMap[depAssetGuid.ToString()],
CurrentBuildPath = depGroupNewBundleName,
PreviousAssetState = context.GuidToPreviousAssetStateMap[depAssetGuid.ToString()]
}
};
var locations = new List<ContentCatalogDataEntry>();
context.ContentState.cachedBundles = new CachedBundleState[]
{
new CachedBundleState() {bundleFileId = "cachedBundle", data = "string"},
new CachedBundleState() {bundleFileId = "cachedBundle2", data = "string"}
};
RevertUnchangedAssetsToPreviousAssetState.ApplyAssetEntryUpdates(ops, context);
Assert.AreEqual(k_ContentUpdateTestCachedBundlePath, context.IdToCatalogDataEntryMap[m_ContentUpdateTestAssetGUID].InternalId);
Assert.AreEqual(depGroupCachedBundlePath, context.IdToCatalogDataEntryMap[depAssetGuid.ToString()].InternalId);
Settings.RemoveGroup(group);
Settings.RemoveGroup(depGroup);
}
[Test]
public void RevertBundleDataCorrectlyReplacesToCacheLoadingData()
{
string bundleName = "cachedBundleName_containKey";
string assetBundleProvider = "UnityEngine.ResourceManagement.ResourceProviders.AssetBundleProvider";
ContentUpdateScript.ContentUpdateContext updateContext = new ContentUpdateScript.ContentUpdateContext();
updateContext.ContentState = new AddressablesContentState();
AssetBundleRequestOptions cachedRequestOptions = new AssetBundleRequestOptions() {Crc = 123, Hash = "abc", BundleName = bundleName, BundleSize = 10};
updateContext.ContentState.cachedBundles = new CachedBundleState[]
{
new CachedBundleState() {bundleFileId = "cachedInternalId", data = cachedRequestOptions}
};
AddressableAssetsBuildContext aaContext = new AddressableAssetsBuildContext();
aaContext.locations = new List<ContentCatalogDataEntry>(2);
List<object> keys = new List<object>();
keys.Add("stringLoadKey");
AssetBundleRequestOptions newLocationData1 = new AssetBundleRequestOptions() {Crc = 456, Hash = "def", BundleName = bundleName, BundleSize = 20};
aaContext.locations.Add(new ContentCatalogDataEntry(typeof(AssetBundleResource), "newInternalID", assetBundleProvider, keys, null, newLocationData1));
AssetBundleRequestOptions newLocationData2 = new AssetBundleRequestOptions() {Crc = 456, Hash = "def", BundleName = "nonCachedBundleName", BundleSize = 20};
aaContext.locations.Add(new ContentCatalogDataEntry(typeof(AssetBundleResource), "newInternalID", assetBundleProvider, keys, null, newLocationData2));
bool reverted = RevertUnchangedAssetsToPreviousAssetState.RevertBundleByNameContains("_containKey", updateContext, aaContext);
Assert.IsTrue(reverted, "Failed to revert the bundle containing _containsKey");
// first entry is reverted
AssetBundleRequestOptions catalogRequestOptions = aaContext.locations[0].Data as AssetBundleRequestOptions;
Assert.AreEqual(cachedRequestOptions.Crc, catalogRequestOptions.Crc, "Reverted Catalog CRC expected to be the same as the cached value");
Assert.AreEqual(cachedRequestOptions.Hash, catalogRequestOptions.Hash, "Reverted Catalog Hash expected to be the same as the cached value");
Assert.AreEqual(cachedRequestOptions.BundleName, catalogRequestOptions.BundleName, "Reverted Catalog BundleName expected to be the same as the cached value");
Assert.AreEqual(cachedRequestOptions.BundleSize, catalogRequestOptions.BundleSize, "Reverted Catalog BundleSize expected to be the same as the cached value");
// second entry is not reverted
catalogRequestOptions = aaContext.locations[1].Data as AssetBundleRequestOptions;
Assert.AreNotEqual(cachedRequestOptions.Crc, catalogRequestOptions.Crc, "Noncached Catalog CRC expected to be different as the cached value");
Assert.AreNotEqual(cachedRequestOptions.Hash, catalogRequestOptions.Hash, "Noncached Catalog Hash expected to be different as the cached value");
Assert.AreNotEqual(cachedRequestOptions.BundleName, catalogRequestOptions.BundleName, "Noncached Catalog BundleName expected to be different as the cached value");
Assert.AreNotEqual(cachedRequestOptions.BundleSize, catalogRequestOptions.BundleSize, "Noncached Catalog BundleSize expected to be different as the cached value");
}
// not found in cache
// not found in catalog
// bundeOptions missing
[Test]
public void RevertBundleFails_WhenBundleMissingFromCacheButInCatalog()
{
string assetBundleProvider = "UnityEngine.ResourceManagement.ResourceProviders.AssetBundleProvider";
ContentUpdateScript.ContentUpdateContext updateContext = new ContentUpdateScript.ContentUpdateContext();
updateContext.ContentState = new AddressablesContentState();
AssetBundleRequestOptions cachedRequestOptions = new AssetBundleRequestOptions() {Crc = 123, Hash = "abc", BundleName = "cachedBundleName", BundleSize = 10};
updateContext.ContentState.cachedBundles = new CachedBundleState[]
{
new CachedBundleState() {bundleFileId = "cachedInternalId", data = cachedRequestOptions}
};
AddressableAssetsBuildContext aaContext = new AddressableAssetsBuildContext();
aaContext.locations = new List<ContentCatalogDataEntry>(1);
List<object> keys = new List<object>();
keys.Add("stringLoadKey");
AssetBundleRequestOptions locData = new AssetBundleRequestOptions() {Crc = 456, Hash = "def", BundleName = "catalogBundleName", BundleSize = 20};
string internalId = "catalogInternalId";
aaContext.locations.Add(new ContentCatalogDataEntry(typeof(AssetBundleResource), internalId, assetBundleProvider, keys, null, locData));
LogAssert.Expect(LogType.Error, $"Matching cached update state for {internalId} failed. Content not found in original build.");
bool reverted = RevertUnchangedAssetsToPreviousAssetState.RevertBundleByNameContains("catalogBundleName", updateContext, aaContext);
Assert.IsFalse(reverted, "Expected to Fail finding \"_containsKey\" where cached content does not have an entry with that bundle Name");
}
[Test]
public void RevertBundleSucceeds_WhenBundleMissingFromCatalogButInCache()
{
string assetBundleProvider = "UnityEngine.ResourceManagement.ResourceProviders.AssetBundleProvider";
ContentUpdateScript.ContentUpdateContext updateContext = new ContentUpdateScript.ContentUpdateContext();
updateContext.ContentState = new AddressablesContentState();
AssetBundleRequestOptions cachedRequestOptions = new AssetBundleRequestOptions() {Crc = 123, Hash = "abc", BundleName = "cachedBundleName", BundleSize = 10};
updateContext.ContentState.cachedBundles = new CachedBundleState[]
{
new CachedBundleState() {bundleFileId = "cachedInternalId", data = cachedRequestOptions}
};
AddressableAssetsBuildContext aaContext = new AddressableAssetsBuildContext();
aaContext.locations = new List<ContentCatalogDataEntry>(1);
List<object> keys = new List<object>();
keys.Add("stringLoadKey");
AssetBundleRequestOptions locData = new AssetBundleRequestOptions() {Crc = 456, Hash = "def", BundleName = "catalogBundleName", BundleSize = 20};
aaContext.locations.Add(new ContentCatalogDataEntry(typeof(AssetBundleResource), "newInternalID", assetBundleProvider, keys, null, locData));
bool reverted = RevertUnchangedAssetsToPreviousAssetState.RevertBundleByNameContains("cachedBundleName", updateContext, aaContext);
Assert.IsTrue(reverted, "Expected to succeed where cache exists but not included in current build to be reverted");
}
[Test]
public void RevertBundleSucceeds_WhenBundleMissingFromCacheAndCatalog()
{
string assetBundleProvider = "UnityEngine.ResourceManagement.ResourceProviders.AssetBundleProvider";
ContentUpdateScript.ContentUpdateContext updateContext = new ContentUpdateScript.ContentUpdateContext();
updateContext.ContentState = new AddressablesContentState();
updateContext.ContentState.cachedBundles = new CachedBundleState[]
{
new CachedBundleState() {bundleFileId = "cachedInternalId", data = null}
};
AddressableAssetsBuildContext aaContext = new AddressableAssetsBuildContext();
aaContext.locations = new List<ContentCatalogDataEntry>(1);
List<object> keys = new List<object>();
keys.Add("stringLoadKey");
aaContext.locations.Add(new ContentCatalogDataEntry(typeof(AssetBundleResource), "newInternalID", assetBundleProvider, keys, null, null));
bool reverted = RevertUnchangedAssetsToPreviousAssetState.RevertBundleByNameContains("catalogBundleName", updateContext, aaContext);
Assert.IsTrue(reverted, "Expected to succeed where bundle to revert was not in either cache or current builds");
}
[Test]
[TestCase("{Addressables.RuntimePath}/TargetPlatform/prefabA.bundle", "{Addressables.RuntimePath}/TargetPlatform", "Library/aa/TargetPlatform")]
[TestCase("{Addressables.RuntimePath}\\TargetPlatform\\prefabA.bundle", "{Addressables.RuntimePath}/TargetPlatform", "Library/aa/TargetPlatform")]
[TestCase("http://localhost/TargetPlatform/prefabA.bundle", "http://localhost/TargetPlatform", "ServerData/TargetPlatform")]
public void BundleIdToBuildPath_ReturnsBundleBuildPath(string bundleId, string rootLoadPath, string rootBuildPath)
{
string buildPath = RevertUnchangedAssetsToPreviousAssetState.BundleIdToBuildPath(bundleId, rootLoadPath, rootBuildPath);
Assert.IsTrue(buildPath.StartsWith(rootBuildPath));
}
[Test]
public void GatherModifiedEntries_IncludesDependants()
{
// Create assets
GameObject mainObject = new GameObject("mainObject");
Material mat = new Material(Shader.Find("Transparent/Diffuse"));
mainObject.AddComponent<MeshRenderer>().material = mat;
string mainAssetPath = GetAssetPath("mainObject.prefab");
string refAssetPath = GetAssetPath("refObject.prefab");
string materialAssetPath = GetAssetPath("testMaterial.mat");
AssetDatabase.CreateAsset(mat, materialAssetPath);
var prefab = PrefabUtility.SaveAsPrefabAsset(mainObject, mainAssetPath);
GameObject refObject = new GameObject("refObject");
refObject.AddComponent<ObjectReferenceMonoBehaviour>().m_ObjectReference = prefab;
PrefabUtility.SaveAsPrefabAsset(refObject, refAssetPath);
AssetDatabase.SaveAssets();
AddressableAssetGroup mainAssetGroup = null;
try
{
// Create addressables
mainAssetGroup = Settings.CreateGroup("TestGroup", false, false, false, null);
var schema = mainAssetGroup.AddSchema<BundledAssetGroupSchema>();
schema.BuildPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalBuildPath);
schema.LoadPath.SetVariableByName(Settings, AddressableAssetSettings.kLocalLoadPath);
schema.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
mainAssetGroup.AddSchema<ContentUpdateGroupSchema>().StaticContent = true;
AddressableAssetEntry mainEntry =
Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(mainAssetPath), mainAssetGroup);
AddressableAssetEntry refEntry =
Settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(refAssetPath), mainAssetGroup);
// Build
var context = new AddressablesDataBuilderInput(Settings);
Settings.ActivePlayerDataBuilder.BuildData<AddressablesPlayerBuildResult>(context);
// Modify assets
var ma = AssetDatabase.LoadAssetAtPath<Material>(materialAssetPath);
ma.color = new Color(Random.value, Random.value, Random.value);
EditorUtility.SetDirty(ma);
AssetDatabase.SaveAssets();
// Test
var tempPath = Path.GetDirectoryName(Application.dataPath) + "/Library/com.unity.addressables/" +
PlatformMappingService.GetPlatformPathSubFolder() + "/addressables_content_state.bin";
var modifiedEntries = ContentUpdateScript.GatherModifiedEntries(Settings, tempPath);
Assert.AreEqual(2, modifiedEntries.Count);
Assert.IsTrue(modifiedEntries.Contains(mainEntry), "Modified Entries does not include the main prefab");
Assert.IsTrue(modifiedEntries.Contains(refEntry), "Modified Entries does not include the prefab that is dependant on Prefab that has changed material");
}
finally
{
// Cleanup
GameObject.DestroyImmediate(mainObject);
GameObject.DestroyImmediate(refObject);
Settings.RemoveGroup(mainAssetGroup);
AssetDatabase.DeleteAsset(mainAssetPath);
AssetDatabase.DeleteAsset(refAssetPath);
AssetDatabase.DeleteAsset(materialAssetPath);
}
}
}
}