Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions TestCommon/TestFixtures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

namespace UnityDataTools.TestCommon;

// Base class that facilitates iterating through sub-sub-folders
// inside the Data location. E.g. GetContexts("AssetBundles")
// finds "TestCommon/Data/AssetBundles/2019.4.0f1", "TestCommon/Data/AssetBundles/2020.3.0f1" etc.
public class BaseTestFixture
{
protected Context Context { get; }
Expand All @@ -15,6 +18,8 @@ public BaseTestFixture(Context context)
Context = context;
}

// Tests that have files that record the expected results for each version
// of Unity can override this method to regenerate those expected results.
protected virtual void OnLoadExpectedData(Context context)
{
}
Expand All @@ -23,6 +28,9 @@ protected virtual void OnLoadExpectedData(Context context)
public void LoadExpectedData()
{
OnLoadExpectedData(Context);

// Load json file with the expected results for a test based on
// folder structure convention (e.g. ExpectedData/<UnityVersion>/ExpectedVersions.json)
Context.ExpectedData.Load(Context.ExpectedDataFolder);
}

Expand All @@ -47,6 +55,9 @@ protected static IEnumerable<Context> GetContexts(string dataFolder)
}
}

// Test fixture that repeats the tests for each folder inside TestCommon/Data/AssetBundles.
// Each sub-folder is expected to have results of an AssetBundle build repeated with a
// different version of Unity.
[TestFixtureSource(typeof(AssetBundleTestFixture), nameof(GetContexts))]
public class AssetBundleTestFixture : BaseTestFixture
{
Expand Down
84 changes: 84 additions & 0 deletions UnityDataTool.Tests/AddressablesBuildLayoutTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System;
using Microsoft.Data.Sqlite;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using NUnit.Framework;

namespace UnityDataTools.UnityDataTool.Tests;

#pragma warning disable NUnit2005, NUnit2006

public class AddressablesBuildLayoutTests
{
private string m_TestOutputFolder;
private string m_TestDataFolder;

[OneTimeSetUp]
public void OneTimeSetup()
{
m_TestOutputFolder = Path.Combine(TestContext.CurrentContext.TestDirectory, "test_folder");
m_TestDataFolder = Path.Combine(TestContext.CurrentContext.TestDirectory, "Data");
Directory.CreateDirectory(m_TestOutputFolder);
Directory.SetCurrentDirectory(m_TestOutputFolder);
}

[TearDown]
public void Teardown()
{
SqliteConnection.ClearAllPools();

var testDir = new DirectoryInfo(m_TestOutputFolder);
testDir.EnumerateFiles()
.ToList().ForEach(f => f.Delete());
testDir.EnumerateDirectories()
.ToList().ForEach(d => d.Delete(true));
}

[Test]
public async Task Analyze_BuildLayout_ContainsExpectedSQLContent()
{
// This folder contains reference files from two builds of the "AudioExample"
// Addressables test project.
// The test confirms some expected content in the database
var path = Path.Combine(m_TestDataFolder, "AddressableBuildLayouts");

var databasePath = Path.Combine(m_TestOutputFolder, "database.db");

Assert.AreEqual(0, await Program.Main(new string[] { "analyze", path, "-p", "*.json" }));
using var db = new SqliteConnection(new SqliteConnectionStringBuilder
{
DataSource = databasePath,
Mode = SqliteOpenMode.ReadWriteCreate,
Pooling = false,
ForeignKeys = false,
}.ConnectionString);
db.Open();

using var cmd = db.CreateCommand();

// Sanity check some expected content in the output SQLite database
cmd.CommandText =
@"SELECT
(SELECT COUNT(*) FROM addressables_builds),
(SELECT COUNT(*) FROM addressables_builds WHERE name = ""buildlayout_2025.01.28.16.35.01.json""),
(SELECT unity_version FROM addressables_builds WHERE id = 1),
(SELECT package_version FROM addressables_builds WHERE id = 1),
(SELECT COUNT(*) FROM addressables_build_bundles WHERE build_id = 1 and name = ""samplepack1_assets_0.bundle""),
(SELECT file_size FROM addressables_build_bundles WHERE build_id = 2 and name = ""samplepack1_assets_0.bundle""),
(SELECT packing_mode FROM addressables_build_groups WHERE build_id = 1 and name = ""SamplePack1""),
(SELECT COUNT(*) FROM asset_bundles)";

using var reader = cmd.ExecuteReader();
reader.Read();

Assert.AreEqual(2, reader.GetInt32(0), "Unexpected number of builds");
Assert.AreEqual(1, reader.GetInt32(1), "Failed to find build matching reference filename");
Assert.AreEqual("6000.1.0b2", reader.GetString(2), "Unexpected Unity Version");
Assert.AreEqual("com.unity.addressables: 2.2.2", reader.GetString(3), "Unexpected Addressables version");
Assert.AreEqual(1, reader.GetInt32(4), "Expected to find specific AssetBundle by name");
Assert.AreEqual(33824, reader.GetInt32(5), "Unexpected size for specific AssetBundle in build 2");
Assert.AreEqual("PackSeparately", reader.GetString(6), "Unexpected packing_mode for group");
Assert.AreEqual(0, reader.GetInt32(7), "Expected no AssetBundles found in reference folder");
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Above is the only new test code.

The rest of the changes are just shuffling existing tests into better structure

}
9 changes: 7 additions & 2 deletions UnityDataTool.Tests/ExpectedDataGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

namespace UnityDataTools.UnityDataTool.Tests;

// Collect and record the current output returned by the same UnityDataTool commands
// that the tests will run. Once saved these become the reference data, and if the output
// changes the tests will fail. So this can be repeated if there is an "expected" change
// in the output.
public static class ExpectedDataGenerator
{
public static void Generate(Context context)
Expand Down Expand Up @@ -71,6 +75,9 @@ public static void Generate(Context context)
var csprojFolder = Directory.GetParent(context.TestDataFolder).Parent.Parent.Parent.FullName;
var outputFolder = Path.Combine(csprojFolder, "ExpectedData", context.UnityDataVersion);

expectedData.Save(outputFolder);

// Also take a snapshot of the output of running "dump" commands on the test file "assetbundle"
Directory.CreateDirectory(outputFolder);

var dumpPath = Path.Combine(outputFolder, "dump");
Expand All @@ -80,7 +87,5 @@ public static void Generate(Context context)
dumpPath = Path.Combine(outputFolder, "dump-s");
Directory.CreateDirectory(dumpPath);
Program.Main(new string[] { "dump", Path.Combine(context.UnityDataFolder, "assetbundle"), "-o", dumpPath, "-s" });

expectedData.Save(outputFolder);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ namespace UnityDataTools.UnityDataTool.Tests;

#pragma warning disable NUnit2005, NUnit2006

public class UnityDataToolTests : AssetBundleTestFixture
public class UnityDataToolAssetBundleTests : AssetBundleTestFixture
{
private string m_TestOutputFolder;

public UnityDataToolTests(Context context) : base(context)
public UnityDataToolAssetBundleTests(Context context) : base(context)
{
}

Expand Down Expand Up @@ -59,20 +59,6 @@ public async Task InvalidFile(
Assert.AreNotEqual(0, await Program.Main(command.ToArray()));
}

public void IsWebBundle_True()
{

var webBundlePath = Path.Combine(Context.TestDataFolder, "WebBundles", "HelloWorld.data");
Assert.IsTrue(Archive.IsWebBundle(new FileInfo(webBundlePath)));
}

[Test]
public void IsWebBundle_False()
{
var nonWebBundlePath = Path.Combine(Context.TestDataFolder, "WebBundles", "NotAWebBundle.txt");
Assert.IsFalse(Archive.IsWebBundle(new FileInfo(nonWebBundlePath)));
}

[Test]
public async Task ArchiveExtract_AssetBundle_FilesExtractedSuccessfully(
[Values("", "-o archive", "--output-path archive")] string options)
Expand All @@ -85,27 +71,6 @@ public async Task ArchiveExtract_AssetBundle_FilesExtractedSuccessfully(
Assert.IsTrue(File.Exists(Path.Combine(m_TestOutputFolder, "archive", "CAB-5d40f7cad7c871cf2ad2af19ac542994.resource")));
}

[Test]
public async Task ArchiveExtract_WebBundle_FileExtractedSuccessfully(
[Values("", "-o archive", "--output-path archive")] string options,
[Values("HelloWorld.data", "HelloWorld.data.gz", "HelloWorld.data.br")] string bundlePath)
{
var path = Path.Combine(Context.TestDataFolder, "WebBundles", bundlePath);
string[] expectedFiles = {
"boot.config",
"data.unity3d",
"RuntimeInitializeOnLoads.json",
"ScriptingAssemblies.json",
Path.Combine("Il2CppData", "Metadata", "global-metadata.dat"),
Path.Combine("Resources", "unity_default_resources"),
};
Assert.AreEqual(0, await Program.Main(new string[] { "archive", "extract", path }.Concat(options.Split(" ", StringSplitOptions.RemoveEmptyEntries)).ToArray()));
foreach (var file in expectedFiles)
{
Assert.IsTrue(File.Exists(Path.Combine(m_TestOutputFolder, "archive", file)));
}
}

[Test]
public async Task ArchiveList_AssetBundle_ListFilesCorrectly()
{
Expand Down Expand Up @@ -139,54 +104,6 @@ public async Task ArchiveList_AssetBundle_ListFilesCorrectly()
}
}

[Test]
public async Task ArchiveList_WebBundle_ListFilesCorrectly(
[Values(
"HelloWorld.data",
"HelloWorld.data.gz",
"HelloWorld.data.br"
)] string bundlePath)
{
var path = Path.Combine(Context.TestDataFolder, "WebBundles", bundlePath);
using var sw = new StringWriter();
var currentOut = Console.Out;
try
{
Console.SetOut(sw);

Assert.AreEqual(0, await Program.Main(new string[] { "archive", "list", path }));

var actualOutput = sw.ToString();
var expectedOutput = (
@"data.unity3d
Size: 253044

RuntimeInitializeOnLoads.json
Size: 700

ScriptingAssemblies.json
Size: 3060

boot.config
Size: 93

Il2CppData/Metadata/global-metadata.dat
Size: 1641180

Resources/unity_default_resources
Size: 607376

"
);

Assert.AreEqual(expectedOutput, actualOutput);
}
finally
{
Console.SetOut(currentOut);
}
}

[Test]
public async Task DumpText_DefaultArgs_TextFileCreatedCorrectly(
[Values("", "-f text", "--output-format text")] string options)
Expand Down Expand Up @@ -352,87 +269,3 @@ private void ValidateDatabase(string databasePath, bool withRefs)
}
}
}

