506 lines
25 KiB
C#
506 lines
25 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Reflection;
|
||
using NUnit.Framework;
|
||
using UnityEditor;
|
||
using UnityEditor.Build.Content;
|
||
using UnityEditor.Build.Pipeline.Utilities;
|
||
using UnityEditor.Experimental;
|
||
using UnityEngine;
|
||
|
||
namespace UnityEditor.Build.Pipeline.Tests
|
||
{
|
||
/// <summary>
|
||
/// Mirrors the IN-104030 repro idea: one texture worth of "letter" subsprites (here A–F) and one
|
||
/// texture worth of "digit" subsprites (0–9), modeled as <see cref="ObjectIdentifier"/>s that share
|
||
/// guid+path per atlas. Contiguous bundles require every object from the same source asset to share
|
||
/// the same asset-derived prefix of the serialization index (length depends on Prefab Packed Header Size; UUM-131143).
|
||
/// </summary>
|
||
/// <remarks>
|
||
/// This file includes both <c>UnityEditor</c> and <c>UnityEngine</c> so the <c>GUID</c> type resolves across Unity
|
||
/// versions (it may live in either assembly). Do not drop one of those usings as redundant cleanup.
|
||
/// </remarks>
|
||
[TestFixture]
|
||
public class PrefabPackedIdentifiersSerializationIndexTests
|
||
{
|
||
// Same layout spirit as IN-104030: two atlases, different guids.
|
||
static readonly GUID kLetterAtlasGuid = new GUID("10385bcdad8d47fda22f5921a3185d58");
|
||
const string kLetterAtlasPath = "Assets/Repro/letters.png";
|
||
|
||
static readonly GUID kDigitAtlasGuid = new GUID("20385bcdad8d47fda22f5921a3185d59");
|
||
const string kDigitAtlasPath = "Assets/Repro/numbers.png";
|
||
|
||
static readonly GUID kExtraArtifactGuid = new GUID("30385bcdad8d47fda22f5921a3185d5a");
|
||
|
||
const BindingFlags kObjectIdentifierFieldFlags = BindingFlags.NonPublic | BindingFlags.Instance;
|
||
|
||
static readonly string[] kObjectIdentifierReflectFieldNames =
|
||
{
|
||
"m_GUID", "m_LocalIdentifierInFile", "m_FileType", "m_FilePath",
|
||
};
|
||
|
||
static PrefabPackedIdentifiersSerializationIndexTests()
|
||
{
|
||
AssertObjectIdentifierReflectionLayout();
|
||
}
|
||
|
||
static void AssertObjectIdentifierReflectionLayout()
|
||
{
|
||
var type = typeof(ObjectIdentifier);
|
||
var missing = new List<string>();
|
||
foreach (string name in kObjectIdentifierReflectFieldNames)
|
||
{
|
||
if (type.GetField(name, kObjectIdentifierFieldFlags) == null)
|
||
missing.Add(name);
|
||
}
|
||
|
||
if (missing.Count != 0)
|
||
{
|
||
Assert.Fail(
|
||
$"UnityEngine.ObjectIdentifier private fields missing or renamed: {string.Join(", ", missing)}. " +
|
||
$"Update {nameof(MakeObjectId)} for this Unity version.");
|
||
}
|
||
}
|
||
|
||
/// <summary>Sprite names A–F; local ids are arbitrary but stable and unique per subsprite.</summary>
|
||
static readonly (char Label, long LocalId)[] kLetterSprites =
|
||
{
|
||
('A', 1001), ('B', 1002), ('C', 1003), ('D', 1004), ('E', 1005), ('F', 1006),
|
||
};
|
||
|
||
/// <summary>Sprite names 0–9; local ids arbitrary stable per subsprite.</summary>
|
||
static readonly (char Label, long LocalId)[] kDigitSprites =
|
||
{
|
||
('0', 2000), ('1', 2001), ('2', 2002), ('3', 2003), ('4', 2004),
|
||
('5', 2005), ('6', 2006), ('7', 2007), ('8', 2008), ('9', 2009),
|
||
};
|
||
|
||
static ObjectIdentifier MakeObjectId(GUID guid, long localIdentifierInFile, FileType fileType, string filePath)
|
||
{
|
||
var objectId = new ObjectIdentifier();
|
||
var boxed = (object)objectId;
|
||
var type = typeof(ObjectIdentifier);
|
||
type.GetField("m_GUID", kObjectIdentifierFieldFlags).SetValue(boxed, guid);
|
||
type.GetField("m_LocalIdentifierInFile", kObjectIdentifierFieldFlags).SetValue(boxed, localIdentifierInFile);
|
||
type.GetField("m_FileType", kObjectIdentifierFieldFlags).SetValue(boxed, fileType);
|
||
type.GetField("m_FilePath", kObjectIdentifierFieldFlags).SetValue(boxed, filePath);
|
||
return (ObjectIdentifier)boxed;
|
||
}
|
||
|
||
static ObjectIdentifier LetterObject(long localId) =>
|
||
MakeObjectId(kLetterAtlasGuid, localId, FileType.SerializedAssetType, kLetterAtlasPath);
|
||
|
||
static ObjectIdentifier DigitObject(long localId) =>
|
||
MakeObjectId(kDigitAtlasGuid, localId, FileType.SerializedAssetType, kDigitAtlasPath);
|
||
|
||
static ObjectIdentifier ExtraArtifactObject(string forwardSlashPath, long localId) =>
|
||
MakeObjectId(kExtraArtifactGuid, localId, FileType.SerializedAssetType, forwardSlashPath);
|
||
|
||
static void PushSbpState(out bool prevV2Hasher, out int prevSeed, out int prevHeader, int headerSize, int hashSeed = 0)
|
||
{
|
||
#if UNITY_2020_1_OR_NEWER
|
||
prevV2Hasher = ScriptableBuildPipeline.useV2Hasher;
|
||
ScriptableBuildPipeline.useV2Hasher = false;
|
||
#else
|
||
prevV2Hasher = false;
|
||
#endif
|
||
prevSeed = ScriptableBuildPipeline.fileIDHashSeed;
|
||
ScriptableBuildPipeline.fileIDHashSeed = hashSeed;
|
||
prevHeader = ScriptableBuildPipeline.prefabPackedHeaderSize;
|
||
ScriptableBuildPipeline.prefabPackedHeaderSize = headerSize;
|
||
}
|
||
|
||
static void PopSbpState(bool prevV2Hasher, int prevSeed, int prevHeader)
|
||
{
|
||
#if UNITY_2020_1_OR_NEWER
|
||
ScriptableBuildPipeline.useV2Hasher = prevV2Hasher;
|
||
#endif
|
||
ScriptableBuildPipeline.fileIDHashSeed = prevSeed;
|
||
ScriptableBuildPipeline.prefabPackedHeaderSize = prevHeader;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Verifies that the first and last letter subsprites (A and F) of the same atlas share the
|
||
/// asset-only prefix of their serialization indices, for every supported header size.
|
||
/// </summary>
|
||
/// <param name="headerSize">Prefab Packed header size (in bytes) that determines how many upper bits of the serialization index are asset-derived.</param>
|
||
[TestCase(1)]
|
||
[TestCase(2)]
|
||
[TestCase(3)]
|
||
[TestCase(4)]
|
||
public void SerializationIndexFromObjectIdentifier_LetterAtlas_A_SharesUpperBitsWith_F(int headerSize)
|
||
{
|
||
PushSbpState(out bool prevV2, out int prevSeed, out int prevHeader, headerSize);
|
||
try
|
||
{
|
||
var packing = new PrefabPackedIdentifiers();
|
||
var idA = LetterObject(1001);
|
||
var idF = LetterObject(1006);
|
||
|
||
ulong prefixA = PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(packing.SerializationIndexFromObjectIdentifier(idA), headerSize);
|
||
ulong prefixF = PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(packing.SerializationIndexFromObjectIdentifier(idF), headerSize);
|
||
|
||
Assert.AreEqual(prefixA, prefixF,
|
||
$"Letter atlas: subsprites A and F must share the asset-only prefix (headerSize={headerSize}, UUM-131143).");
|
||
}
|
||
finally
|
||
{
|
||
PopSbpState(prevV2, prevSeed, prevHeader);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Verifies that the first and last digit subsprites (0 and 9) of the same atlas share the
|
||
/// asset-only prefix of their serialization indices, for every supported header size.
|
||
/// </summary>
|
||
/// <param name="headerSize">Prefab Packed header size (in bytes) that determines how many upper bits of the serialization index are asset-derived.</param>
|
||
[TestCase(1)]
|
||
[TestCase(2)]
|
||
[TestCase(3)]
|
||
[TestCase(4)]
|
||
public void SerializationIndexFromObjectIdentifier_DigitAtlas_0_SharesUpperBitsWith_9(int headerSize)
|
||
{
|
||
PushSbpState(out bool prevV2, out int prevSeed, out int prevHeader, headerSize);
|
||
try
|
||
{
|
||
var packing = new PrefabPackedIdentifiers();
|
||
var id0 = DigitObject(2000);
|
||
var id9 = DigitObject(2009);
|
||
|
||
ulong prefix0 = PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(packing.SerializationIndexFromObjectIdentifier(id0), headerSize);
|
||
ulong prefix9 = PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(packing.SerializationIndexFromObjectIdentifier(id9), headerSize);
|
||
|
||
Assert.AreEqual(prefix0, prefix9,
|
||
$"Digit atlas: subsprites 0 and 9 must share the asset-only prefix (headerSize={headerSize}, UUM-131143).");
|
||
}
|
||
finally
|
||
{
|
||
PopSbpState(prevV2, prevSeed, prevHeader);
|
||
}
|
||
}
|
||
|
||
// Previously: SerializationIndexFromObjectIdentifier_AllLetterSubsprites_ShareOneUpperUInt32
|
||
/// <summary>
|
||
/// Verifies that every letter subsprite (A–F) of the letter atlas maps to the same asset-only
|
||
/// prefix, so a contiguous bundle keeps the whole source asset together.
|
||
/// </summary>
|
||
[Test]
|
||
public void SerializationIndexFromObjectIdentifier_AllLetterSubsprites_ShareOneAssetPrefix()
|
||
{
|
||
const int headerSize = 2;
|
||
PushSbpState(out bool prevV2, out int prevSeed, out int prevHeader, headerSize);
|
||
try
|
||
{
|
||
var packing = new PrefabPackedIdentifiers();
|
||
var prefixes = new List<ulong>(kLetterSprites.Length);
|
||
foreach (var (label, localId) in kLetterSprites)
|
||
{
|
||
var id = LetterObject(localId);
|
||
prefixes.Add(PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(packing.SerializationIndexFromObjectIdentifier(id), headerSize));
|
||
}
|
||
|
||
ulong first = prefixes[0];
|
||
for (int i = 1; i < prefixes.Count; i++)
|
||
{
|
||
Assert.AreEqual(first, prefixes[i],
|
||
$"Letter atlas: subsprite {kLetterSprites[i].Label} should match A's asset prefix (UUM-131143).");
|
||
}
|
||
}
|
||
finally
|
||
{
|
||
PopSbpState(prevV2, prevSeed, prevHeader);
|
||
}
|
||
}
|
||
|
||
// Previously: SerializationIndexFromObjectIdentifier_AllDigitSubsprites_ShareOneUpperUInt32
|
||
/// <summary>
|
||
/// Verifies that every digit subsprite (0–9) of the digit atlas maps to the same asset-only
|
||
/// prefix, so a contiguous bundle keeps the whole source asset together.
|
||
/// </summary>
|
||
[Test]
|
||
public void SerializationIndexFromObjectIdentifier_AllDigitSubsprites_ShareOneAssetPrefix()
|
||
{
|
||
const int headerSize = 2;
|
||
PushSbpState(out bool prevV2, out int prevSeed, out int prevHeader, headerSize);
|
||
try
|
||
{
|
||
var packing = new PrefabPackedIdentifiers();
|
||
var prefixes = new List<ulong>(kDigitSprites.Length);
|
||
foreach (var (label, localId) in kDigitSprites)
|
||
{
|
||
var id = DigitObject(localId);
|
||
prefixes.Add(PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(packing.SerializationIndexFromObjectIdentifier(id), headerSize));
|
||
}
|
||
|
||
ulong first = prefixes[0];
|
||
for (int i = 1; i < prefixes.Count; i++)
|
||
{
|
||
Assert.AreEqual(first, prefixes[i],
|
||
$"Digit atlas: subsprite {kDigitSprites[i].Label} should match 0's asset prefix (UUM-131143).");
|
||
}
|
||
}
|
||
finally
|
||
{
|
||
PopSbpState(prevV2, prevSeed, prevHeader);
|
||
}
|
||
}
|
||
|
||
// Previously: SerializationIndexFromObjectIdentifier_LetterAtlasAndDigitAtlas_DifferInUpperUInt32
|
||
/// <summary>
|
||
/// Verifies that subsprites from two different atlases land on different asset-only prefixes and
|
||
/// do not collide on the full serialization index.
|
||
/// </summary>
|
||
[Test]
|
||
public void SerializationIndexFromObjectIdentifier_LetterAtlasAndDigitAtlas_DifferInAssetPrefix()
|
||
{
|
||
const int headerSize = 2;
|
||
PushSbpState(out bool prevV2, out int prevSeed, out int prevHeader, headerSize);
|
||
try
|
||
{
|
||
var packing = new PrefabPackedIdentifiers();
|
||
long letterIndex = packing.SerializationIndexFromObjectIdentifier(LetterObject(1003));
|
||
long digitIndex = packing.SerializationIndexFromObjectIdentifier(DigitObject(2005));
|
||
|
||
Assert.AreNotEqual(
|
||
PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(letterIndex, headerSize),
|
||
PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(digitIndex, headerSize),
|
||
"Letter atlas vs digit atlas should not share the same asset-only prefix.");
|
||
Assert.AreNotEqual(letterIndex, digitIndex, "Distinct subsprites should not collide on the full index.");
|
||
}
|
||
finally
|
||
{
|
||
PopSbpState(prevV2, prevSeed, prevHeader);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Verifies that subsprites of the letter atlas still share the asset-only prefix when a non-zero
|
||
/// <c>fileIDHashSeed</c> is configured.
|
||
/// </summary>
|
||
/// <param name="headerSize">Prefab Packed header size (in bytes) that determines how many upper bits of the serialization index are asset-derived.</param>
|
||
[TestCase(1)]
|
||
[TestCase(2)]
|
||
[TestCase(3)]
|
||
[TestCase(4)]
|
||
public void SerializationIndexFromObjectIdentifier_NonZeroFileIdHashSeed_LetterAtlas_SharesAssetPrefix(int headerSize)
|
||
{
|
||
const int kNonZeroSeed = 42;
|
||
PushSbpState(out bool prevV2, out int prevSeed, out int prevHeader, headerSize, kNonZeroSeed);
|
||
try
|
||
{
|
||
var packing = new PrefabPackedIdentifiers();
|
||
var idA = LetterObject(1001);
|
||
var idF = LetterObject(1006);
|
||
|
||
ulong prefixA = PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(packing.SerializationIndexFromObjectIdentifier(idA), headerSize);
|
||
ulong prefixF = PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(packing.SerializationIndexFromObjectIdentifier(idF), headerSize);
|
||
|
||
Assert.AreEqual(prefixA, prefixF,
|
||
$"Letter atlas with fileIDHashSeed={kNonZeroSeed}: A and F must share asset-only prefix (headerSize={headerSize}).");
|
||
}
|
||
finally
|
||
{
|
||
PopSbpState(prevV2, prevSeed, prevHeader);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Verifies that the letter and digit atlases keep distinct asset-only prefixes when a non-zero
|
||
/// <c>fileIDHashSeed</c> is configured.
|
||
/// </summary>
|
||
[Test]
|
||
public void SerializationIndexFromObjectIdentifier_NonZeroFileIdHashSeed_LetterAndDigitAtlases_DifferInAssetPrefix()
|
||
{
|
||
const int headerSize = 2;
|
||
const int kNonZeroSeed = 42;
|
||
PushSbpState(out bool prevV2, out int prevSeed, out int prevHeader, headerSize, kNonZeroSeed);
|
||
try
|
||
{
|
||
var packing = new PrefabPackedIdentifiers();
|
||
long letterIndex = packing.SerializationIndexFromObjectIdentifier(LetterObject(1003));
|
||
long digitIndex = packing.SerializationIndexFromObjectIdentifier(DigitObject(2005));
|
||
|
||
Assert.AreNotEqual(
|
||
PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(letterIndex, headerSize),
|
||
PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(digitIndex, headerSize),
|
||
"Letter vs digit atlas should not share the same asset-only prefix when fileIDHashSeed is non-zero.");
|
||
}
|
||
finally
|
||
{
|
||
PopSbpState(prevV2, prevSeed, prevHeader);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Same asset-prefix expectations, but for object identifiers whose file path points at a
|
||
/// non-primary artifact under <c>VirtualArtifacts/Extra/</c> rather than at an asset in the project.
|
||
/// Those paths are produced on demand by <see cref="VirtualArtifactSerializationIndexTestImporter"/>.
|
||
/// </summary>
|
||
[TestFixture]
|
||
public sealed class VirtualArtifactsExtraSerializationIndex
|
||
{
|
||
const string kTildeFixtureFileA = "~extra_a.uum131143_virt";
|
||
const string kTildeFixtureFileB = "~extra_b.uum131143_virt";
|
||
|
||
const string kStagingAssetPathA = "Packages/com.unity.scriptablebuildpipeline/Tests/Editor/Fixtures/sbp_uum131143_staging_a.uum131143_virt";
|
||
const string kStagingAssetPathB = "Packages/com.unity.scriptablebuildpipeline/Tests/Editor/Fixtures/sbp_uum131143_staging_b.uum131143_virt";
|
||
|
||
const string kFixturesVirtualRoot = "Packages/com.unity.scriptablebuildpipeline/Tests/Editor/Fixtures";
|
||
|
||
static string s_virtualExtraPathA;
|
||
static string s_virtualExtraPathB;
|
||
|
||
static string FixturesPhysicalDirectory =>
|
||
Path.GetFullPath(Path.Combine(Application.dataPath, "..", "Packages", "com.unity.scriptablebuildpipeline", "Tests", "Editor", "Fixtures"));
|
||
|
||
/// <summary>
|
||
/// Deploys the staging fixtures and forces production of their scripted-importer artifacts, caching
|
||
/// the two distinct <c>VirtualArtifacts/Extra/</c> paths the tests in this fixture run against.
|
||
/// </summary>
|
||
[OneTimeSetUp]
|
||
public static void ProduceExtraArtifactPaths()
|
||
{
|
||
DeployStagingFixturesFromTildeSources();
|
||
s_virtualExtraPathA = ProduceOneVirtualArtifactsExtraPath(kStagingAssetPathA);
|
||
s_virtualExtraPathB = ProduceOneVirtualArtifactsExtraPath(kStagingAssetPathB);
|
||
Assert.AreNotEqual(s_virtualExtraPathA, s_virtualExtraPathB,
|
||
"Two preview artifacts must resolve to distinct VirtualArtifacts/Extra paths.");
|
||
}
|
||
|
||
/// <summary>
|
||
/// Deletes the staging fixture assets copied into the package by <see cref="ProduceExtraArtifactPaths"/>.
|
||
/// </summary>
|
||
[OneTimeTearDown]
|
||
public static void RemoveStagingFixtures()
|
||
{
|
||
AssetDatabase.DeleteAsset(kStagingAssetPathA);
|
||
AssetDatabase.DeleteAsset(kStagingAssetPathB);
|
||
}
|
||
|
||
static void DeployStagingFixturesFromTildeSources()
|
||
{
|
||
string dir = FixturesPhysicalDirectory;
|
||
string srcA = Path.Combine(dir, kTildeFixtureFileA);
|
||
string srcB = Path.Combine(dir, kTildeFixtureFileB);
|
||
if (!File.Exists(srcA))
|
||
throw new IOException($"Missing tilde fixture: {srcA}");
|
||
if (!File.Exists(srcB))
|
||
throw new IOException($"Missing tilde fixture: {srcB}");
|
||
|
||
// File.Copy does not create .meta; under Packages/ Unity ignores assets without a sibling .meta,
|
||
// so these scripted-importer fixtures never import and ForceProduceArtifact fails in CI.
|
||
string srcAssetPathA = $"{kFixturesVirtualRoot}/{kTildeFixtureFileA}";
|
||
string srcAssetPathB = $"{kFixturesVirtualRoot}/{kTildeFixtureFileB}";
|
||
RemovePhysicalAssetIfMissingMeta(Path.Combine(dir, Path.GetFileName(kStagingAssetPathA)));
|
||
RemovePhysicalAssetIfMissingMeta(Path.Combine(dir, Path.GetFileName(kStagingAssetPathB)));
|
||
CopyStagingFixtureViaAssetDatabase(srcAssetPathA, kStagingAssetPathA);
|
||
CopyStagingFixtureViaAssetDatabase(srcAssetPathB, kStagingAssetPathB);
|
||
|
||
AssetDatabase.ImportAsset(kStagingAssetPathA, ImportAssetOptions.ForceUpdate);
|
||
AssetDatabase.ImportAsset(kStagingAssetPathB, ImportAssetOptions.ForceUpdate);
|
||
}
|
||
|
||
static void RemovePhysicalAssetIfMissingMeta(string physicalAssetPath)
|
||
{
|
||
if (!File.Exists(physicalAssetPath))
|
||
return;
|
||
if (File.Exists(physicalAssetPath + ".meta"))
|
||
return;
|
||
File.Delete(physicalAssetPath);
|
||
}
|
||
|
||
static void CopyStagingFixtureViaAssetDatabase(string srcUnityPath, string dstUnityPath)
|
||
{
|
||
if (AssetDatabase.LoadMainAssetAtPath(dstUnityPath) != null)
|
||
AssetDatabase.DeleteAsset(dstUnityPath);
|
||
if (!AssetDatabase.CopyAsset(srcUnityPath, dstUnityPath))
|
||
throw new IOException($"AssetDatabase.CopyAsset failed: {srcUnityPath} -> {dstUnityPath}");
|
||
}
|
||
|
||
static string ProduceOneVirtualArtifactsExtraPath(string assetPath)
|
||
{
|
||
GUID guid = AssetDatabase.GUIDFromAssetPath(assetPath);
|
||
Assert.False(guid.Empty(), $"Missing test asset (expected in this package): {assetPath}");
|
||
|
||
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||
|
||
var key = new ArtifactKey(guid, typeof(VirtualArtifactSerializationIndexTestImporter));
|
||
var artifactId = AssetDatabaseExperimental.ForceProduceArtifact(key);
|
||
Assert.IsTrue(artifactId.isValid, "ForceProduceArtifact should yield a valid ArtifactID.");
|
||
|
||
Assert.IsTrue(AssetDatabaseExperimental.GetArtifactPaths(artifactId, out string[] paths),
|
||
"GetArtifactPaths should succeed after production.");
|
||
Assert.IsNotNull(paths);
|
||
Assert.IsNotEmpty(paths, "ScriptedImporter artifact should list at least one produced path.");
|
||
|
||
foreach (string p in paths)
|
||
{
|
||
if (p.Replace('\\', '/').StartsWith("VirtualArtifacts/Extra/", StringComparison.Ordinal))
|
||
return p;
|
||
}
|
||
|
||
Assert.Fail($"Expected at least one path under VirtualArtifacts/Extra/ for {assetPath}. Got: {string.Join(", ", paths)}");
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Verifies that two objects with different local ids inside the same <c>VirtualArtifacts/Extra/</c>
|
||
/// file share the asset-only prefix of their serialization indices.
|
||
/// </summary>
|
||
/// <param name="fileIdHashSeed">Value assigned to <c>ScriptableBuildPipeline.fileIDHashSeed</c> for the duration of the test.</param>
|
||
[TestCase(0)]
|
||
[TestCase(42)]
|
||
public void SerializationIndexFromObjectIdentifier_VirtualArtifactsExtra_SameFileDifferentLocalIds_ShareAssetPrefix(int fileIdHashSeed)
|
||
{
|
||
const int headerSize = 2;
|
||
PushSbpState(out bool prevV2, out int prevSeed, out int prevHeader, headerSize, fileIdHashSeed);
|
||
try
|
||
{
|
||
var packing = new PrefabPackedIdentifiers();
|
||
var id1 = ExtraArtifactObject(s_virtualExtraPathA, 3001);
|
||
var id2 = ExtraArtifactObject(s_virtualExtraPathA, 3002);
|
||
|
||
ulong p1 = PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(packing.SerializationIndexFromObjectIdentifier(id1), headerSize);
|
||
ulong p2 = PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(packing.SerializationIndexFromObjectIdentifier(id2), headerSize);
|
||
|
||
Assert.AreEqual(p1, p2,
|
||
$"VirtualArtifacts/Extra same file: local ids must share asset-only prefix (fileIDHashSeed={fileIdHashSeed}).");
|
||
}
|
||
finally
|
||
{
|
||
PopSbpState(prevV2, prevSeed, prevHeader);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Verifies that objects living in two different <c>VirtualArtifacts/Extra/</c> files land on
|
||
/// different asset-only prefixes.
|
||
/// </summary>
|
||
/// <param name="fileIdHashSeed">Value assigned to <c>ScriptableBuildPipeline.fileIDHashSeed</c> for the duration of the test.</param>
|
||
[TestCase(0)]
|
||
[TestCase(42)]
|
||
public void SerializationIndexFromObjectIdentifier_VirtualArtifactsExtra_DifferentFiles_DifferInAssetPrefix(int fileIdHashSeed)
|
||
{
|
||
const int headerSize = 2;
|
||
PushSbpState(out bool prevV2, out int prevSeed, out int prevHeader, headerSize, fileIdHashSeed);
|
||
try
|
||
{
|
||
var packing = new PrefabPackedIdentifiers();
|
||
long idxA = packing.SerializationIndexFromObjectIdentifier(ExtraArtifactObject(s_virtualExtraPathA, 3001));
|
||
long idxB = packing.SerializationIndexFromObjectIdentifier(ExtraArtifactObject(s_virtualExtraPathB, 3002));
|
||
|
||
Assert.AreNotEqual(
|
||
PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(idxA, headerSize),
|
||
PrefabPackedSerializationIndexTestUtil.AssetOnlyPrefix(idxB, headerSize),
|
||
$"Different VirtualArtifacts/Extra files should not share asset-only prefix (fileIDHashSeed={fileIdHashSeed}).");
|
||
}
|
||
finally
|
||
{
|
||
PopSbpState(prevV2, prevSeed, prevHeader);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|