暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

TestResultXmlParser.cs 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text.RegularExpressions;
  6. using System.Xml.Linq;
  7. using Unity.PerformanceTesting.Data;
  8. using UnityEngine;
  9. namespace Unity.PerformanceTesting.Editor
  10. {
  11. /// <summary>
  12. /// Helper class to parse test runs into performance test runs.
  13. /// </summary>
  14. public class TestResultXmlParser
  15. {
  16. /// <summary>
  17. /// Parses performance test run from test run result xml.
  18. /// </summary>
  19. /// <param name="resultXmlFileName">Path to test results xml file.</param>
  20. /// <returns></returns>
  21. public Run GetPerformanceTestRunFromXml(string resultXmlFileName)
  22. {
  23. ValidateInput(resultXmlFileName);
  24. var xmlDocument = TryLoadResultXmlFile(resultXmlFileName);
  25. var performanceTestRun = TryParseXmlToPerformanceTestRun(xmlDocument);
  26. return performanceTestRun;
  27. }
  28. private void ValidateInput(string resultXmlFileName)
  29. {
  30. if (string.IsNullOrEmpty(resultXmlFileName))
  31. {
  32. Debug.LogWarning($"Test results path is null or empty.");
  33. }
  34. if (!File.Exists(resultXmlFileName))
  35. {
  36. Debug.LogWarning($"Test results file does not exists at path: {resultXmlFileName}");
  37. }
  38. }
  39. private XDocument TryLoadResultXmlFile(string resultXmlFileName)
  40. {
  41. try
  42. {
  43. return XDocument.Load(resultXmlFileName);
  44. }
  45. catch (Exception e)
  46. {
  47. var errMsg = $"Failed to load xml result file: {resultXmlFileName}";
  48. Debug.LogWarning($"{errMsg}\r\nException: {e.Message}\r\n{e.StackTrace}");
  49. }
  50. return null;
  51. }
  52. private Run TryParseXmlToPerformanceTestRun(XContainer xmlDocument)
  53. {
  54. var output = xmlDocument.Descendants("output").ToArray();
  55. if (!output.Any())
  56. {
  57. return null;
  58. }
  59. var run = DeserializeMetadata(output);
  60. DeserializeTestResults(output, run);
  61. return run;
  62. }
  63. private void DeserializeTestResults(IEnumerable<XElement> output, Run run)
  64. {
  65. foreach (var element in output)
  66. {
  67. foreach (var line in element.Value.Split('\n'))
  68. {
  69. var json = GetJsonFromHashtag("performancetestresult2", line);
  70. if (json == null)
  71. {
  72. continue;
  73. }
  74. var result = TryDeserializePerformanceTestResultJsonObject(json);
  75. if (result != null)
  76. {
  77. run.Results.Add(result);
  78. }
  79. }
  80. }
  81. }
  82. private Run DeserializeMetadata(IEnumerable<XElement> output)
  83. {
  84. foreach (var element in output)
  85. {
  86. var pattern = @"##performancetestruninfo2:(.+)\n";
  87. var regex = new Regex(pattern);
  88. var matches = regex.Match(element.Value);
  89. if (matches.Groups.Count == 0) continue;
  90. if (matches.Captures.Count == 0) continue;
  91. if (matches.Groups[1].Captures.Count > 1)
  92. {
  93. Debug.LogError("Performance test run had multiple hardware and player settings, there should only be one.");
  94. return null;
  95. }
  96. var json = matches.Groups[1].Value;
  97. if (string.IsNullOrEmpty(json))
  98. {
  99. Debug.LogError("Performance test run has incomplete hardware and player settings.");
  100. return null;
  101. }
  102. var result = TryDeserializePerformanceTestRunJsonObject(json);
  103. return result;
  104. }
  105. return null;
  106. }
  107. private PerformanceTestResult TryDeserializePerformanceTestResultJsonObject(string json)
  108. {
  109. try
  110. {
  111. return JsonUtility.FromJson<PerformanceTestResult>(json);
  112. }
  113. catch (Exception e)
  114. {
  115. var errMsg = $"Exception thrown while deserializing json string to PerformanceTestResult: {json}";
  116. Debug.LogWarning($"{errMsg}\r\nException: {e.Message}\r\n{e.StackTrace}");
  117. }
  118. return null;
  119. }
  120. private Run TryDeserializePerformanceTestRunJsonObject(string json)
  121. {
  122. try
  123. {
  124. return JsonUtility.FromJson<Run>(json);
  125. }
  126. catch (Exception e)
  127. {
  128. var errMsg = $"Exception thrown while deserializing json string to PerformanceTestRun: {json}";
  129. Debug.LogWarning($"{errMsg}\r\nException: {e.Message}\r\n{e.StackTrace}");
  130. }
  131. return null;
  132. }
  133. private string GetJsonFromHashtag(string tag, string line)
  134. {
  135. if (!line.Contains($"##{tag}:")) return null;
  136. var jsonStart = line.IndexOf('{');
  137. var openBrackets = 0;
  138. var stringIndex = jsonStart;
  139. while (openBrackets > 0 || stringIndex == jsonStart)
  140. {
  141. var character = line[stringIndex];
  142. switch (character)
  143. {
  144. case '{':
  145. openBrackets++;
  146. break;
  147. case '}':
  148. openBrackets--;
  149. break;
  150. }
  151. stringIndex++;
  152. }
  153. var jsonEnd = stringIndex;
  154. return line.Substring(jsonStart, jsonEnd - jsonStart);
  155. }
  156. }
  157. }