public class UnityDataToolPlayerDataTests : PlayerDataTestFixture
{
private string m_TestOutputFolder;

public UnityDataToolPlayerDataTests(Context context) : base(context)
{
}

[OneTimeSetUp]
public void OneTimeSetup()
{
m_TestOutputFolder = Path.Combine(TestContext.CurrentContext.TestDirectory, "test_folder");
Directory.CreateDirectory(m_TestOutputFolder);
Directory.SetCurrentDirectory(m_TestOutputFolder);
}

[TearDown]
public void Teardown()
{
SqliteConnection.ClearAllPools();

foreach (var file in new DirectoryInfo(m_TestOutputFolder).EnumerateFiles())
{
file.Delete();
}
}

[Test]
public async Task Analyze_PlayerData_DatabaseCorrect()
{
var databasePath = Path.Combine(m_TestOutputFolder, "database.db");
var analyzePath = Path.Combine(Context.UnityDataFolder);

Assert.AreEqual(0, await Program.Main(new string[] { "analyze", analyzePath, "-p", "*." }));
using var db = new SqliteConnection(new SqliteConnectionStringBuilder
{
DataSource = databasePath,
Mode = SqliteOpenMode.ReadWriteCreate,
Pooling = false,
ForeignKeys = false,
}.ConnectionString);
db.Open();

using var cmd = db.CreateCommand();

cmd.CommandText =
@"SELECT
(SELECT COUNT(*) FROM asset_bundles),
(SELECT COUNT(*) FROM assets),
(SELECT COUNT(*) FROM objects),
(SELECT COUNT(*) FROM refs),
(SELECT COUNT(*) FROM serialized_files)";

using var reader = cmd.ExecuteReader();

reader.Read();

Assert.AreEqual(0, reader.GetInt32(0));
Assert.AreEqual(0, reader.GetInt32(1));
Assert.Greater(reader.GetInt32(2), 0);
Assert.Greater(reader.GetInt32(3), 0);
Assert.AreEqual(1, reader.GetInt32(4));
}

[Test]
public async Task DumpText_PlayerData_TextFileCreatedCorrectly()
{
var path = Path.Combine(Context.UnityDataFolder, "level0");
var outputFile = Path.Combine(m_TestOutputFolder, "level0.txt");

Assert.AreEqual(0, await Program.Main(new string[] { "dump", path }));
Assert.IsTrue(File.Exists(outputFile));

var content = File.ReadAllText(outputFile);
var expected = File.ReadAllText(Path.Combine(Context.ExpectedDataFolder, "level0.txt"));

// Normalize line endings.
content = Regex.Replace(content, @"\r\n|\n\r|\r", "\n");
expected = Regex.Replace(expected, @"\r\n|\n\r|\r", "\n");

Assert.AreEqual(expected, content);
}
}
Loading