PageRenderTime 117ms CodeModel.GetById 5ms RepoModel.GetById 1ms app.codeStats 0ms

/Python/Tests/VSInterpretersTests/VSInterpretersTests.cs

https://gitlab.com/SplatoonModdingHub/PTVS
C# | 348 lines | 278 code | 54 blank | 16 comment | 7 complexity | a33c51e707ef0c036540731ed683fea8 MD5 | raw file
  1. // Python Tools for Visual Studio
  2. // Copyright(c) Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the License); you may not use
  6. // this file except in compliance with the License. You may obtain a copy of the
  7. // License at http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
  10. // OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
  11. // IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
  12. // MERCHANTABLITY OR NON-INFRINGEMENT.
  13. //
  14. // See the Apache Version 2.0 License for specific language governing
  15. // permissions and limitations under the License.
  16. using System;
  17. using System.Collections.Generic;
  18. using System.ComponentModel.Composition;
  19. using System.ComponentModel.Composition.Hosting;
  20. using System.IO;
  21. using System.Linq;
  22. using System.Reflection;
  23. using System.Text;
  24. using System.Text.RegularExpressions;
  25. using Microsoft.PythonTools;
  26. using Microsoft.PythonTools.Infrastructure;
  27. using Microsoft.PythonTools.Interpreter;
  28. using Microsoft.PythonTools.Parsing;
  29. using Microsoft.VisualStudio.Shell.Interop;
  30. using Microsoft.VisualStudio.TestTools.UnitTesting;
  31. using TestUtilities;
  32. using TestUtilities.Mocks;
  33. using TestUtilities.Python;
  34. namespace VSInterpretersTests {
  35. [TestClass]
  36. public class VSInterpretersTests {
  37. [ClassInitialize]
  38. public static void DoDeployment(TestContext context) {
  39. AssertListener.Initialize();
  40. PythonTestData.Deploy(includeTestData: false);
  41. }
  42. private static readonly List<string> _tempFiles = new List<string>();
  43. [ClassCleanup]
  44. public static void RemoveFiles() {
  45. foreach (var file in _tempFiles) {
  46. try {
  47. File.Delete(file);
  48. } catch {
  49. }
  50. }
  51. }
  52. private static string CompileString(string csharpCode, string outFile) {
  53. var provider = new Microsoft.CSharp.CSharpCodeProvider();
  54. var parameters = new System.CodeDom.Compiler.CompilerParameters {
  55. OutputAssembly = outFile,
  56. GenerateExecutable = false,
  57. GenerateInMemory = false
  58. };
  59. parameters.ReferencedAssemblies.Add(typeof(ExportAttribute).Assembly.Location);
  60. parameters.ReferencedAssemblies.Add(typeof(IPythonInterpreterFactoryProvider).Assembly.Location);
  61. var result = provider.CompileAssemblyFromSource(parameters, csharpCode);
  62. if (result.Errors.HasErrors) {
  63. foreach (var err in result.Errors) {
  64. Console.WriteLine(err);
  65. }
  66. }
  67. if (!File.Exists(outFile)) {
  68. Assert.Fail("Failed to compile {0}", outFile);
  69. }
  70. _tempFiles.Add(outFile);
  71. return outFile;
  72. }
  73. private static string FactoryProviderSuccessPath {
  74. get {
  75. var path = Path.ChangeExtension(Path.GetTempFileName(), "dll");
  76. if (File.Exists(path)) {
  77. return path;
  78. }
  79. return CompileString(@"
  80. using System;
  81. using System.Collections.Generic;
  82. using System.ComponentModel.Composition;
  83. using Microsoft.PythonTools.Interpreter;
  84. namespace FactoryProviderSuccess {
  85. [Export(typeof(IPythonInterpreterFactoryProvider))]
  86. [InterpreterFactoryId(""Success"")]
  87. public class FactoryProviderSuccess : IPythonInterpreterFactoryProvider {
  88. public IPythonInterpreterFactory GetInterpreterFactory(string id) {
  89. return null;
  90. }
  91. public IEnumerable<InterpreterConfiguration> GetInterpreterConfigurations() { yield break; }
  92. public event EventHandler InterpreterFactoriesChanged { add { } remove { } }
  93. public object GetProperty(string id, string propName) { return null; }
  94. }
  95. }", path);
  96. }
  97. }
  98. [TestMethod, Priority(1)]
  99. public void ProviderLoadLog_Success() {
  100. var path = FactoryProviderTypeLoadErrorPath;
  101. var catalogLog = new MockLogger();
  102. var container = InterpreterCatalog.CreateContainer(
  103. catalogLog,
  104. typeof(IInterpreterOptionsService).Assembly.Location,
  105. typeof(IInterpreterRegistryService).Assembly.Location,
  106. GetType().Assembly.Location
  107. );
  108. var log = container.GetExport<MockLogger>().Value;
  109. var service = container.GetExportedValue<IInterpreterOptionsService>();
  110. var registry = container.GetExportedValue<IInterpreterRegistryService>();
  111. foreach (var interpreter in registry.Configurations) {
  112. Console.WriteLine(interpreter);
  113. }
  114. foreach (var item in log.AllItems) {
  115. Console.WriteLine(item);
  116. }
  117. Assert.AreEqual(0, log.AllItems.Count);
  118. }
  119. [TestMethod, Priority(1)]
  120. public void ProviderLoadLog_FileNotFound() {
  121. var catalogLog = new MockLogger();
  122. var path = Path.ChangeExtension(Path.GetTempFileName(), "dll");
  123. File.Delete(path);
  124. Assert.IsFalse(File.Exists(path));
  125. var container = InterpreterCatalog.CreateContainer(
  126. catalogLog,
  127. typeof(IInterpreterOptionsService).Assembly.Location,
  128. typeof(IInterpreterRegistryService).Assembly.Location,
  129. GetType().Assembly.Location,
  130. path
  131. );
  132. var log = container.GetExport<MockLogger>().Value;
  133. var service = container.GetExportedValue<IInterpreterOptionsService>();
  134. var registry = container.GetExportedValue<IInterpreterRegistryService>();
  135. foreach (var interpreter in registry.Configurations) {
  136. Console.WriteLine(interpreter);
  137. }
  138. var error = catalogLog.AllItems.Single();
  139. Assert.IsTrue(error.StartsWith("Failed to load interpreter provider assembly"));
  140. Assert.AreNotEqual(-1, error.IndexOf("System.IO.FileNotFoundException: "));
  141. }
  142. private static string FactoryProviderCorruptPath {
  143. get {
  144. var path = Path.ChangeExtension(Path.GetTempFileName(), "dll");
  145. if (File.Exists(path)) {
  146. return path;
  147. }
  148. using (var src = new FileStream(FactoryProviderSuccessPath, FileMode.Open, FileAccess.Read))
  149. using (var dest = new FileStream(path, FileMode.Create, FileAccess.Write)) {
  150. var rnd = new Random();
  151. var buffer = new byte[4096];
  152. int read = src.Read(buffer, 0, buffer.Length);
  153. while (read > 0) {
  154. for (int count = 64; count > 0; --count) {
  155. var i = rnd.Next(buffer.Length);
  156. buffer[i] = (byte)(buffer[i] + rnd.Next(byte.MaxValue));
  157. }
  158. dest.Write(buffer, 0, read);
  159. read = src.Read(buffer, 0, buffer.Length);
  160. }
  161. }
  162. return path;
  163. }
  164. }
  165. [TestMethod, Priority(1)]
  166. public void ProviderLoadLog_CorruptImage() {
  167. var catalogLog = new MockLogger();
  168. var path = Path.ChangeExtension(Path.GetTempFileName(), "dll");
  169. File.Delete(path);
  170. Assert.IsFalse(File.Exists(path));
  171. var container = InterpreterCatalog.CreateContainer(
  172. catalogLog,
  173. typeof(IInterpreterOptionsService).Assembly.Location,
  174. typeof(IInterpreterRegistryService).Assembly.Location,
  175. GetType().Assembly.Location,
  176. FactoryProviderCorruptPath
  177. );
  178. var log = container.GetExport<MockLogger>().Value;
  179. var service = container.GetExportedValue<IInterpreterOptionsService>();
  180. var registry = container.GetExportedValue<IInterpreterRegistryService>();
  181. foreach (var interpreter in registry.Configurations) {
  182. Console.WriteLine(interpreter);
  183. }
  184. var error = catalogLog.AllItems.Single();
  185. Assert.IsTrue(error.StartsWith("Failed to load interpreter provider assembly"));
  186. Assert.AreNotEqual(-1, error.IndexOf("System.BadImageFormatException: "));
  187. }
  188. private static string FactoryProviderTypeLoadErrorPath {
  189. get {
  190. var path = Path.ChangeExtension(Path.GetTempFileName(), "dll");
  191. if (File.Exists(path)) {
  192. return path;
  193. }
  194. return CompileString(@"
  195. using System;
  196. using System.Collections.Generic;
  197. using System.ComponentModel.Composition;
  198. using Microsoft.PythonTools.Interpreter;
  199. namespace FactoryProviderTypeLoadException {
  200. [Export(typeof(IPythonInterpreterFactoryProvider))]
  201. [InterpreterFactoryId(""TypeError"")]
  202. public class FactoryProviderTypeLoadException : IPythonInterpreterFactoryProvider {
  203. static FactoryProviderTypeLoadException() {
  204. throw new Exception();
  205. }
  206. public IPythonInterpreterFactory GetInterpreterFactory(string id) {
  207. return null;
  208. }
  209. public IEnumerable<InterpreterConfiguration> GetInterpreterConfigurations() { yield break; }
  210. public event EventHandler InterpreterFactoriesChanged { add { } remove { } }
  211. public object GetProperty(string id, string propName) { return null; }
  212. }
  213. }", path);
  214. }
  215. }
  216. [TestMethod, Priority(1)]
  217. public void ProviderLoadLog_TypeLoadException() {
  218. var path = FactoryProviderTypeLoadErrorPath;
  219. var catalogLog = new MockLogger();
  220. var container = InterpreterCatalog.CreateContainer(
  221. catalogLog,
  222. FactoryProviderTypeLoadErrorPath,
  223. typeof(IInterpreterOptionsService).Assembly.Location,
  224. typeof(IInterpreterRegistryService).Assembly.Location,
  225. GetType().Assembly.Location
  226. );
  227. var log = container.GetExport<MockLogger>().Value;
  228. var service = container.GetExportedValue<IInterpreterOptionsService>();
  229. var registry = container.GetExportedValue<IInterpreterRegistryService>();
  230. foreach (var interpreter in registry.Configurations) {
  231. Console.WriteLine(interpreter);
  232. }
  233. bool isMatch = false;
  234. foreach (var msg in log.AllItems) {
  235. Console.WriteLine(msg);
  236. isMatch |= new Regex(@"Failed to get interpreter factory value:.*System\.ComponentModel\.Composition\.CompositionException").IsMatch(msg);
  237. }
  238. Assert.IsTrue(isMatch);
  239. Assert.IsNotNull(registry.Configurations.FirstOrDefault());
  240. }
  241. [TestMethod, Priority(1)]
  242. public void ProviderLoadLog_SuccessAndFailure() {
  243. var path = FactoryProviderTypeLoadErrorPath;
  244. var catalogLog = new MockLogger();
  245. var container = InterpreterCatalog.CreateContainer(
  246. catalogLog,
  247. FactoryProviderTypeLoadErrorPath,
  248. FactoryProviderSuccessPath,
  249. typeof(IInterpreterOptionsService).Assembly.Location,
  250. typeof(IInterpreterRegistryService).Assembly.Location,
  251. GetType().Assembly.Location
  252. );
  253. var log = container.GetExport<MockLogger>().Value;
  254. var service = container.GetExportedValue<IInterpreterOptionsService>();
  255. var registry = container.GetExportedValue<IInterpreterRegistryService>();
  256. foreach (var interpreter in registry.Configurations) {
  257. Console.WriteLine(interpreter);
  258. }
  259. foreach (var item in log.AllItems) {
  260. Console.WriteLine(item);
  261. }
  262. Assert.AreEqual(1, log.AllItems.Count);
  263. }
  264. [TestMethod, Priority(0)]
  265. public void InvalidInterpreterVersion() {
  266. try {
  267. var lv = new Version(1, 0).ToLanguageVersion();
  268. Assert.Fail("Expected InvalidOperationException");
  269. } catch (InvalidOperationException) {
  270. }
  271. try {
  272. InterpreterFactoryCreator.CreateInterpreterFactory(new InterpreterFactoryCreationOptions {
  273. Id = Guid.NewGuid().ToString(),
  274. LanguageVersionString = "1.0"
  275. });
  276. Assert.Fail("Expected ArgumentException");
  277. } catch (ArgumentException ex) {
  278. // Expect version number in message
  279. AssertUtil.Contains(ex.Message, "1.0");
  280. }
  281. }
  282. }
  283. [Export(typeof(IInterpreterLog))]
  284. [Export(typeof(MockLogger))]
  285. [PartCreationPolicy(CreationPolicy.Shared)]
  286. class MockLogger : ICatalogLog, IInterpreterLog {
  287. public readonly List<string> AllItems = new List<string>();
  288. public void Log(string msg) {
  289. AllItems.Add(msg);
  290. }
  291. }
  292. }