No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BurstMethodTreeViewTests.cs 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. using System;
  2. using NUnit.Framework;
  3. using Unity.Burst.Editor;
  4. using UnityEngine.TestTools;
  5. using Unity.Burst;
  6. using Unity.Jobs;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using UnityEditor.IMGUI.Controls;
  10. using UnityEngine;
  11. public class BurstMethodTreeViewTests
  12. {
  13. /*
  14. Consists of a tree looking like:
  15. Root
  16. └►BurstMethodTreeViewTests
  17. │►Job1
  18. │ │
  19. │ └►TestMethod1
  20. │►Job2
  21. │ │
  22. │ └►TestMethod1
  23. │►Job3
  24. │ │
  25. │ └►TestMethod1(System.IntPtr)
  26. │►Job4
  27. │ │
  28. │ └►TestMethod1
  29. │►Job5 - (IJob)
  30. │►NameOverlapping
  31. │ │
  32. │ └►NameOverlap(int,int)
  33. └►Job5 - (IJob)
  34. */
  35. private BurstMethodTreeView _treeView;
  36. private List<BurstCompileTarget> _targets;
  37. private string _filter;
  38. [SetUp]
  39. public void SetUp()
  40. {
  41. _filter = string.Empty;
  42. _treeView = new BurstMethodTreeView(
  43. new TreeViewState(),
  44. () => _filter,
  45. () => (true, true)
  46. );
  47. string name = "TestMethod1";
  48. _targets = new List<BurstCompileTarget>
  49. {
  50. new BurstCompileTarget(typeof(Job1).GetMethod(name), typeof(Job1), null, true),
  51. new BurstCompileTarget(typeof(Job2).GetMethod(name), typeof(Job2), null, true),
  52. new BurstCompileTarget(typeof(Job3).GetMethod(name), typeof(Job3), null, true),
  53. new BurstCompileTarget(typeof(Job4).GetMethod(name), typeof(Job4), null, true),
  54. new BurstCompileTarget(typeof(NameOverlapping).GetMethod(nameof(NameOverlapping.NameOverlap)), typeof(NameOverlapping), null, true),
  55. new BurstCompileTarget(typeof(Job5).GetMethod("Execute"), typeof(Job5), typeof(IJob), false),
  56. };
  57. }
  58. private void testEquality<T>(List<T> exp, List<T> act)
  59. {
  60. Assert.AreEqual(exp.Count, act.Count, "List length did not match.");
  61. if (exp is List<TreeViewItem> elist && act is List<TreeViewItem> alist)
  62. {
  63. for (int i = 0; i < act.Count; i++)
  64. {
  65. Assert.IsTrue(alist[i].CompareTo(elist[i]) == 0,
  66. $"expected: {elist[i].displayName}\nactual: {alist[i].displayName}");
  67. }
  68. }
  69. else
  70. {
  71. for (int i = 0; i < act.Count; i++)
  72. {
  73. Assert.AreEqual(exp[i], act[i], $"list items did not match at index {i}");
  74. }
  75. }
  76. }
  77. [Test]
  78. public void ProcessNewItemTest()
  79. {
  80. // Test for method containing . in name:
  81. List<StringSlice> oldNameSpace = new List<StringSlice>();
  82. int idJ = 0;
  83. var (idn, newtarget, nameSpace) =
  84. BurstMethodTreeView.ProcessNewItem(0, ++idJ, _targets[2], oldNameSpace);
  85. Assert.AreEqual(-2, idn);
  86. var expTargets = new List<TreeViewItem>
  87. {
  88. new TreeViewItem(-1, 0, $"{nameof(BurstMethodTreeViewTests)}"),
  89. new TreeViewItem(-2,1,$"{nameof(Job3)}"),
  90. new TreeViewItem(1, 2, "TestMethod1(System.IntPtr)")
  91. };
  92. var expNS = new List<StringSlice>
  93. {
  94. new StringSlice($"{nameof(BurstMethodTreeViewTests)}"),
  95. new StringSlice($"{nameof(Job3)}")
  96. };
  97. testEquality(expTargets, newtarget);
  98. testEquality(expNS, nameSpace);
  99. // Test for method with . and with thing in namespace:
  100. (idn, newtarget, nameSpace) = BurstMethodTreeView.ProcessNewItem(idn, ++idJ, _targets[2], nameSpace);
  101. Assert.AreEqual(-2, idn); // no new non-leafs added.
  102. expTargets = new List<TreeViewItem>
  103. {
  104. new TreeViewItem(2, 2, "TestMethod1(System.IntPtr)")
  105. };
  106. testEquality(expTargets, newtarget);
  107. testEquality(expNS, nameSpace);
  108. // Test with IJob instead of static method:
  109. (idn, newtarget, nameSpace) = BurstMethodTreeView.ProcessNewItem(0, ++idJ, _targets[5], oldNameSpace);
  110. Assert.AreEqual(-1, idn); // no new non-leafs added.
  111. expTargets = new List<TreeViewItem>
  112. {
  113. new TreeViewItem(-1, 0, $"{nameof(BurstMethodTreeViewTests)}"),
  114. new TreeViewItem(2, 2, $"{nameof(Job5)} - ({nameof(IJob)})")
  115. };
  116. expNS = new List<StringSlice> { new StringSlice($"{nameof(BurstMethodTreeViewTests)}"), };
  117. testEquality(expTargets, newtarget);
  118. testEquality(expNS, nameSpace);
  119. }
  120. private readonly (string, string[])[] _findNameSpacesTestInput =
  121. {
  122. ("Burst.Compiler.IL.Tests.TestGenerics+GenericStructOuter2`2+GenericStructInner`1[[Burst.Compiler.IL.Tests.TestGenerics+MyValueData1, Unity.Burst.Tests.UnitTests, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],[Burst.Compiler.IL.Tests.TestGenerics+MyValueData2, Unity.Burst.Tests.UnitTests, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null],[Burst.Compiler.IL.Tests.TestGenerics+MyValueData2, Unity.Burst.Tests.UnitTests, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]",
  123. new []{ "Burst.Compiler.IL.Tests.TestGenerics", "GenericStructOuter2`2" }),
  124. ("NameOverlapping+NameOverlap(int a, int b)",
  125. new []{ "NameOverlapping" }),
  126. };
  127. [Test]
  128. public void ExtractNameSpacesTest()
  129. {
  130. foreach (var (displayName, expectedNameSpaces) in _findNameSpacesTestInput)
  131. {
  132. var (nameSpaces, methodNameIdx) = BurstMethodTreeView.ExtractNameSpaces(displayName);
  133. int len = expectedNameSpaces.Length;
  134. Assert.AreEqual(len, nameSpaces.Count, "Amount of namespaces found is wrong.");
  135. int expectedNSIdx = 0;
  136. for (int i = 0; i < len; i++)
  137. {
  138. expectedNSIdx += expectedNameSpaces[i].Length + 1;
  139. Assert.AreEqual(expectedNameSpaces[i], nameSpaces[i].ToString(), "Wrong namespace name retrieval.");
  140. }
  141. Assert.AreEqual(expectedNSIdx, methodNameIdx, "Wrong index of method name.");
  142. }
  143. }
  144. [Test]
  145. public void InitializeTest()
  146. {
  147. int numNodes = 1 + _targets.Count; // Root + internal nodes.
  148. _treeView.Initialize(_targets, false);
  149. LogAssert.NoUnexpectedReceived();
  150. Assert.AreEqual(numNodes, _treeView.GetExpanded().Count, "All menu items should be expanded");
  151. _treeView.SetExpanded(-2, false);
  152. Assert.AreEqual(numNodes-1, _treeView.GetExpanded().Count, "First Job should be folded.");
  153. _treeView.Initialize(_targets, true);
  154. LogAssert.NoUnexpectedReceived();
  155. Assert.AreEqual(numNodes-1, _treeView.GetExpanded().Count);
  156. }
  157. [Test]
  158. public void BuildRootTest()
  159. {
  160. _treeView.Initialize(_targets, false);
  161. LogAssert.NoUnexpectedReceived();
  162. int dexp = 0;
  163. int idNexp = -1;
  164. int idLexp = 1;
  165. foreach (TreeViewItem twi in _treeView.GetRows())
  166. {
  167. Assert.AreEqual(dexp++, twi.depth, $"Depth of item \"{twi}\" was wrong.");
  168. if (dexp > 2) { dexp = 1; }
  169. Assert.AreEqual(twi.hasChildren ? idNexp-- : idLexp++, twi.id, $"ID of item \"{twi}\" was wrong.");
  170. }
  171. }
  172. [Test]
  173. public void GetSelection()
  174. {
  175. _treeView.Initialize(_targets, false);
  176. LogAssert.NoUnexpectedReceived();
  177. IList<int> actual = _treeView.GetSelection();
  178. Assert.IsEmpty(actual, "Selection count wrong.");
  179. _treeView.SelectAllRows();
  180. actual = _treeView.GetSelection();
  181. Assert.IsEmpty(actual, "Selection count wrong. Multirow selection not allowed.");
  182. _treeView.SetSelection(new List<int> { -2 });
  183. actual = _treeView.GetSelection();
  184. Assert.AreEqual(0, actual.Count, "Selection count wrong. Label selection not allowed.");
  185. _treeView.SetSelection(new List<int> { 1 });
  186. actual = _treeView.GetSelection();
  187. Assert.AreEqual(1, actual.Count, "Selection count wrong.");
  188. Assert.AreEqual(1, actual[0], "Selection ID wrong.");
  189. }
  190. [Test]
  191. public void TrySelectByDisplayNameTest()
  192. {
  193. const string name = "BurstMethodTreeViewTests.Job1.TestMethod1()";
  194. _treeView.Initialize(_targets, false);
  195. LogAssert.NoUnexpectedReceived();
  196. Assert.IsFalse(_treeView.TrySelectByDisplayName("Not present"));
  197. Assert.IsTrue(_treeView.TrySelectByDisplayName(name), "TreeView Could not find method.");
  198. }
  199. [Test]
  200. public void ProcessEntireTestProject()
  201. {
  202. // Make it filter out some jobs:
  203. _filter = "Unity";
  204. // Get all target jobs!
  205. var assemblyList = BurstReflection.EditorAssembliesThatCanPossiblyContainJobs;
  206. var result = BurstReflection.FindExecuteMethods(assemblyList, BurstReflectionAssemblyOptions.None).CompileTargets;
  207. result.Sort((left, right) => string.Compare(left.GetDisplayName(), right.GetDisplayName(), StringComparison.Ordinal));
  208. // Initialize the tree view:
  209. _treeView.Initialize(result, false);
  210. LogAssert.NoUnexpectedReceived();
  211. // Check if everything is good and ready:
  212. var visibleJobs = _treeView.GetRows().Where(twi => !twi.hasChildren);
  213. foreach (TreeViewItem twi in visibleJobs)
  214. {
  215. var actual = result[twi.id - 1];
  216. var expected = twi.displayName;
  217. Assert.IsTrue(actual.GetDisplayName().Contains(expected), $"Retrieved the wrong target base on id.\nGot \"{actual.GetDisplayName()}\"\nExpected \"{expected}\"");
  218. }
  219. }
  220. [BurstCompile]
  221. private struct Job1
  222. {
  223. [BurstCompile]
  224. public static void TestMethod1() { }
  225. }
  226. [BurstCompile]
  227. private struct Job2
  228. {
  229. [BurstCompile]
  230. public static void TestMethod1() { }
  231. }
  232. [BurstCompile]
  233. private struct Job3
  234. {
  235. [BurstCompile]
  236. public static void TestMethod1(System.IntPtr ptr) { }
  237. }
  238. [BurstCompile]
  239. private struct Job4
  240. {
  241. [BurstCompile]
  242. public static void TestMethod1() { }
  243. }
  244. [BurstCompile]
  245. private struct Job5 : IJob
  246. {
  247. public void Execute() { }
  248. }
  249. [BurstCompile]
  250. private class NameOverlapping
  251. {
  252. [BurstCompile]
  253. public static int NameOverlap(int a, int b) => a + b;
  254. }
  255. }