public void SharedTypes_CodeGen_Skips_Shared_Types_And_Properties() { CreateClientFilesTask task = null; var expectedOutputFiles = new[] { "ServerClassLib.g.cs", // generated "TestEntity.shared.cs", // via server project "ServerClassLib2.shared.cs" // via P2P }; try { task = CodeGenHelper.CreateClientFilesTaskInstance("STT", /*includeClientOutputAssembly*/ false); MockBuildEngine mockBuildEngine = task.BuildEngine as MockBuildEngine; // Work Item 199139: // We're stripping ServerClassLib2 from the reference assemblies since we cannot depend on Visual Studio // to reliably produce a full set of dependencies. This will force the assembly resolution code to // search for ServerClassLib2 during codegen. // Note: Our assembly resolution code is only exercised when running against an installed product. When // we're running locally, resolution occurs without error. task.ServerReferenceAssemblies = task.ServerReferenceAssemblies.Where(item => !item.ItemSpec.Contains("ServerClassLib2")).ToArray(); bool success = task.Execute(); if (!success) { Assert.Fail("CreateClientFilesTask failed:\r\n" + mockBuildEngine.ConsoleLogger.Errors); } ITaskItem[] outputFiles = task.OutputFiles.ToArray(); Assert.AreEqual(expectedOutputFiles.Length, outputFiles.Length); string generatedFile = CodeGenHelper.GetOutputFile(outputFiles, expectedOutputFiles[0]); string generatedCode = string.Empty; using (StreamReader t1 = new StreamReader(generatedFile)) { generatedCode = t1.ReadToEnd(); } ConsoleLogger logger = new ConsoleLogger(); logger.LogMessage(generatedCode); CodeGenHelper.AssertGenerated(generatedCode, "public sealed partial class TestEntity : Entity"); CodeGenHelper.AssertGenerated(generatedCode, "public string TheKey"); CodeGenHelper.AssertGenerated(generatedCode, "public int TheValue"); // This property is in shared code (via link) and should not have been generated CodeGenHelper.AssertNotGenerated(generatedCode, "public int ServerAndClientValue"); // The automatic property in shared code should have been generated because // the PDB would lack any info to know it was shared strictly at the source level CodeGenHelper.AssertGenerated(generatedCode, "public string AutomaticProperty"); // The server-only IsValid method should have emitted a comment warning it is not shared CodeGenHelper.AssertGenerated(generatedCode, "// [CustomValidationAttribute(typeof(ServerClassLib.TestValidatorServer), \"IsValid\")]"); // The TestDomainSharedService already had a matching TestDomainSharedContext DomainContext // pre-built into the client project. Verify we did *NOT* regenerate a 2nd copy // TODO: Do it // CodeGenHelper.AssertNotGenerated(generatedCode, "TestDomainShared"); // CodeGenHelper.AssertNotGenerated(generatedCode, "TestEntity2"); // Test that we get an informational message about skipping this shared domain context // TODO: Do it // string msg = string.Format(CultureInfo.CurrentCulture, Resource.Shared_DomainContext_Skipped, "TestDomainSharedService"); // TestHelper.AssertContainsMessages(mockBuildEngine.ConsoleLogger, msg); // This property is in shared code in a p2p referenced assembly and should not have been generated CodeGenHelper.AssertNotGenerated(generatedCode, "public int SharedProperty_CL2"); } finally { CodeGenHelper.DeleteTempFolder(task); } }
public void CleanClientFiles_Deletes_Generated_Files() { CreateClientFilesTask task = null; MockBuildEngine mockBuildEngine; try { // ==================================================== // Test setup -- generate code by calling Create task // ==================================================== task = CodeGenHelper.CreateClientFilesTaskInstance("CLRCF1", /*includeClientOutputAssembly*/ false); bool success = task.Execute(); if (!success) { mockBuildEngine = task.BuildEngine as MockBuildEngine; Assert.Fail("CreateClientFilesTask failed:\r\n" + mockBuildEngine.ConsoleLogger.Errors); } string generatedCodeOutputFolder = task.GeneratedCodePath; Assert.IsTrue(Directory.Exists(generatedCodeOutputFolder), "Expected task to have created " + generatedCodeOutputFolder); string[] files = Directory.GetFiles(generatedCodeOutputFolder); Assert.AreEqual(2, files.Length, "Code gen should have generated 3 code files"); string generatedFile = Path.Combine(generatedCodeOutputFolder, "ServerClassLib.g.cs"); Assert.IsTrue(File.Exists(generatedFile), "Expected task to have generated " + generatedFile); string copiedFile = Path.Combine(generatedCodeOutputFolder, "TestEntity.shared.cs"); Assert.IsTrue(File.Exists(copiedFile), "Expected task to have copied " + copiedFile); string outputFolder = task.OutputPath; Assert.IsTrue(Directory.Exists(outputFolder), "Expected task to have created " + outputFolder); files = Directory.GetFiles(outputFolder); string generatedFiles = string.Empty; foreach (string file in files) { generatedFiles += (file + Environment.NewLine); } Assert.AreEqual(5, files.Length, "Code gen should have generated this many ancillary files but instead saw:" + Environment.NewLine + generatedFiles); string fileList = Path.Combine(outputFolder, "ClientClassLib.SimpleEntityFiles.txt"); Assert.IsTrue(File.Exists(fileList), "Expected code gen to have created " + fileList + " but saw:" + Environment.NewLine + generatedFiles); string refList = Path.Combine(outputFolder, "ClientClassLib.SimpleEntityClientRefs.txt"); Assert.IsTrue(File.Exists(refList), "Expected code gen to have created " + refList + " but saw:" + Environment.NewLine + generatedFiles); refList = Path.Combine(outputFolder, "ClientClassLib.SimpleEntityServerRefs.txt"); Assert.IsTrue(File.Exists(refList), "Expected code gen to have created " + refList + " but saw:" + Environment.NewLine + generatedFiles); string sourceFileList = Path.Combine(outputFolder, "ClientClassLib.SimpleEntitySourceFiles.txt"); Assert.IsTrue(File.Exists(sourceFileList), "Expected code gen to have created " + sourceFileList + " but saw:" + Environment.NewLine + generatedFiles); string riaLinkList = Path.Combine(outputFolder, "ClientClassLib.SimpleEntityLinks.txt"); Assert.IsTrue(File.Exists(riaLinkList), "Expected code gen to have created " + riaLinkList + " but saw:" + Environment.NewLine + generatedFiles); // ========================================== // Main body of test -- the Clean // ========================================== // Step 1: instantiate Clean task instance and execute it, giving it same info as the Create task CleanClientFilesTask cleanTask = new CleanClientFilesTask(); mockBuildEngine = new MockBuildEngine(); cleanTask.BuildEngine = mockBuildEngine; cleanTask.OutputPath = task.OutputPath; cleanTask.GeneratedCodePath = task.GeneratedCodePath; cleanTask.ClientProjectPath = task.ClientProjectPath; success = cleanTask.Execute(); Assert.IsTrue(success, "Clean task returned false"); // No errors or warnings allowed TestHelper.AssertNoErrorsOrWarnings(mockBuildEngine.ConsoleLogger); // Step 2: validate files created above are gone // TODO, 244509: we no longer remove empty folder // Assert.IsFalse(Directory.Exists(generatedCodeOutputFolder), "Expected clean to have deleted " + generatedCodeOutputFolder); Assert.IsFalse(File.Exists(fileList), "Expected clean to have deleted " + fileList); Assert.IsFalse(File.Exists(refList), "Expected clean to have deleted " + refList); Assert.IsFalse(File.Exists(sourceFileList), "Expected clean to have deleted " + sourceFileList); Assert.IsFalse(File.Exists(riaLinkList), "Expected clean to have deleted " + riaLinkList); // Step 3: verify redundant clean does no harm and succeeds success = cleanTask.Execute(); Assert.IsTrue(success, "Clean task returned false"); } finally { CodeGenHelper.DeleteTempFolder(task); } }
public void ClientFilesTask_Safe_File_Copy() { CleanClientFilesTask task = new CleanClientFilesTask(); MockBuildEngine mockBuildEngine = new MockBuildEngine(); task.BuildEngine = mockBuildEngine; string tempFolder = CodeGenHelper.GenerateTempFolder(); try { // Do a simple copy with no special handling for attributes string file1 = Path.Combine(tempFolder, "File1.txt"); string file2 = Path.Combine(tempFolder, "File2.txt"); File.AppendAllText(file1, "stuff"); bool success = task.SafeFileCopy(file1, file2, /*isProjectFile*/ false); Assert.IsTrue(success, "SafeFileCopy reported failure"); Assert.IsTrue(File.Exists(file2), "File2 did not get created"); string content = File.ReadAllText(file2); Assert.AreEqual("stuff", content, "File2 did not get right content"); FileAttributes fa = File.GetAttributes(file2); Assert.AreEqual(0, (int)(fa & FileAttributes.ReadOnly), "Expected RO bit not to be set"); Assert.IsFalse(task.FilesWereWritten, "Should not have marked files as written"); File.Delete(file2); // Repeat, but ask for it to be treated as a project file success = task.SafeFileCopy(file1, file2, /*isProjectFile*/ true); Assert.IsTrue(success, "SafeFileCopy reported failure"); Assert.IsTrue(File.Exists(file2), "File2 did not get created"); content = File.ReadAllText(file2); Assert.AreEqual("stuff", content, "File2 did not get right content"); fa = File.GetAttributes(file2); Assert.AreEqual((int)FileAttributes.ReadOnly, (int)(fa & FileAttributes.ReadOnly), "Expected RO bit to be set"); Assert.IsTrue(task.FilesWereWritten, "Should have marked files as written"); task.SafeFileDelete(file2); string errorMessage = String.Empty; // Finally, try a clearly illegal copy and catch the error using (FileStream fs = new FileStream(file1, FileMode.Open, FileAccess.Read, FileShare.None)) { try { File.Copy(file1, file2, true); } catch (IOException iox) { errorMessage = iox.Message; } success = task.SafeFileCopy(file1, file2, /*isProjectFile*/ false); } Assert.IsFalse(success, "Expected illegal copy to report failure"); string expectedWarning = string.Format(CultureInfo.CurrentCulture, Resource.Failed_To_Copy_File, file1, file2, errorMessage); TestHelper.AssertContainsWarnings(mockBuildEngine.ConsoleLogger, expectedWarning); } finally { CodeGenHelper.DeleteTempFolder(tempFolder); } }
public void CleanClientFiles_Safe_File_Delete() { CleanClientFilesTask task = new CleanClientFilesTask(); MockBuildEngine mockBuildEngine = new MockBuildEngine(); task.BuildEngine = mockBuildEngine; // Test 1 -- null and empty deletes do nothing task.SafeFileDelete(null); TestHelper.AssertNoErrorsOrWarnings(mockBuildEngine.ConsoleLogger); task.SafeFileDelete(string.Empty); TestHelper.AssertNoErrorsOrWarnings(mockBuildEngine.ConsoleLogger); // Test 2 -- nonexistant file does nothing string fileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); Assert.IsFalse(File.Exists(fileName)); task.SafeFileDelete(fileName); TestHelper.AssertNoErrorsOrWarnings(mockBuildEngine.ConsoleLogger); // Test 3 -- verify delete on actual file succeeds without error File.WriteAllText(fileName, "stuff"); Assert.IsTrue(File.Exists(fileName)); task.SafeFileDelete(fileName); Assert.IsFalse(File.Exists(fileName)); TestHelper.AssertNoErrorsOrWarnings(mockBuildEngine.ConsoleLogger); // Test 4 -- verify delete on actual file with READONLY attribute set succeeds without error File.WriteAllText(fileName, "stuff"); File.SetAttributes(fileName, FileAttributes.ReadOnly); Assert.IsTrue(File.Exists(fileName)); task.SafeFileDelete(fileName); Assert.IsFalse(File.Exists(fileName)); TestHelper.AssertNoErrorsOrWarnings(mockBuildEngine.ConsoleLogger); // Test 5 -- attempt to delete while file is open. // Verify we log a warning containing the exception's message File.WriteAllText(fileName, "stuff"); Assert.IsTrue(File.Exists(fileName)); string errorMessage = null; using (StreamReader t1 = new StreamReader(fileName)) { // We do a delete here to capture the exception we expect the SafeFileDelete to encounter try { File.Delete(fileName); } catch (IOException ioe) { errorMessage = ioe.Message; } Assert.IsNotNull(errorMessage, "Expected File.Delete to throw IOException"); task.SafeFileDelete(fileName); } Assert.IsTrue(File.Exists(fileName)); File.Delete(fileName); string expectedWarning = string.Format(CultureInfo.CurrentCulture, Resource.Failed_To_Delete_File_Error, fileName, errorMessage); TestHelper.AssertContainsWarnings(mockBuildEngine.ConsoleLogger, expectedWarning); }