PageRenderTime 57ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/Python/Tests/Analysis/CompletionDBTest.cs

https://gitlab.com/SplatoonModdingHub/PTVS
C# | 394 lines | 301 code | 59 blank | 34 comment | 6 complexity | 02de6bcbf9cd32416631e50599537921 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. extern alias analysis;
  17. using System;
  18. using System.Collections.Generic;
  19. using System.Diagnostics;
  20. using System.IO;
  21. using System.Linq;
  22. using System.Reflection;
  23. using System.Text;
  24. using System.Threading.Tasks;
  25. using Microsoft.PythonTools;
  26. using Microsoft.PythonTools.Infrastructure;
  27. using Microsoft.PythonTools.Intellisense;
  28. using Microsoft.PythonTools.Interpreter;
  29. using Microsoft.PythonTools.Interpreter.Default;
  30. using Microsoft.PythonTools.Parsing;
  31. using Microsoft.VisualStudio.TestTools.UnitTesting;
  32. using TestUtilities;
  33. using TestUtilities.Python;
  34. using Assert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
  35. namespace PythonToolsTests {
  36. [TestClass]
  37. public class CompletionDBTest {
  38. [ClassInitialize]
  39. public static void DoDeployment(TestContext context) {
  40. AssertListener.Initialize();
  41. PythonTestData.Deploy();
  42. }
  43. private void TestOpen(PythonVersion path) {
  44. path.AssertInstalled();
  45. Console.WriteLine(path.InterpreterPath);
  46. Guid testId = Guid.NewGuid();
  47. var testDir = TestData.GetTempPath(testId.ToString());
  48. // run the scraper
  49. using (var proc = ProcessOutput.RunHiddenAndCapture(
  50. path.InterpreterPath,
  51. TestData.GetPath("PythonScraper.py"),
  52. testDir,
  53. TestData.GetPath("CompletionDB")
  54. )) {
  55. Console.WriteLine("Command: " + proc.Arguments);
  56. proc.Wait();
  57. // it should succeed
  58. Console.WriteLine("**Stdout**");
  59. foreach (var line in proc.StandardOutputLines) {
  60. Console.WriteLine(line);
  61. }
  62. Console.WriteLine("");
  63. Console.WriteLine("**Stdout**");
  64. foreach (var line in proc.StandardErrorLines) {
  65. Console.WriteLine(line);
  66. }
  67. Assert.AreEqual(0, proc.ExitCode, "Bad exit code: " + proc.ExitCode);
  68. }
  69. // perform some basic validation
  70. dynamic builtinDb = Unpickle.Load(new FileStream(Path.Combine(testDir, path.Version.Is3x() ? "builtins.idb" : "__builtin__.idb"), FileMode.Open, FileAccess.Read));
  71. if (path.Version.Is2x()) { // no open in 3.x
  72. foreach (var overload in builtinDb["members"]["open"]["value"]["overloads"]) {
  73. Assert.AreEqual("__builtin__", overload["ret_type"][0][0]);
  74. Assert.AreEqual("file", overload["ret_type"][0][1]);
  75. }
  76. if (!path.InterpreterPath.Contains("Iron")) {
  77. // http://pytools.codeplex.com/workitem/799
  78. var arr = (IList<object>)builtinDb["members"]["list"]["value"]["members"]["__init__"]["value"]["overloads"];
  79. Assert.AreEqual(
  80. "args",
  81. ((dynamic)(arr[0]))["args"][1]["name"]
  82. );
  83. }
  84. }
  85. if (!path.InterpreterPath.Contains("Iron")) {
  86. dynamic itertoolsDb = Unpickle.Load(new FileStream(Path.Combine(testDir, "itertools.idb"), FileMode.Open, FileAccess.Read));
  87. var tee = itertoolsDb["members"]["tee"]["value"];
  88. var overloads = tee["overloads"];
  89. var nArg = overloads[0]["args"][1];
  90. Assert.AreEqual("n", nArg["name"]);
  91. Assert.AreEqual("2", nArg["default_value"]);
  92. dynamic sreDb = Unpickle.Load(new FileStream(Path.Combine(testDir, "_sre.idb"), FileMode.Open, FileAccess.Read));
  93. var members = sreDb["members"];
  94. Assert.IsTrue(members.ContainsKey("SRE_Pattern"));
  95. Assert.IsTrue(members.ContainsKey("SRE_Match"));
  96. }
  97. Console.WriteLine("Passed: {0}", path.InterpreterPath);
  98. }
  99. [TestMethod, Priority(1)]
  100. public void TestOpen25() {
  101. TestOpen(PythonPaths.Python25 ?? PythonPaths.Python25_x64);
  102. }
  103. [TestMethod, Priority(1)]
  104. public void TestOpen26() {
  105. TestOpen(PythonPaths.Python26 ?? PythonPaths.Python26_x64);
  106. }
  107. [TestMethod, Priority(1)]
  108. public void TestOpen27() {
  109. TestOpen(PythonPaths.Python27 ?? PythonPaths.Python27_x64);
  110. }
  111. [TestMethod, Priority(1)]
  112. public void TestOpen30() {
  113. TestOpen(PythonPaths.Python30 ?? PythonPaths.Python30_x64);
  114. }
  115. [TestMethod, Priority(1)]
  116. public void TestOpen31() {
  117. TestOpen(PythonPaths.Python31 ?? PythonPaths.Python31_x64);
  118. }
  119. [TestMethod, Priority(1)]
  120. public void TestOpen32() {
  121. TestOpen(PythonPaths.Python32 ?? PythonPaths.Python32_x64);
  122. }
  123. [TestMethod, Priority(1)]
  124. public void TestOpen33() {
  125. TestOpen(PythonPaths.Python33 ?? PythonPaths.Python33_x64);
  126. }
  127. [TestMethod, Priority(1)]
  128. public void TestOpen34() {
  129. TestOpen(PythonPaths.Python34 ?? PythonPaths.Python34_x64);
  130. }
  131. [TestMethod, Priority(1)]
  132. public void TestOpen35() {
  133. TestOpen(PythonPaths.Python35 ?? PythonPaths.Python35_x64);
  134. }
  135. [TestMethod, Priority(1)]
  136. public void TestPthFiles() {
  137. var outputPath = TestData.GetTempPath(randomSubPath: true);
  138. Console.WriteLine("Writing to: " + outputPath);
  139. // run the analyzer
  140. using (var output = ProcessOutput.RunHiddenAndCapture("Microsoft.PythonTools.Analyzer.exe",
  141. "/lib", TestData.GetPath(@"TestData\PathStdLib"),
  142. "/version", "2.7",
  143. "/outdir", outputPath,
  144. "/indir", TestData.GetPath("CompletionDB"),
  145. "/log", "AnalysisLog.txt")) {
  146. output.Wait();
  147. Console.WriteLine("* Stdout *");
  148. foreach (var line in output.StandardOutputLines) {
  149. Console.WriteLine(line);
  150. }
  151. Console.WriteLine("* Stderr *");
  152. foreach (var line in output.StandardErrorLines) {
  153. Console.WriteLine(line);
  154. }
  155. Assert.AreEqual(0, output.ExitCode);
  156. }
  157. File.Copy(TestData.GetPath(@"CompletionDB\__builtin__.idb"), Path.Combine(outputPath, "__builtin__.idb"));
  158. var fact = InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(new Version(2, 7));
  159. var paths = new List<string> { outputPath };
  160. paths.AddRange(Directory.EnumerateDirectories(outputPath));
  161. var typeDb = new PythonTypeDatabase(fact, paths);
  162. var module = typeDb.GetModule("SomeLib");
  163. Assert.IsNotNull(module, "Could not import SomeLib");
  164. var fobMod = typeDb.GetModule("SomeLib.fob");
  165. Assert.IsNotNull(fobMod, "Could not import SomeLib.fob");
  166. var cClass = ((IPythonModule)fobMod).GetMember(null, "C");
  167. Assert.IsNotNull(cClass, "Could not get SomeLib.fob.C");
  168. Assert.AreEqual(PythonMemberType.Class, cClass.MemberType);
  169. }
  170. [TestMethod, Priority(1)]
  171. public void PydInPackage() {
  172. PythonPaths.Python27.AssertInstalled();
  173. var outputPath = TestData.GetTempPath(randomSubPath: true);
  174. Console.WriteLine("Writing to: " + outputPath);
  175. // run the analyzer
  176. using (var output = ProcessOutput.RunHiddenAndCapture("Microsoft.PythonTools.Analyzer.exe",
  177. "/python", PythonPaths.Python27.InterpreterPath,
  178. "/lib", TestData.GetPath(@"TestData\PydStdLib"),
  179. "/version", "2.7",
  180. "/outdir", outputPath,
  181. "/indir", TestData.GetPath("CompletionDB"),
  182. "/log", "AnalysisLog.txt")) {
  183. output.Wait();
  184. Console.WriteLine("* Stdout *");
  185. foreach (var line in output.StandardOutputLines) {
  186. Console.WriteLine(line);
  187. }
  188. Console.WriteLine("* Stderr *");
  189. foreach (var line in output.StandardErrorLines) {
  190. Console.WriteLine(line);
  191. }
  192. Assert.AreEqual(0, output.ExitCode);
  193. }
  194. var fact = InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(new Version(2, 7));
  195. var paths = new List<string> { outputPath };
  196. paths.AddRange(Directory.EnumerateDirectories(outputPath));
  197. var typeDb = new PythonTypeDatabase(fact, paths);
  198. var module = typeDb.GetModule("Package.winsound");
  199. Assert.IsNotNull(module, "Package.winsound was not analyzed");
  200. var package = typeDb.GetModule("Package");
  201. Assert.IsNotNull(package, "Could not import Package");
  202. var member = package.GetMember(null, "winsound");
  203. Assert.IsNotNull(member, "Could not get member Package.winsound");
  204. Assert.AreSame(module, member);
  205. module = typeDb.GetModule("Package._testcapi");
  206. Assert.IsNotNull(module, "Package._testcapi was not analyzed");
  207. package = typeDb.GetModule("Package");
  208. Assert.IsNotNull(package, "Could not import Package");
  209. member = package.GetMember(null, "_testcapi");
  210. Assert.IsNotNull(member, "Could not get member Package._testcapi");
  211. Assert.IsNotInstanceOfType(member, typeof(CPythonMultipleMembers));
  212. Assert.AreSame(module, member);
  213. module = typeDb.GetModule("Package.select");
  214. Assert.IsNotNull(module, "Package.select was not analyzed");
  215. package = typeDb.GetModule("Package");
  216. Assert.IsNotNull(package, "Could not import Package");
  217. member = package.GetMember(null, "select");
  218. Assert.IsNotNull(member, "Could not get member Package.select");
  219. Assert.IsInstanceOfType(member, typeof(CPythonMultipleMembers));
  220. var mm = (CPythonMultipleMembers)member;
  221. AssertUtil.ContainsExactly(mm.Members.Select(m => m.MemberType),
  222. PythonMemberType.Module,
  223. PythonMemberType.Constant,
  224. PythonMemberType.Class
  225. );
  226. Assert.IsNotNull(mm.Members.Contains(module));
  227. try {
  228. // Only clean up if the test passed
  229. Directory.Delete(outputPath, true);
  230. } catch { }
  231. }
  232. /// <summary>
  233. /// Checks that members removed or introduced in later versions show up or don't in
  234. /// earlier versions as appropriate.
  235. /// </summary>
  236. [TestMethod, Priority(1)]
  237. public void VersionedSharedDatabase() {
  238. var twoFive = PythonTypeDatabase.CreateDefaultTypeDatabase(new Version(2, 5));
  239. var twoSix = PythonTypeDatabase.CreateDefaultTypeDatabase(new Version(2, 6));
  240. var twoSeven = PythonTypeDatabase.CreateDefaultTypeDatabase(new Version(2, 7));
  241. var threeOh = PythonTypeDatabase.CreateDefaultTypeDatabase(new Version(3, 0));
  242. var threeOne = PythonTypeDatabase.CreateDefaultTypeDatabase(new Version(3, 1));
  243. var threeTwo = PythonTypeDatabase.CreateDefaultTypeDatabase(new Version(3, 2));
  244. // new in 2.6
  245. Assert.AreEqual(null, twoFive.BuiltinModule.GetAnyMember("bytearray"));
  246. foreach (var version in new[] { twoSix, twoSeven, threeOh, threeOne, threeTwo }) {
  247. Assert.AreNotEqual(version, version.BuiltinModule.GetAnyMember("bytearray"));
  248. }
  249. // new in 2.7
  250. Assert.AreEqual(null, twoSix.BuiltinModule.GetAnyMember("memoryview"));
  251. foreach (var version in new[] { twoSeven, threeOh, threeOne, threeTwo }) {
  252. Assert.AreNotEqual(version, version.BuiltinModule.GetAnyMember("memoryview"));
  253. }
  254. // not in 3.0
  255. foreach (var version in new[] { twoFive, twoSix, twoSeven }) {
  256. Assert.AreNotEqual(null, version.BuiltinModule.GetAnyMember("StandardError"));
  257. }
  258. foreach (var version in new[] { threeOh, threeOne, threeTwo }) {
  259. Assert.AreEqual(null, version.BuiltinModule.GetAnyMember("StandardError"));
  260. }
  261. // new in 3.0
  262. foreach (var version in new[] { twoFive, twoSix, twoSeven }) {
  263. Assert.AreEqual(null, version.BuiltinModule.GetAnyMember("exec"));
  264. Assert.AreEqual(null, version.BuiltinModule.GetAnyMember("print"));
  265. }
  266. foreach (var version in new[] { threeOh, threeOne, threeTwo }) {
  267. Assert.AreNotEqual(null, version.BuiltinModule.GetAnyMember("exec"));
  268. Assert.AreNotEqual(null, version.BuiltinModule.GetAnyMember("print"));
  269. }
  270. // new in 3.1
  271. foreach (var version in new[] { twoFive, twoSix, twoSeven, threeOh }) {
  272. Assert.AreEqual(null, version.GetModule("sys").GetMember(null, "int_info"));
  273. }
  274. foreach (var version in new[] { threeOne, threeTwo }) {
  275. Assert.AreNotEqual(null, version.GetModule("sys").GetMember(null, "int_info"));
  276. }
  277. // new in 3.2
  278. foreach (var version in new[] { twoFive, twoSix, twoSeven, threeOh, threeOne }) {
  279. Assert.AreEqual(null, version.GetModule("sys").GetMember(null, "setswitchinterval"));
  280. }
  281. foreach (var version in new[] { threeTwo }) {
  282. Assert.AreNotEqual(null, version.GetModule("sys").GetMember(null, "setswitchinterval"));
  283. }
  284. }
  285. [TestMethod, Priority(2)]
  286. public void CheckObsoleteGenerateFunction() {
  287. var path = PythonPaths.Versions.LastOrDefault(p => p != null && p.IsCPython);
  288. path.AssertInstalled();
  289. var factory = InterpreterFactoryCreator.CreateInterpreterFactory(
  290. new InterpreterConfiguration(
  291. path.Id,
  292. "Test Interpreter",
  293. path.PrefixPath,
  294. path.InterpreterPath,
  295. path.InterpreterPath,
  296. path.LibPath,
  297. "PYTHONPATH",
  298. path.Isx64 ? ProcessorArchitecture.Amd64 : ProcessorArchitecture.X86,
  299. path.Version.ToVersion()
  300. ),
  301. new InterpreterFactoryCreationOptions {
  302. WatchLibraryForNewModules = false
  303. }
  304. );
  305. var tcs = new TaskCompletionSource<int>();
  306. var beforeProc = Process.GetProcessesByName("Microsoft.PythonTools.Analyzer");
  307. var request = new PythonTypeDatabaseCreationRequest {
  308. Factory = factory,
  309. OutputPath = TestData.GetTempPath(randomSubPath: true),
  310. SkipUnchanged = true,
  311. OnExit = tcs.SetResult
  312. };
  313. Console.WriteLine("OutputPath: {0}", request.OutputPath);
  314. #pragma warning disable 618
  315. PythonTypeDatabase.Generate(request);
  316. #pragma warning restore 618
  317. int expected = 0;
  318. if (!tcs.Task.Wait(TimeSpan.FromMinutes(1.0))) {
  319. var proc = Process.GetProcessesByName("Microsoft.PythonTools.Analyzer")
  320. .Except(beforeProc)
  321. .ToArray();
  322. // Ensure we actually started running
  323. Assert.AreNotEqual(0, proc.Length, "Process is not running");
  324. expected = -1;
  325. // Kill the process
  326. foreach (var p in proc) {
  327. Console.WriteLine("Killing process {0}", p.Id);
  328. p.Kill();
  329. }
  330. Assert.IsTrue(tcs.Task.Wait(TimeSpan.FromMinutes(1.0)), "Process did not die");
  331. }
  332. Assert.AreEqual(expected, tcs.Task.Result, "Incorrect exit code");
  333. }
  334. }
  335. }