251 lines
10 KiB
C#
251 lines
10 KiB
C#
|
|
using System.Collections;
|
|||
|
|
using UnityEngine;
|
|||
|
|
using UnityEditor;
|
|||
|
|
using NUnit.Framework;
|
|||
|
|
using UnityEditor.Build.Reporting;
|
|||
|
|
using System.IO;
|
|||
|
|
using UnityEngine.TestTools;
|
|||
|
|
using System.Diagnostics;
|
|||
|
|
|
|||
|
|
namespace Autodesk.Fbx.BuildTests
|
|||
|
|
{
|
|||
|
|
internal class BuildTest
|
|||
|
|
{
|
|||
|
|
private const string k_fbxsdkNativePlugin = "UnityFbxSdkNative";
|
|||
|
|
private const string k_autodeskFbxDll = "Autodesk.Fbx.dll";
|
|||
|
|
|
|||
|
|
#if UNITY_EDITOR_WIN
|
|||
|
|
private const string k_fbxsdkNativePluginExt = ".dll";
|
|||
|
|
private const string k_buildPluginPath = "{0}_Data";
|
|||
|
|
private const BuildTarget k_buildTarget = BuildTarget.StandaloneWindows64;
|
|||
|
|
private const string k_autodeskDllInstallPath = "Managed";
|
|||
|
|
#elif UNITY_EDITOR_OSX
|
|||
|
|
private const string k_fbxsdkNativePluginExt = ".bundle";
|
|||
|
|
private const string k_buildPluginPath = "{0}.app/Contents";
|
|||
|
|
private const BuildTarget k_buildTarget = BuildTarget.StandaloneOSX;
|
|||
|
|
private const string k_autodeskDllInstallPath = "Resources/Data/Managed";
|
|||
|
|
#else // UNITY_EDITOR_LINUX
|
|||
|
|
private const string k_fbxsdkNativePluginExt = ".so";
|
|||
|
|
private const string k_buildPluginPath = "{0}_Data";
|
|||
|
|
private const BuildTarget k_buildTarget = BuildTarget.StandaloneLinux64;
|
|||
|
|
private const string k_autodeskDllInstallPath = "Managed";
|
|||
|
|
#endif
|
|||
|
|
private const BuildTargetGroup k_buildTargetGroup = BuildTargetGroup.Standalone;
|
|||
|
|
|
|||
|
|
private const string k_buildTestScene = "Packages/com.autodesk.fbx/Tests/Runtime/BuildTestsAssets/BuildTestScene.unity";
|
|||
|
|
|
|||
|
|
private const string k_createdFbx = "emptySceneFromRuntimeBuild.fbx";
|
|||
|
|
|
|||
|
|
private const string k_runningBuildSymbol = "FBX_RUNNING_BUILD_TEST";
|
|||
|
|
|
|||
|
|
#if UNITY_EDITOR_LINUX
|
|||
|
|
private const string k_buildName = "test.x86_64";
|
|||
|
|
#else
|
|||
|
|
private const string k_buildName = "test.exe";
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
private string BuildFolder { get { return Path.Combine(Path.GetDirectoryName(Application.dataPath), "_safe_to_delete_build"); } }
|
|||
|
|
|
|||
|
|
public static IEnumerable RuntimeFbxSdkTestData
|
|||
|
|
{
|
|||
|
|
get
|
|||
|
|
{
|
|||
|
|
yield return new TestCaseData(
|
|||
|
|
new string[] { k_runningBuildSymbol },
|
|||
|
|
false,
|
|||
|
|
ScriptingImplementation.Mono2x
|
|||
|
|
).SetName("FbxSdkNotIncludedAtRuntime_Mono").Returns(null);
|
|||
|
|
yield return new TestCaseData(
|
|||
|
|
new string[] { k_runningBuildSymbol, "FBXSDK_RUNTIME" },
|
|||
|
|
true,
|
|||
|
|
ScriptingImplementation.Mono2x
|
|||
|
|
).SetName("FbxSdkIncludedAtRuntime_Mono").Returns(null);
|
|||
|
|
#if !UNITY_EDITOR_LINUX || UNITY_2019_3_OR_NEWER
|
|||
|
|
yield return new TestCaseData(
|
|||
|
|
new string[] { k_runningBuildSymbol },
|
|||
|
|
false,
|
|||
|
|
ScriptingImplementation.IL2CPP
|
|||
|
|
).SetName("FbxSdkNotIncludedAtRuntime_IL2CPP").Returns(null);
|
|||
|
|
yield return new TestCaseData(
|
|||
|
|
new string[] { k_runningBuildSymbol, "FBXSDK_RUNTIME" },
|
|||
|
|
true,
|
|||
|
|
ScriptingImplementation.IL2CPP
|
|||
|
|
).SetName("FbxSdkIncludedAtRuntime_IL2CPP").Returns(null);
|
|||
|
|
#endif // !UNITY_EDITOR_LINUX || UNITY_2019_3_OR_NEWER
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[SetUp]
|
|||
|
|
public void Init()
|
|||
|
|
{
|
|||
|
|
// Create build folder
|
|||
|
|
Directory.CreateDirectory(BuildFolder);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[TearDown]
|
|||
|
|
public void Term()
|
|||
|
|
{
|
|||
|
|
// reset the scripting define symbols
|
|||
|
|
var symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(k_buildTargetGroup);
|
|||
|
|
// remove the running build symbol and everything after it
|
|||
|
|
var result = symbols.Split(new string[] { k_runningBuildSymbol, ";" + k_runningBuildSymbol }, System.StringSplitOptions.None);
|
|||
|
|
PlayerSettings.SetScriptingDefineSymbolsForGroup(k_buildTargetGroup, result[0]);
|
|||
|
|
|
|||
|
|
// set scripting backend back to default (Mono)
|
|||
|
|
PlayerSettings.SetScriptingBackend(k_buildTargetGroup, ScriptingImplementation.Mono2x);
|
|||
|
|
|
|||
|
|
// delete build folder
|
|||
|
|
if (Directory.Exists(BuildFolder))
|
|||
|
|
{
|
|||
|
|
Directory.Delete(BuildFolder, recursive: true);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private BuildReport BuildPlayer()
|
|||
|
|
{
|
|||
|
|
BuildPlayerOptions options = new BuildPlayerOptions();
|
|||
|
|
options.locationPathName = Path.Combine(BuildFolder, k_buildName);
|
|||
|
|
options.target = k_buildTarget;
|
|||
|
|
options.targetGroup = k_buildTargetGroup;
|
|||
|
|
options.scenes = new string[] { k_buildTestScene };
|
|||
|
|
|
|||
|
|
var report = BuildPipeline.BuildPlayer(options);
|
|||
|
|
|
|||
|
|
Assert.That(report.summary.result, Is.EqualTo(BuildResult.Succeeded));
|
|||
|
|
|
|||
|
|
return report;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void AddDefineSymbols(string[] toAdd)
|
|||
|
|
{
|
|||
|
|
if (toAdd.Length <= 0)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(k_buildTargetGroup);
|
|||
|
|
if (!string.IsNullOrEmpty(symbols))
|
|||
|
|
{
|
|||
|
|
symbols += ";";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
symbols += toAdd[0];
|
|||
|
|
for (int i = 1; i < toAdd.Length; i++)
|
|||
|
|
{
|
|||
|
|
symbols += ";" + toAdd[i];
|
|||
|
|
}
|
|||
|
|
PlayerSettings.SetScriptingDefineSymbolsForGroup(k_buildTargetGroup, symbols);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[Ignore("Ignoring in CI because we don't control which backends are installed")]
|
|||
|
|
[UnityTest]
|
|||
|
|
[TestCaseSource("RuntimeFbxSdkTestData")]
|
|||
|
|
public IEnumerator TestFbxSdkAtRuntime(string[] defineSymbols, bool dllExists, ScriptingImplementation scriptingImplementation)
|
|||
|
|
{
|
|||
|
|
PlayerSettings.SetScriptingBackend(k_buildTargetGroup, scriptingImplementation);
|
|||
|
|
AddDefineSymbols(defineSymbols);
|
|||
|
|
|
|||
|
|
// start and stop playmode to force a domain reload
|
|||
|
|
Assert.False(Application.isPlaying);
|
|||
|
|
yield return new EnterPlayMode();
|
|||
|
|
Assert.True(Application.isPlaying);
|
|||
|
|
yield return new ExitPlayMode();
|
|||
|
|
Assert.False(Application.isPlaying);
|
|||
|
|
|
|||
|
|
var report = BuildPlayer();
|
|||
|
|
|
|||
|
|
// check whether the plugins were copied
|
|||
|
|
var buildPathWithoutExt = Path.ChangeExtension(report.summary.outputPath, null);
|
|||
|
|
var buildPluginFullPath = Path.Combine(
|
|||
|
|
string.Format(k_buildPluginPath, buildPathWithoutExt),
|
|||
|
|
"Plugins",
|
|||
|
|
#if UNITY_EDITOR_LINUX
|
|||
|
|
"x86_64",
|
|||
|
|
#endif
|
|||
|
|
k_fbxsdkNativePlugin + k_fbxsdkNativePluginExt
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
NUnit.Framework.Constraints.Constraint constraint = Does.Not.Exist;
|
|||
|
|
if (dllExists)
|
|||
|
|
{
|
|||
|
|
constraint = Does.Exist;
|
|||
|
|
}
|
|||
|
|
Assert.That(buildPluginFullPath, constraint);
|
|||
|
|
|
|||
|
|
// Autodesk.Fbx.dll will not exist if building with IL2CPP
|
|||
|
|
if(scriptingImplementation != ScriptingImplementation.IL2CPP)
|
|||
|
|
{
|
|||
|
|
// check the size of Autodesk.Fbx.dll
|
|||
|
|
var autodeskDllFullPath = Path.Combine(
|
|||
|
|
string.Format(k_buildPluginPath, buildPathWithoutExt),
|
|||
|
|
k_autodeskDllInstallPath,
|
|||
|
|
k_autodeskFbxDll
|
|||
|
|
);
|
|||
|
|
Assert.That(autodeskDllFullPath, Does.Exist);
|
|||
|
|
var fileInfo = new FileInfo(autodeskDllFullPath);
|
|||
|
|
|
|||
|
|
// If the FBX SDK is copied over at runtime, the DLL filesize will
|
|||
|
|
// be ~350,000. If it isn't copied over it will be ~3500.
|
|||
|
|
// Putting the expected size as 10000 to allow for some buffer room.
|
|||
|
|
var expectedDllFileSize = 10000;
|
|||
|
|
if (dllExists)
|
|||
|
|
{
|
|||
|
|
Assert.That(fileInfo.Length, Is.GreaterThan(expectedDllFileSize));
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
Assert.That(fileInfo.Length, Is.LessThan(expectedDllFileSize));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var buildPath = report.summary.outputPath;
|
|||
|
|
|
|||
|
|
#if UNITY_EDITOR_OSX
|
|||
|
|
buildPath = Path.ChangeExtension(buildPath, "app");
|
|||
|
|
buildPath = Path.Combine(buildPath, "Contents", "MacOS");
|
|||
|
|
// on Unity 2018.4, the path to the executable is:
|
|||
|
|
// test.app/Contents/MacOS/test
|
|||
|
|
// whereas in later versions, the path is:
|
|||
|
|
// test.app/Contents/MacOS/{product_name}
|
|||
|
|
#if UNITY_2018_4
|
|||
|
|
buildPath = Path.Combine(buildPath, Path.GetFileNameWithoutExtension(k_buildName));
|
|||
|
|
#else // UNITY_2018_4
|
|||
|
|
buildPath = Path.Combine(buildPath, Application.productName);
|
|||
|
|
#endif // UNITY_2018_4
|
|||
|
|
#endif // UNITY_EDITOR_OSX
|
|||
|
|
|
|||
|
|
Process p = new Process();
|
|||
|
|
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
|
|||
|
|
p.StartInfo.FileName = buildPath;
|
|||
|
|
p.StartInfo.Arguments = "-batchmode -nographics";
|
|||
|
|
p.StartInfo.UseShellExecute = true;
|
|||
|
|
p.Start();
|
|||
|
|
|
|||
|
|
// Wait for 10 seconds for application to run.
|
|||
|
|
// If it doesn't finish by then something has probably
|
|||
|
|
// gone wrong, like the export script gave an error or wasn't
|
|||
|
|
// included in the build.
|
|||
|
|
bool hasExited = p.WaitForExit(10000);
|
|||
|
|
if (!hasExited)
|
|||
|
|
{
|
|||
|
|
p.Kill();
|
|||
|
|
Assert.Fail(string.Format("Process running {0} timed out", buildPath));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Check that the FBX was created
|
|||
|
|
var buildPluginFbxPath = Path.Combine(
|
|||
|
|
string.Format(k_buildPluginPath, buildPathWithoutExt),
|
|||
|
|
k_createdFbx
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
// Make sure the constraint is still set properly.
|
|||
|
|
// The constraint resets between this check and the previous.
|
|||
|
|
constraint = Does.Not.Exist;
|
|||
|
|
if (dllExists)
|
|||
|
|
{
|
|||
|
|
constraint = Does.Exist;
|
|||
|
|
}
|
|||
|
|
Assert.That(buildPluginFbxPath, constraint);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|