From 7b1bb025dea1d1e9e144cce0dcbba2d86f053b8f Mon Sep 17 00:00:00 2001 From: Bevan Weiss Date: Tue, 18 Jun 2024 19:03:40 +1000 Subject: CreateGroups additions Signed-off-by: Bevan Weiss --- src/test/burn/WixTestTools/UserGroupVerifier.cs | 198 +++++++++++++++ .../ProductA/ProductA.wixproj | 13 + .../UtilExtensionGroupTests/ProductA/product.wxs | 25 ++ .../ProductAddCommentToExistingGroup.wixproj | 13 + .../ProductAddCommentToExistingGroup/product.wxs | 23 ++ .../ProductCommentDelete.wixproj | 13 + .../ProductCommentDelete/product.wxs | 18 ++ .../ProductCommentFail/ProductCommentFail.wixproj | 13 + .../ProductCommentFail/product_fail.wxs | 22 ++ .../ProductFail/ProductFail.wixproj | 13 + .../ProductFail/product_fail.wxs | 29 +++ .../ProductFailIfExists/FailIfExists.wxs | 18 ++ .../ProductFailIfExists.wixproj | 13 + .../ProductNestedGroups.wixproj | 13 + .../ProductNestedGroups/product.wxs | 33 +++ .../ProductNewGroupWithComment.wixproj | 13 + .../ProductNewGroupWithComment/product.wxs | 23 ++ .../ProductNonVitalGroup/NonVitalUserGroup.wxs | 19 ++ .../ProductNonVitalUserGroup.wixproj | 13 + .../ProductRestrictedDomain.wixproj | 13 + .../ProductRestrictedDomain/RestrictedDomain.wxs | 20 ++ .../ProductWithCommandLineParameters.wixproj | 13 + .../ProductWithCommandLineParameters.wxs | 19 ++ .../UtilExtensionGroupTests.cs | 271 +++++++++++++++++++++ 24 files changed, 861 insertions(+) create mode 100644 src/test/burn/WixTestTools/UserGroupVerifier.cs create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductA/ProductA.wixproj create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductA/product.wxs create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductAddCommentToExistingGroup/ProductAddCommentToExistingGroup.wixproj create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductAddCommentToExistingGroup/product.wxs create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentDelete/ProductCommentDelete.wixproj create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentDelete/product.wxs create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentFail/ProductCommentFail.wixproj create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentFail/product_fail.wxs create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductFail/ProductFail.wixproj create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductFail/product_fail.wxs create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductFailIfExists/FailIfExists.wxs create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductFailIfExists/ProductFailIfExists.wixproj create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductNestedGroups/ProductNestedGroups.wixproj create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductNestedGroups/product.wxs create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductNewGroupWithComment/ProductNewGroupWithComment.wixproj create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductNewGroupWithComment/product.wxs create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductNonVitalGroup/NonVitalUserGroup.wxs create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductNonVitalGroup/ProductNonVitalUserGroup.wixproj create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductRestrictedDomain/ProductRestrictedDomain.wixproj create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductRestrictedDomain/RestrictedDomain.wxs create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductWithCommandLineParameters/ProductWithCommandLineParameters.wixproj create mode 100644 src/test/msi/TestData/UtilExtensionGroupTests/ProductWithCommandLineParameters/ProductWithCommandLineParameters.wxs create mode 100644 src/test/msi/WixToolsetTest.MsiE2E/UtilExtensionGroupTests.cs (limited to 'src/test') diff --git a/src/test/burn/WixTestTools/UserGroupVerifier.cs b/src/test/burn/WixTestTools/UserGroupVerifier.cs new file mode 100644 index 00000000..2f874057 --- /dev/null +++ b/src/test/burn/WixTestTools/UserGroupVerifier.cs @@ -0,0 +1,198 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixTestTools +{ + using System; + using System.Text; + using System.DirectoryServices; + using System.DirectoryServices.AccountManagement; + using System.Security.Principal; + using Xunit; + + /// + /// Contains methods for User Group verification + /// + public static class UserGroupVerifier + { + /// + /// Create a local group on the machine + /// + /// + /// Has to be run as an Admin + public static void CreateLocalGroup(string groupName) + { + DeleteLocalGroup(groupName); + GroupPrincipal newGroup = new GroupPrincipal(new PrincipalContext(ContextType.Machine)); + newGroup.Name = groupName; + newGroup.Description = String.Empty; + newGroup.Save(); + } + + /// + /// Deletes a local gorup from the machine + /// + /// group name to delete + /// Has to be run as an Admin + public static void DeleteLocalGroup(string groupName) + { + GroupPrincipal newGroup = GetGroup(String.Empty, groupName); + if (null != newGroup) + { + newGroup.Delete(); + } + } + + /// + /// Verifies that a group exists or not + /// + /// domain name for the group, empty for local groups + /// the group name + public static bool GroupExists(string domainName, string groupName) + { + GroupPrincipal group = GetGroup(domainName, groupName); + + return null != group; + } + + /// + /// Sets the group comment for a given group + /// + /// domain name for the group, empty for local users + /// the group name + /// comment to be set for the group + public static void SetGroupComment(string domainName, string groupName, string comment) + { + GroupPrincipal group = GetGroup(domainName, groupName); + + Assert.False(null == group, String.Format("Group '{0}' was not found under domain '{1}'.", groupName, domainName)); + + var directoryEntry = group.GetUnderlyingObject() as DirectoryEntry; + Assert.False(null == directoryEntry); + directoryEntry.Properties["Description"].Value = comment; + group.Save(); + } + + /// + /// Adds the specified group to the specified local group + /// + /// Member to add + /// Group to add too + public static void AddGroupToGroup(string memberName, string groupName) + { + DirectoryEntry localMachine; + DirectoryEntry localGroup; + + localMachine = new DirectoryEntry("WinNT://" + Environment.MachineName.ToString()); + localGroup = localMachine.Children.Find(groupName, "group"); + Assert.False(null == localGroup, String.Format("Group '{0}' was not found.", groupName)); + DirectoryEntry group = FindActiveDirectoryGroup(memberName); + localGroup.Invoke("Add", new object[] { group.Path.ToString() }); + } + + /// + /// Find the specified group in AD + /// + /// group name to lookup + /// DirectoryEntry of the group + private static DirectoryEntry FindActiveDirectoryGroup(string groupName) + { + var mLocalMachine = new DirectoryEntry("WinNT://" + Environment.MachineName.ToString()); + var mLocalEntries = mLocalMachine.Children; + + var theGroup = mLocalEntries.Find(groupName); + return theGroup; + } + + /// + /// Verifies the group comment for a given group + /// + /// domain name for the group, empty for local users + /// the group name + /// the comment to be verified + public static void VerifyGroupComment(string domainName, string groupName, string comment) + { + GroupPrincipal group = GetGroup(domainName, groupName); + + Assert.False(null == group, String.Format("Group '{0}' was not found under domain '{1}'.", groupName, domainName)); + + var directoryEntry = group.GetUnderlyingObject() as DirectoryEntry; + Assert.False(null == directoryEntry); + Assert.True(comment == (string)(directoryEntry.Properties["Description"].Value)); + } + + /// + /// Verify that a given group is member of a local group + /// + /// domain name for the group, empty for local groups + /// the member name + /// list of groups to check for membership + public static void VerifyIsMemberOf(string domainName, string memberName, params string[] groupNames) + { + IsMemberOf(domainName, memberName, true, groupNames); + } + + /// + /// Verify that a given group is NOT member of a local group + /// + /// domain name for the group, empty for local groups + /// the member name + /// list of groups to check for membership + public static void VerifyIsNotMemberOf(string domainName, string memberName, params string[] groupNames) + { + IsMemberOf(domainName, memberName, false, groupNames); + } + + /// + /// Verify that a given user is member of a local group + /// + /// domain name for the group, empty for local groups + /// the member name + /// whether the group is expected to be a member of the groups or not + /// list of groups to check for membership + private static void IsMemberOf(string domainName, string memberName, bool shouldBeMember, params string[] groupNames) + { + GroupPrincipal group = GetGroup(domainName, memberName); + Assert.False(null == group, String.Format("Group '{0}' was not found under domain '{1}'.", memberName, domainName)); + + bool missedAGroup = false; + string message = String.Empty; + foreach (string groupName in groupNames) + { + try + { + bool found = group.IsMemberOf(new PrincipalContext(ContextType.Machine), IdentityType.Name, groupName); + if (found != shouldBeMember) + { + missedAGroup = true; + message += String.Format("Group '{0}/{1}' is {2} a member of local group '{3}'. \r\n", domainName, memberName, found ? String.Empty : "NOT", groupName); + } + } + catch (System.DirectoryServices.AccountManagement.PrincipalOperationException) + { + missedAGroup = true; + message += String.Format("Local group '{0}' was not found. \r\n", groupName); + } + } + Assert.False(missedAGroup, message); + } + + /// + /// Returns the GroupPrincipal object for a given group + /// + /// Domain name to look under, if Empty the LocalMachine is assumed as the domain + /// + /// UserPrincipal Object for the group if found, or null other wise + private static GroupPrincipal GetGroup(string domainName, string groupName) + { + if (String.IsNullOrEmpty(domainName)) + { + return GroupPrincipal.FindByIdentity(new PrincipalContext(ContextType.Machine), IdentityType.Name, groupName); + } + else + { + return GroupPrincipal.FindByIdentity(new PrincipalContext(ContextType.Domain,domainName), IdentityType.Name, groupName); + } + } + } +} + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductA/ProductA.wixproj b/src/test/msi/TestData/UtilExtensionGroupTests/ProductA/ProductA.wixproj new file mode 100644 index 00000000..3895b853 --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductA/ProductA.wixproj @@ -0,0 +1,13 @@ + + + + {A3E0B539-63F9-4B43-9E34-F33AE1C6E06D} + true + + + + + + + + \ No newline at end of file diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductA/product.wxs b/src/test/msi/TestData/UtilExtensionGroupTests/ProductA/product.wxs new file mode 100644 index 00000000..e3c143e6 --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductA/product.wxs @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductAddCommentToExistingGroup/ProductAddCommentToExistingGroup.wixproj b/src/test/msi/TestData/UtilExtensionGroupTests/ProductAddCommentToExistingGroup/ProductAddCommentToExistingGroup.wixproj new file mode 100644 index 00000000..5938e525 --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductAddCommentToExistingGroup/ProductAddCommentToExistingGroup.wixproj @@ -0,0 +1,13 @@ + + + + {B33D3140-4AA5-469D-9DEE-AAF8F0C626DA} + true + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductAddCommentToExistingGroup/product.wxs b/src/test/msi/TestData/UtilExtensionGroupTests/ProductAddCommentToExistingGroup/product.wxs new file mode 100644 index 00000000..e0170746 --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductAddCommentToExistingGroup/product.wxs @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentDelete/ProductCommentDelete.wixproj b/src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentDelete/ProductCommentDelete.wixproj new file mode 100644 index 00000000..63bb2370 --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentDelete/ProductCommentDelete.wixproj @@ -0,0 +1,13 @@ + + + + {9E4C301E-5F36-4A86-85BE-776E067D929D} + true + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentDelete/product.wxs b/src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentDelete/product.wxs new file mode 100644 index 00000000..d1824890 --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentDelete/product.wxs @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentFail/ProductCommentFail.wixproj b/src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentFail/ProductCommentFail.wixproj new file mode 100644 index 00000000..66f308ae --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentFail/ProductCommentFail.wixproj @@ -0,0 +1,13 @@ + + + + {85F698E0-F542-4CB4-80A1-6630D2DEB647} + true + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentFail/product_fail.wxs b/src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentFail/product_fail.wxs new file mode 100644 index 00000000..29b908da --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductCommentFail/product_fail.wxs @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductFail/ProductFail.wixproj b/src/test/msi/TestData/UtilExtensionGroupTests/ProductFail/ProductFail.wixproj new file mode 100644 index 00000000..e2fe3aa8 --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductFail/ProductFail.wixproj @@ -0,0 +1,13 @@ + + + + {91D27DAC-04C1-4160-914E-343676D36CAA} + true + + + + + + + + \ No newline at end of file diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductFail/product_fail.wxs b/src/test/msi/TestData/UtilExtensionGroupTests/ProductFail/product_fail.wxs new file mode 100644 index 00000000..fb35bc1e --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductFail/product_fail.wxs @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductFailIfExists/FailIfExists.wxs b/src/test/msi/TestData/UtilExtensionGroupTests/ProductFailIfExists/FailIfExists.wxs new file mode 100644 index 00000000..00f8e12d --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductFailIfExists/FailIfExists.wxs @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductFailIfExists/ProductFailIfExists.wixproj b/src/test/msi/TestData/UtilExtensionGroupTests/ProductFailIfExists/ProductFailIfExists.wixproj new file mode 100644 index 00000000..9e1a836f --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductFailIfExists/ProductFailIfExists.wixproj @@ -0,0 +1,13 @@ + + + + {BC803822-929E-47DA-AB3A-3A62EEEA2BFB} + true + + + + + + + + \ No newline at end of file diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductNestedGroups/ProductNestedGroups.wixproj b/src/test/msi/TestData/UtilExtensionGroupTests/ProductNestedGroups/ProductNestedGroups.wixproj new file mode 100644 index 00000000..3b2e3942 --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductNestedGroups/ProductNestedGroups.wixproj @@ -0,0 +1,13 @@ + + + + {8B6C2900-44C4-42C9-879F-82F551B10C15} + true + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductNestedGroups/product.wxs b/src/test/msi/TestData/UtilExtensionGroupTests/ProductNestedGroups/product.wxs new file mode 100644 index 00000000..191d605c --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductNestedGroups/product.wxs @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductNewGroupWithComment/ProductNewGroupWithComment.wixproj b/src/test/msi/TestData/UtilExtensionGroupTests/ProductNewGroupWithComment/ProductNewGroupWithComment.wixproj new file mode 100644 index 00000000..aeac903a --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductNewGroupWithComment/ProductNewGroupWithComment.wixproj @@ -0,0 +1,13 @@ + + + + {549E1829-BBDE-42E1-968A-BEB8FC12BFC7} + true + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductNewGroupWithComment/product.wxs b/src/test/msi/TestData/UtilExtensionGroupTests/ProductNewGroupWithComment/product.wxs new file mode 100644 index 00000000..2d012b23 --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductNewGroupWithComment/product.wxs @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductNonVitalGroup/NonVitalUserGroup.wxs b/src/test/msi/TestData/UtilExtensionGroupTests/ProductNonVitalGroup/NonVitalUserGroup.wxs new file mode 100644 index 00000000..a834c76b --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductNonVitalGroup/NonVitalUserGroup.wxs @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductNonVitalGroup/ProductNonVitalUserGroup.wixproj b/src/test/msi/TestData/UtilExtensionGroupTests/ProductNonVitalGroup/ProductNonVitalUserGroup.wixproj new file mode 100644 index 00000000..8734224d --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductNonVitalGroup/ProductNonVitalUserGroup.wixproj @@ -0,0 +1,13 @@ + + + + {455C8D4F-6D59-405C-AD51-0ACC7FB91A26} + true + + + + + + + + \ No newline at end of file diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductRestrictedDomain/ProductRestrictedDomain.wixproj b/src/test/msi/TestData/UtilExtensionGroupTests/ProductRestrictedDomain/ProductRestrictedDomain.wixproj new file mode 100644 index 00000000..e4a01a3a --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductRestrictedDomain/ProductRestrictedDomain.wixproj @@ -0,0 +1,13 @@ + + + + {50CF526C-A862-4327-9EA3-C96AAB6FABCE} + true + + + + + + + + \ No newline at end of file diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductRestrictedDomain/RestrictedDomain.wxs b/src/test/msi/TestData/UtilExtensionGroupTests/ProductRestrictedDomain/RestrictedDomain.wxs new file mode 100644 index 00000000..edb3387c --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductRestrictedDomain/RestrictedDomain.wxs @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductWithCommandLineParameters/ProductWithCommandLineParameters.wixproj b/src/test/msi/TestData/UtilExtensionGroupTests/ProductWithCommandLineParameters/ProductWithCommandLineParameters.wixproj new file mode 100644 index 00000000..93a56216 --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductWithCommandLineParameters/ProductWithCommandLineParameters.wixproj @@ -0,0 +1,13 @@ + + + + {79F2CB65-1E71-42EB-AA30-51BD70C29B23} + true + + + + + + + + diff --git a/src/test/msi/TestData/UtilExtensionGroupTests/ProductWithCommandLineParameters/ProductWithCommandLineParameters.wxs b/src/test/msi/TestData/UtilExtensionGroupTests/ProductWithCommandLineParameters/ProductWithCommandLineParameters.wxs new file mode 100644 index 00000000..059ecee8 --- /dev/null +++ b/src/test/msi/TestData/UtilExtensionGroupTests/ProductWithCommandLineParameters/ProductWithCommandLineParameters.wxs @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + diff --git a/src/test/msi/WixToolsetTest.MsiE2E/UtilExtensionGroupTests.cs b/src/test/msi/WixToolsetTest.MsiE2E/UtilExtensionGroupTests.cs new file mode 100644 index 00000000..796c4ecd --- /dev/null +++ b/src/test/msi/WixToolsetTest.MsiE2E/UtilExtensionGroupTests.cs @@ -0,0 +1,271 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolsetTest.MsiE2E +{ + using System; + using WixTestTools; + using Xunit; + using Xunit.Abstractions; + + public class UtilExtensionGroupTests : MsiE2ETests + { + public UtilExtensionGroupTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { } + + // Verify that the users specified in the authoring are created as expected. + [RuntimeFact] + public void CanInstallAndUninstallGroups() + { + UserGroupVerifier.CreateLocalGroup("testName3"); + var productA = this.CreatePackageInstaller("ProductA"); + + productA.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + + // Validate New User Information. + Assert.True(UserGroupVerifier.GroupExists(String.Empty, "testName1"), String.Format("Group '{0}' was not created on Install", "testName1")); + Assert.True(UserGroupVerifier.GroupExists(String.Empty, "testName2"), String.Format("Group '{0}' was not created on Install", "testName2")); + Assert.True(UserGroupVerifier.GroupExists(String.Empty, "testName3"), String.Format("Group '{0}' was not created on Install", "testName3")); + + productA.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + + // Verify Users marked as RemoveOnUninstall were removed. + Assert.False(UserGroupVerifier.GroupExists(String.Empty, "testName1"), String.Format("Group '{0}' was not removed on Uninstall", "testName1")); + Assert.True(UserGroupVerifier.GroupExists(String.Empty, "testName2"), String.Format("Group '{0}' was removed on Uninstall", "testName2")); + + // clean up + UserGroupVerifier.DeleteLocalGroup("testName1"); + UserGroupVerifier.DeleteLocalGroup("testName2"); + UserGroupVerifier.DeleteLocalGroup("testName3"); + } + + // Verify the rollback action reverts all Users changes. + [RuntimeFact] + public void CanRollbackGroups() + { + UserGroupVerifier.CreateLocalGroup("testName3"); + var productFail = this.CreatePackageInstaller("ProductFail"); + + // make sure the user accounts are deleted before we start + UserGroupVerifier.DeleteLocalGroup("testName1"); + UserGroupVerifier.DeleteLocalGroup("testName2"); + + productFail.InstallProduct(MSIExec.MSIExecReturnCode.ERROR_INSTALL_FAILURE); + + // Verify added Users were removed on rollback. + Assert.False(UserGroupVerifier.GroupExists(String.Empty, "testName1"), String.Format("Group '{0}' was not removed on Rollback", "testName1")); + Assert.False(UserGroupVerifier.GroupExists(String.Empty, "testName2"), String.Format("Group '{0}' was not removed on Rollback", "testName2")); + + // clean up + UserGroupVerifier.DeleteLocalGroup("testName1"); + UserGroupVerifier.DeleteLocalGroup("testName2"); + UserGroupVerifier.DeleteLocalGroup("testName3"); + } + + + // Verify that command-line parameters aer not blocked by repair switches. + // Original code signalled repair mode by using "-f ", which silently + // terminated the command-line parsing, ignoring any parameters that followed. + [RuntimeFact()] + public void CanRepairGroupsWithCommandLineParameters() + { + var arguments = new string[] + { + "TESTPARAMETER1=testName1", + }; + var productWithCommandLineParameters = this.CreatePackageInstaller("ProductWithCommandLineParameters"); + + // Make sure that the user doesn't exist when we start the test. + UserGroupVerifier.DeleteLocalGroup("testName1"); + + // Install + productWithCommandLineParameters.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS, arguments); + + // Repair + productWithCommandLineParameters.RepairProduct(MSIExec.MSIExecReturnCode.SUCCESS, arguments); + + // Clean up + UserGroupVerifier.DeleteLocalGroup("testName1"); + } + + + // Verify that the groups specified in the authoring are created as expected on repair. + [RuntimeFact()] + public void CanRepairGroups() + { + UserGroupVerifier.CreateLocalGroup("testName3"); + var productA = this.CreatePackageInstaller("ProductA"); + + productA.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + + // Validate New User Information. + UserGroupVerifier.DeleteLocalGroup("testName1"); + + productA.RepairProduct(MSIExec.MSIExecReturnCode.SUCCESS); + + // Validate New User Information. + Assert.True(UserGroupVerifier.GroupExists(String.Empty, "testName1"), String.Format("User '{0}' was not installed on Repair", "testName1")); + Assert.True(UserGroupVerifier.GroupExists(String.Empty, "testName2"), String.Format("User '{0}' was not installed after Repair", "testName2")); + + productA.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + + // Verify Users marked as RemoveOnUninstall were removed. + Assert.False(UserGroupVerifier.GroupExists(String.Empty, "testName1"), String.Format("User '{0}' was not removed on Uninstall", "testName1")); + Assert.True(UserGroupVerifier.GroupExists(String.Empty, "testName2"), String.Format("User '{0}' was removed on Uninstall", "testName2")); + + // clean up + UserGroupVerifier.DeleteLocalGroup("testName1"); + UserGroupVerifier.DeleteLocalGroup("testName2"); + UserGroupVerifier.DeleteLocalGroup("testName3"); + } + + // Verify that Installation fails if FailIfExists is set. + [RuntimeFact] + public void FailsIfGroupExists() + { + var productFailIfExists = this.CreatePackageInstaller("ProductFailIfExists"); + + // Create 'existinggroup' + UserGroupVerifier.CreateLocalGroup("existinggroup"); + + try + { + productFailIfExists.InstallProduct(MSIExec.MSIExecReturnCode.ERROR_INSTALL_FAILURE); + + // Verify User still exists. + bool userExists = UserGroupVerifier.GroupExists(String.Empty, "existinggroup"); + + Assert.True(userExists, String.Format("Group '{0}' was removed on Rollback", "existinggroup")); + } + finally + { + // clean up + UserGroupVerifier.DeleteLocalGroup("existinggroup"); + } + } + + // Verify that a group cannot be created on a domain on which you don't have create user permission. + [RuntimeFact] + public void FailsIfRestrictedDomain() + { + var productRestrictedDomain = this.CreatePackageInstaller("ProductRestrictedDomain"); + + string logFile = productRestrictedDomain.InstallProduct(MSIExec.MSIExecReturnCode.ERROR_INSTALL_FAILURE, "TEMPDOMAIN=DOESNOTEXIST"); + + // Verify expected error message in the log file + Assert.True(LogVerifier.MessageInLogFile(logFile, "CreateGroup: Error 0x8007054b: failed to find Domain DOESNOTEXIST.")); + } + + // Verify that a group can be created with a group comment + [RuntimeFact] + public void CanCreateNewGroupWithComment() + { + var productNewUserWithComment = this.CreatePackageInstaller("ProductNewGroupWithComment"); + + productNewUserWithComment.InstallProduct(); + UserGroupVerifier.VerifyGroupComment(String.Empty, "testName1", "testComment1"); + + // clean up + UserGroupVerifier.DeleteLocalGroup("testName1"); + } + + // Verify that a comment can be added to an existing group + [RuntimeFact] + public void CanAddCommentToExistingGroup() + { + UserGroupVerifier.CreateLocalGroup("testName1"); + var productAddCommentToExistingUser = this.CreatePackageInstaller("ProductAddCommentToExistingGroup"); + + productAddCommentToExistingUser.InstallProduct(); + + UserGroupVerifier.VerifyGroupComment(String.Empty, "testName1", "testComment1"); + + // clean up + UserGroupVerifier.DeleteLocalGroup("testName1"); + } + + // Verify that a comment can be repaired for a new group + [RuntimeFact] + public void CanRepairCommentOfNewGroup() + { + var productNewUserWithComment = this.CreatePackageInstaller("ProductNewGroupWithComment"); + + productNewUserWithComment.InstallProduct(); + UserGroupVerifier.SetGroupComment(String.Empty, "testName1", ""); + + productNewUserWithComment.RepairProduct(); + UserGroupVerifier.VerifyGroupComment(String.Empty, "testName1", "testComment1"); + + // clean up + UserGroupVerifier.DeleteLocalGroup("testName1"); + } + + // Verify that a comment can be changed for an existing group + [RuntimeFact] + public void CanChangeCommentOfExistingGroup() + { + UserGroupVerifier.CreateLocalGroup("testName1"); + UserGroupVerifier.SetGroupComment(String.Empty, "testName1", "initialTestComment1"); + var productNewUserWithComment = this.CreatePackageInstaller("ProductNewGroupWithComment"); + + productNewUserWithComment.InstallProduct(); + UserGroupVerifier.VerifyGroupComment(String.Empty, "testName1", "testComment1"); + + // clean up + UserGroupVerifier.DeleteLocalGroup("testName1"); + } + + // Verify that a comment can be rolled back for an existing group + [RuntimeFact] + public void CanRollbackCommentOfExistingGroup() + { + UserGroupVerifier.CreateLocalGroup("testName1"); + UserGroupVerifier.SetGroupComment(String.Empty, "testName1", "initialTestComment1"); + var productCommentFail = this.CreatePackageInstaller("ProductCommentFail"); + + productCommentFail.InstallProduct(MSIExec.MSIExecReturnCode.ERROR_INSTALL_FAILURE); + + // Verify that comment change was rolled back. + UserGroupVerifier.VerifyGroupComment(String.Empty, "testName1", "initialTestComment1"); + + // clean up + UserGroupVerifier.DeleteLocalGroup("testName1"); + } + + // Verify that a comment can be deleted for an existing group + [RuntimeFact] + public void CanDeleteCommentOfExistingGroup() + { + UserGroupVerifier.CreateLocalGroup("testName1"); + UserGroupVerifier.SetGroupComment(String.Empty, "testName1", "testComment1"); + var productCommentDelete = this.CreatePackageInstaller("ProductCommentDelete"); + + productCommentDelete.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + + // Verify that comment was removed. + UserGroupVerifier.VerifyGroupComment(String.Empty, "testName1", ""); + + // clean up + UserGroupVerifier.DeleteLocalGroup("testName1"); + } + + // Verify that a comment can be deleted for an existing group + [RuntimeFact] + public void CanNestGroups() + { + var productNestedGroups = this.CreatePackageInstaller("ProductNestedGroups"); + + productNestedGroups.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + + // Verify group nested membership + UserGroupVerifier.VerifyIsMemberOf(String.Empty, "Administrators", new string[] { "testName1", "testName2" }); + UserGroupVerifier.VerifyIsMemberOf(String.Empty, "Power Users", new string[] { "testName1" }); + + UserGroupVerifier.VerifyIsNotMemberOf(String.Empty, "Administrators", new string[] { "testName3" }); + UserGroupVerifier.VerifyIsNotMemberOf(String.Empty, "Power Users", new string[] { "testName2", "testName3" }); + + // clean up + UserGroupVerifier.DeleteLocalGroup("testName1"); + UserGroupVerifier.DeleteLocalGroup("testName2"); + UserGroupVerifier.DeleteLocalGroup("testName3"); + } + } +} -- cgit v1.2.3-55-g6feb