Adding more WMI tests (dotnet/corefx#24879)
authorPaulo Janotti <pauloja@microsoft.com>
Thu, 26 Oct 2017 17:43:38 +0000 (10:43 -0700)
committerGitHub <noreply@github.com>
Thu, 26 Oct 2017 17:43:38 +0000 (10:43 -0700)
* Adding more WMI tests

* Opportunistically updating projects: removing suppression not needed
anymore, and add netfx for test

* Addressing review feedback

* Renaming test conditions

Commit migrated from https://github.com/dotnet/corefx/commit/9b5c2cd0899ac38728d37f61f539ff9b250bb88b

16 files changed:
src/libraries/System.Management/src/System.Management.csproj
src/libraries/System.Management/tests/Configurations.props
src/libraries/System.Management/tests/MofHelpers/MofCollection.cs [new file with mode: 0644]
src/libraries/System.Management/tests/MofHelpers/MofFixture.cs [new file with mode: 0644]
src/libraries/System.Management/tests/Resources/CleanUp.mof [new file with mode: 0644]
src/libraries/System.Management/tests/Resources/WmiEBvt.mof [new file with mode: 0644]
src/libraries/System.Management/tests/System.Management.Tests.csproj
src/libraries/System.Management/tests/System/Management/ManagementClassTests.cs
src/libraries/System.Management/tests/System/Management/ManagementClassTestsMofRequired.cs [new file with mode: 0644]
src/libraries/System.Management/tests/System/Management/ManagementDateTimeConverterTests.cs
src/libraries/System.Management/tests/System/Management/ManagementEventWatcherTests.cs [new file with mode: 0644]
src/libraries/System.Management/tests/System/Management/ManagementObjectSearcherTests.cs [new file with mode: 0644]
src/libraries/System.Management/tests/System/Management/ManagementObjectSearcherTestsMofRequired.cs [new file with mode: 0644]
src/libraries/System.Management/tests/System/Management/ManagementObjectTests.cs
src/libraries/System.Management/tests/System/Management/SelectQueryTests.cs
src/libraries/System.Management/tests/WmiTestHelper.cs [new file with mode: 0644]

index 771330c..cb7c6a4 100644 (file)
@@ -10,8 +10,6 @@
     <UWPCompatible>false</UWPCompatible>
     <IncludeDllSafeSearchPathAttribute>true</IncludeDllSafeSearchPathAttribute>
     <GeneratePlatformNotSupportedAssemblyMessage Condition="'$(TargetsWindows)' != 'true' or '$(TargetGroup)' == 'uap'">SR.PlatformNotSupported_SystemManagement</GeneratePlatformNotSupportedAssemblyMessage>
-    <!-- When generating PNSE assembly disable CA1821 since finalizers are being generated empty -->
-    <NoWarn Condition="'$(TargetsWindows)' != 'true' or '$(TargetGroup)' == 'uap'">$(NoWarn);CA1821</NoWarn>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Windows_NT-Debug|AnyCPU'" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Windows_NT-Release|AnyCPU'" />
index d8cd9ec..808952d 100644 (file)
@@ -3,6 +3,7 @@
   <PropertyGroup>
     <BuildConfigurations>
         netcoreapp-Windows_NT;
+        netfx;
     </BuildConfigurations>
   </PropertyGroup>
 </Project>
diff --git a/src/libraries/System.Management/tests/MofHelpers/MofCollection.cs b/src/libraries/System.Management/tests/MofHelpers/MofCollection.cs
new file mode 100644 (file)
index 0000000..1e56742
--- /dev/null
@@ -0,0 +1,18 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Xunit;
+
+namespace System.Management.Tests
+{
+    [CollectionDefinition("Mof Collection")]
+    [OuterLoop]
+    public class MofCollection : ICollectionFixture<MofFixture>
+    {
+        // This class has no code, and is never created. Its purpose is simply
+        // to be the place to apply [CollectionDefinition] and all the 
+        // ICollectionFixture<> interfaces.
+        // See https://xunit.github.io/docs/shared-context.html#collection-fixture
+    }
+}
diff --git a/src/libraries/System.Management/tests/MofHelpers/MofFixture.cs b/src/libraries/System.Management/tests/MofHelpers/MofFixture.cs
new file mode 100644 (file)
index 0000000..7399321
--- /dev/null
@@ -0,0 +1,67 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using Xunit;
+
+namespace System.Management.Tests
+{
+    public class MofFixture : IDisposable
+    {
+        private Assembly _assembly = typeof(MofFixture).GetTypeInfo().Assembly;
+        private string _mofCompilerPath = Path.Combine(Environment.SystemDirectory, @"wbem\mofcomp.exe");
+
+        public MofFixture()
+        {
+            if (AdminHelpers.IsProcessElevated())
+                ExtractAndCompileMof("WmiEBvt.mof");
+        }
+
+        public void Dispose()
+        {
+            if (AdminHelpers.IsProcessElevated())
+                ExtractAndCompileMof("CleanUp.mof");
+        }
+
+        private void ExtractAndCompileMof(string mofResourceName)
+        {
+            string mofFilePath = null;
+            try
+            {
+                mofFilePath = ExtractMofFromResourcesToFile(mofResourceName);
+                CompileMof(mofFilePath);
+            }
+            finally
+            {
+                if (mofFilePath != null)
+                    File.Delete(mofFilePath);
+            }
+        }
+
+        private string ExtractMofFromResourcesToFile(string mofResourceName)
+        {
+            var mofFilePath = Path.Combine(Path.GetTempPath(), mofResourceName);
+            using (var mofStream = new StreamReader(_assembly.GetManifestResourceStream(mofResourceName)))
+            {
+                string mofContent = mofStream.ReadToEnd();
+                File.WriteAllText(mofFilePath, mofContent);
+            }
+
+            return mofFilePath;
+        }
+
+        private void CompileMof(string mofFilePath)
+        {
+            var psi = new ProcessStartInfo(_mofCompilerPath, mofFilePath);
+            psi.UseShellExecute = false;
+            psi.RedirectStandardOutput = true;
+            Process p = Process.Start(psi);
+            p.WaitForExit();
+            string output = p.StandardOutput.ReadToEnd();
+            Assert.True(p.ExitCode == 0, $"Failed to compile mof file {mofFilePath} output: {output}");
+        }
+    }
+}
diff --git a/src/libraries/System.Management/tests/Resources/CleanUp.mof b/src/libraries/System.Management/tests/Resources/CleanUp.mof
new file mode 100644 (file)
index 0000000..11611b7
--- /dev/null
@@ -0,0 +1,2 @@
+#pragma namespace("\\\\.\\root")
+#pragma deleteInstance("__namespace.Name='WmiEBvt'", NOFAIL)
\ No newline at end of file
diff --git a/src/libraries/System.Management/tests/Resources/WmiEBvt.mof b/src/libraries/System.Management/tests/Resources/WmiEBvt.mof
new file mode 100644 (file)
index 0000000..91874f1
--- /dev/null
@@ -0,0 +1,304 @@
+#pragma namespace("\\\\.\\root")
+#pragma deleteclass("WmiEBvt", nofail)
+
+instance of __namespace
+{
+       Name = "WmiEBvt";
+};
+
+#pragma namespace("\\\\.\\root\\WmiEBvt")
+#pragma deleteclass("Class1", nofail)          // This will delete all subclasses and instances
+#pragma deleteclass("Class2", nofail)          // This will delete all subclasses and instances
+#pragma deleteclass("Class3", nofail)          // This will delete all subclasses and instances
+#pragma deleteclass("Class4", nofail)          // This will delete all subclasses and instances
+#pragma deleteclass("Class5", nofail)          // This will delete all subclasses and instances
+#pragma deleteclass("ClassA", nofail)          // This will delete all subclasses and instances
+#pragma deleteclass("ClassB", nofail)          // This will delete all subclasses and instances
+#pragma deleteclass("ClassC", nofail)          // This will delete all subclasses and instances
+#pragma deleteclass("ClassD", nofail)          // This will delete all subclasses and instances
+#pragma deleteclass("ClassE", nofail)          // This will delete all subclasses and instances
+#pragma deleteclass("ClassF", nofail)          // This will delete all subclasses and instances
+#pragma deleteclass("RefClass", nofail)                // This will delete all subclasses and instances
+#pragma deleteclass("AssocClass", nofail)      
+///////////////////////////////////////////////////////////////////////////////////
+instance of __namespace
+{
+       Name = "ms_409";
+};
+
+///////////////////////////////////////////////////////////////////////////////////
+// Create Class1
+[Class1Q1 (1.0): ToInstance, Class1Q2 (2): ToInstance, Class1Q3 ("3"): ToInstance, Class1Q4 (true): ToInstance]
+class Class1
+{
+       [key] string MyKey;
+       sint32 MyNumber;
+};
+
+// Create Class2
+class Class2: Class1
+{
+       sint32 Class2Number;
+};
+
+// Create Class3
+class Class3
+{
+       [key] string Class3Key;
+       sint32 Class3Number;
+};
+
+// Create Class4
+class Class4
+{
+       [key] string Class4Key;
+       sint32 Class4Number;
+};
+
+//
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Create instances of Class1
+[Alias ("$One1")]
+instance of Class1 as $One1
+{
+       MyKey="One1";
+       MyNumber = 1;
+};
+instance of Class1 as $One2
+{
+       MyKey="One2";
+       MyNumber = 2;
+};
+instance of Class1 as $One3
+{
+       MyKey="One3";
+       MyNumber = 3;
+};
+
+// Create instances of Class2
+instance of Class2 as $Two1
+{
+       MyKey="Two1";
+       MyNumber= 1;
+       Class2Number = 1;
+};
+
+instance of Class2 as $Two2
+{
+       MyKey="Two2";
+       MyNumber = 2;
+       Class2Number = 2;
+};
+
+// Create instances of Class3
+instance of Class3 as $Three1
+{
+       Class3Key="Three1";
+       Class3Number = 1;
+};
+instance of Class3 as $Three2
+{
+       Class3Key="Three2";
+       Class3Number = 2;
+};
+instance of Class3 as $Three3
+{
+       Class3Key="Three3";
+       Class3Number = 3;
+};
+
+// Create instances of Class4
+instance of Class4 as $Four1
+{
+       Class4Key="Four1";
+       Class4Number = 1;
+};
+instance of Class4 as $Four2
+{
+       Class4Key="Four2";
+       Class4Number= 2;
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Create Association Class A
+[Association: ToInstance]
+class AssocA
+{
+       [key] Class1 ref Path1;
+       [key] Class3 ref Path2;
+       string Name;
+};
+
+// Create instances of AssocClass A
+instance of AssocA
+{
+       Path1=$One1;
+       Path2=$Three1;
+       Name="AssocA1";
+};
+
+instance of AssocA
+{
+       Path1=$One2;
+       Path2=$Three1;
+       Name="AssocA2";
+};
+
+instance of AssocA
+{
+       Path1=$Two1;
+       Path2=$Three3;
+       Name="AssocA3";
+};
+
+instance of AssocA
+{
+       Path1=$Two2;
+       Path2=$Three3;
+       Name="AssocA4";
+};
+
+// Create Association Class B
+[Association: ToInstance, QB1("VB1"): ToInstance]
+class AssocB
+{
+       [key] Class3 ref Path1;
+       [key] Class4 ref Path2;
+       string Name;
+};
+
+instance of AssocB
+{
+       Path1=$Three1;
+       Path2=$Four1;
+       Name="AssocB1";
+};
+
+instance of AssocB
+{
+       Path1=$Three2;
+       Path2=$Four2;
+       Name="AssocB2";
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// This section define class create embedded object
+//
+///////////////////////////////////////////////////////////////////////////////////
+// Create class to compare
+// Create ClassEm
+class ClassEm
+{
+       [key] string ClassKey;
+       object ClassEmbed;
+};
+class EmbedClass
+{
+       string ClassKey;
+       sint32 ClassNumber;
+};
+class EmbedSub : EmbedClass
+{
+};
+instance of ClassEm as $EmRef
+{
+       ClassKey = "ClassEm1";
+       ClassEmbed = 
+       instance of EmbedSub
+       {
+               ClassKey = "1";
+               ClassNumber = 1;
+       };
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Create instances to generate event every 0.1 seconds
+// EventQuery: SELECT * FROM __TimerEvent WHERE TimerID = "MyEvent"
+instance of __IntervalTimerInstruction
+{
+  TimerId = "MyEvent";     // inherited from __TimerInstruction
+  SkipIfPassed = FALSE;    // also inherited
+  IntervalBetweenEvents = 100;
+};
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// This class is designed for test 2.1.8.8
+//
+
+class RefClass
+{
+       [key] sint32 myKey;
+};
+
+instance of RefClass as $RefRef
+{
+       myKey = 6;
+};
+
+[myReal64 (1.0): ToInstance, mySInt32 (2): ToInstance, myString ("ThisIsAString"): ToInstance, myBool (true): ToInstance]
+class ClassF
+{
+       [key]sint32 mySInt32;
+       sint8 mySInt8; 
+       string myString;
+       boolean myBool;
+       ClassEm myEmbedClass;   
+       sint16 mySInt16;        
+       sint64 mySInt64;
+       Real32 myReal32;
+       Real64 myReal64;
+       UInt8 myUInt8;
+       UInt16 myUInt16;
+       UInt32 myUInt32;
+       UInt64 myUInt64;
+       object myObject;
+       object ref myWeakRef;
+       RefClass ref myStrongRef;
+       char16 myChar16;
+       
+};
+
+instance of ClassF
+{
+       myString = "myInstanceString";
+       myBool = true;
+       myEmbedClass =
+               instance of ClassEm
+               {
+                       ClassKey = "ClassEmF";
+                       ClassEmbed = 
+                       instance of EmbedSub
+                       {
+                               ClassKey = "F";
+                               ClassNumber = 2;
+                       };
+               };
+       mySInt8 = -8; 
+       mySInt16 = -16;
+       mySInt32 = -32;
+       mySInt64 = -64;
+       myReal32 = 32.32;
+       myReal64 = 64.64;
+       myUInt8 = 8;
+       myUInt16 = 16;
+       myUInt32 = 32;
+       myUInt64 = 64;
+       myObject = 
+               instance of EmbedSub
+               {
+                       ClassKey = "F";
+                       ClassNumber = 2;
+               };
+       myWeakRef = $EmRef;
+       myStrongRef = $RefRef;
+       myChar16 = 'c'; 
+};
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
index 02465dc..b3a7308 100644 (file)
@@ -6,11 +6,28 @@
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Windows_NT-Debug|AnyCPU'" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Windows_NT-Release|AnyCPU'" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Windows_NT-Debug|AnyCPU'" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Windows_NT-Release|AnyCPU'" />
   <ItemGroup>
+    <Compile Include="MofHelpers\MofCollection.cs" />
+    <Compile Include="MofHelpers\MofFixture.cs" />
+    <Compile Include="System\Management\ManagementClassTestsMofRequired.cs" />
     <Compile Include="System\Management\ManagementClassTests.cs" />
     <Compile Include="System\Management\ManagementDateTimeConverterTests.cs" />
+    <Compile Include="System\Management\ManagementEventWatcherTests.cs" />
+    <Compile Include="System\Management\ManagementObjectSearcherTests.cs" />
+    <Compile Include="System\Management\ManagementObjectSearcherTestsMofRequired.cs" />
     <Compile Include="System\Management\ManagementObjectTests.cs" />
     <Compile Include="System\Management\SelectQueryTests.cs" />
+    <Compile Include="WmiTestHelper.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Resources\WmiEBvt.mof">
+      <LogicalName>WmiEBvt.mof</LogicalName>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Resources\CleanUp.mof">
+      <LogicalName>CleanUp.mof</LogicalName>
+    </EmbeddedResource>
   </ItemGroup>
   <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
 </Project>
\ No newline at end of file
index bba2a25..5a83084 100644 (file)
@@ -4,15 +4,13 @@
 
 using System.CodeDom;
 using System.IO;
-using System.Management;
 using Xunit;
 
 namespace System.Management.Tests
 {
-    [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "WMI not supported via UAP")]
     public class ManagementClassTests
     {
-        [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+        [ConditionalTheory(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
         [InlineData(false, false)]
         [InlineData(false, true)]
         [InlineData(true, false)]
@@ -26,7 +24,7 @@ namespace System.Management.Tests
             }
         }
 
-        [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+        [ConditionalTheory(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
         [InlineData(CodeLanguage.CSharp)]
         [InlineData(CodeLanguage.VB)]
         public void Get_SourceFile_For_Win32_Processor(CodeLanguage lang)
@@ -47,7 +45,7 @@ namespace System.Management.Tests
             }
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
         public void ClassMembers_For_Win32_LogicalDisk()
         {
             var managementClass = new ManagementClass(new ManagementPath("Win32_LogicalDisk"));
@@ -67,7 +65,7 @@ namespace System.Management.Tests
                 Assert.False(string.IsNullOrWhiteSpace(qualifier.Name));
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
         public void EnumerateInstances_For_Win32_LogicalDisk()
         {
             using (var managementClass = new ManagementClass(new ManagementPath("Win32_LogicalDisk")))
@@ -84,5 +82,26 @@ namespace System.Management.Tests
                 }
             }
         }
+
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsElevatedAndSupportsWmi))]
+        public void Create_Delete_Namespace()
+        {
+            using (var rootNamespace = new ManagementClass("root:__namespace"))
+            using (ManagementObject newNamespace = rootNamespace.CreateInstance())
+            {
+                const string NewNamespace = "CoreFx_Create_Delete_Namespace_Test";
+                newNamespace["Name"] = NewNamespace;
+                newNamespace.Put();
+
+                ManagementObject targetNamespace = new ManagementObject($"root:__namespace.Name='{NewNamespace}'");
+                Assert.Equal(NewNamespace, targetNamespace["Name"]);
+
+                // If any of the steps below fail it is likely that the new namespace was not deleted, likely it will have to
+                // be deleted via a tool like wbemtest.
+                targetNamespace.Delete();
+                ManagementException managementException = Assert.Throws<ManagementException>(() => targetNamespace.Get());
+                Assert.Equal(ManagementStatus.NotFound, managementException.ErrorCode);
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Management/tests/System/Management/ManagementClassTestsMofRequired.cs b/src/libraries/System.Management/tests/System/Management/ManagementClassTestsMofRequired.cs
new file mode 100644 (file)
index 0000000..9097d57
--- /dev/null
@@ -0,0 +1,91 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Xunit;
+
+namespace System.Management.Tests
+{
+    [Collection("Mof Collection")]
+    public class ManagementClassTestsMofRequired
+    {
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsElevatedAndSupportsWmi))]
+        public void Create_Modify_Delete_Static_Class()
+        {
+            using (var newClass = new ManagementClass(WmiTestHelper.Namespace))
+            {
+                const string NewClassName = "CoreFX_Create_Modify_Delete_Static_Class\uEE68\uD79D\u1659";
+                const string PropertyName = "Key";
+                const int PropertyValue = 10;
+
+                newClass["__CLASS"] = NewClassName;
+                newClass.Properties.Add(PropertyName, CimType.SInt32, false);
+                newClass.Properties[PropertyName].Qualifiers.Add("key", true);
+                newClass.Put();
+
+                var targetClass = new ManagementClass(WmiTestHelper.Namespace, NewClassName, null);
+                targetClass.Get();
+
+                newClass[PropertyName] = PropertyValue;
+                newClass.Put();
+                targetClass.Get();
+                Assert.Equal(PropertyValue, (int)targetClass[PropertyName]);
+
+                // If any of the steps below fail it is likely that the new class was not deleted, likely it will have to
+                // be deleted via a tool like wbemtest.
+                newClass.Delete();
+                ManagementException managementException = Assert.Throws<ManagementException>(() => targetClass.Get());
+                Assert.Equal(ManagementStatus.NotFound, managementException.ErrorCode);
+            }
+        }
+
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsElevatedAndSupportsWmi))]
+        public void Create_Modify_Delete_Static_And_Instance()
+        {
+            using (var newClass = new ManagementClass(WmiTestHelper.Namespace))
+            {
+                const string NewClassName = "CoreFX_Create_Static_Class_And_Instance";
+                const string KeyPropertyName = "Key";
+                const int KeyPropertyValue = 1;
+                const string MoviePropertyName = "Movie";
+                const string OldMovieValue = "Sequel I";
+                const string NewMovieValue = "Sequel II";
+
+                newClass["__CLASS"] = NewClassName;
+                newClass.Properties.Add(KeyPropertyName, CimType.SInt32, false);
+                newClass.Properties[KeyPropertyName].Qualifiers.Add("key", true);
+                newClass.Properties.Add(MoviePropertyName, CimType.String, false);
+                newClass.Put();
+
+                ManagementObject newInstance = newClass.CreateInstance();
+                newInstance[KeyPropertyName] = KeyPropertyValue;
+                newInstance[MoviePropertyName] = OldMovieValue;
+                newInstance.Put();
+
+                var targetInstance = new ManagementObject(
+                    WmiTestHelper.Namespace, $"{NewClassName}.{KeyPropertyName}='{KeyPropertyValue}'", null);
+                targetInstance.Get();
+                Assert.Equal(OldMovieValue, targetInstance[MoviePropertyName].ToString());
+
+                newInstance[MoviePropertyName] = NewMovieValue;
+                newInstance.Put();
+                Assert.Equal(NewMovieValue, newInstance[MoviePropertyName].ToString());
+
+                targetInstance.Get();
+                Assert.Equal(NewMovieValue, targetInstance[MoviePropertyName].ToString());
+
+                // If any of the steps below fail it is likely that the new class was not deleted, likely it will have to
+                // be deleted via a tool like wbemtest.
+                newInstance.Delete();
+                ManagementException managementException = Assert.Throws<ManagementException>(() => targetInstance.Get());
+                Assert.Equal(ManagementStatus.NotFound, managementException.ErrorCode);
+
+                // If any of the steps below fail it is likely that the new class was not deleted, likely it will have to
+                // be deleted via a tool like wbemtest.
+                newClass.Delete();
+                managementException = Assert.Throws<ManagementException>(() => newClass.Get());
+                Assert.Equal(ManagementStatus.NotFound, managementException.ErrorCode);
+            }
+        }
+    }
+}
index b7fa73a..d2cdfff 100644 (file)
@@ -2,15 +2,13 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
-using System.Management;
 using Xunit;
 
 namespace System.Management.Tests
 {
-    [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "WMI not supported via UAP")]
     public class ManagementDateTimeConverterTests
     {
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
         public void DateTime_RoundTrip()
         {
             var date = new DateTime(2002, 4, 8, 14, 18, 35, 978, DateTimeKind.Utc);
@@ -24,7 +22,7 @@ namespace System.Management.Tests
             Assert.Equal(dmtfDate, convertedDmtfDate);
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
         public void TimeSpan_RoundTrip()
         {
             var timeSpan = new TimeSpan(10, 12, 25, 32, 123);
diff --git a/src/libraries/System.Management/tests/System/Management/ManagementEventWatcherTests.cs b/src/libraries/System.Management/tests/System/Management/ManagementEventWatcherTests.cs
new file mode 100644 (file)
index 0000000..f4827db
--- /dev/null
@@ -0,0 +1,74 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Threading;
+using Xunit;
+
+namespace System.Management.Tests
+{
+    [Collection("Mof Collection")]
+    public class ManagementEventWatcherTests
+    {
+        private const string Query = "SELECT * FROM __TimerEvent WHERE TimerID = 'MyEvent'";
+
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsElevatedAndSupportsWmi))]
+        [OuterLoop]
+        public void Receive_Events_Sync()
+        {
+            ManagementEventWatcher watcher = null;
+            try
+            {
+                // Setup: Timer event is already set up by mof file to fire every 0.1 seconds.
+                // Run: Subscribe __TimerEvent with the specified TimerID
+                watcher = new ManagementEventWatcher(
+                    WmiTestHelper.Namespace,
+                    Query,
+                    new EventWatcherOptions(null, TimeSpan.FromSeconds(5), 1));
+
+                ManagementBaseObject evt = watcher.WaitForNextEvent();
+
+                Assert.True(evt["TimerID"].ToString() == "MyEvent", $"Unexpected TimerID value {evt["TimerID"]}");
+            }
+            finally
+            {
+                if (watcher != null)
+                    watcher.Stop();
+            }
+        }
+
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsElevatedAndSupportsWmi))]
+        [OuterLoop]
+        public void Receive_Events_Async()
+        {
+            ManagementEventWatcher watcher = null;
+            var resetEvent = new ManualResetEvent(false);
+
+            try
+            {
+                // Setup: Timer event is already set up by mof file to fire every 0.1 seconds.
+                // Run: Subscribe __TimerEvent with the specified TimerID
+                watcher = new ManagementEventWatcher(
+                    WmiTestHelper.Namespace,
+                    Query,
+                    new EventWatcherOptions(null, TimeSpan.FromSeconds(5), 1));
+
+                watcher.EventArrived += (object sender, EventArrivedEventArgs args) =>
+                {
+                    ManagementBaseObject newEvent = args.NewEvent;
+                    Assert.True(newEvent["TimerID"].ToString() == "MyEvent", $"Unexpected TimerID value {newEvent["TimerID"]}");
+                    resetEvent.Set();
+                };
+                
+                watcher.Start();
+
+                Assert.True(resetEvent.WaitOne(TimeSpan.FromSeconds(5), true), "Timeout waiting for receive event.");
+            }
+            finally
+            {
+                if (watcher != null)
+                    watcher.Stop();
+            }
+        }
+    }
+}
diff --git a/src/libraries/System.Management/tests/System/Management/ManagementObjectSearcherTests.cs b/src/libraries/System.Management/tests/System/Management/ManagementObjectSearcherTests.cs
new file mode 100644 (file)
index 0000000..c5486dd
--- /dev/null
@@ -0,0 +1,69 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Linq;
+using Xunit;
+
+namespace System.Management.Tests
+{
+    public class ManagementObjectSearcherTests
+    {
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
+        public void Dynamic_Instances()
+        {
+            using (var searcher = new ManagementObjectSearcher())
+            {
+                const string targetClass = "Win32_Process";
+                var selectQuery = new SelectQuery(targetClass);
+                searcher.Query = selectQuery;
+                ManagementObjectCollection instances = searcher.Get();
+                Assert.True(instances.Count > 0);
+                foreach (ManagementObject instance in instances)
+                    Assert.Equal(targetClass, instance.Path.ClassName);
+            }
+        }
+
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
+        [OuterLoop]
+        public void Related_Instances()
+        {
+            using (var searcher = new ManagementObjectSearcher())
+            {
+                var relatedObjectQuery = new RelatedObjectQuery($"Win32_LogicalDisk.DeviceID='{WmiTestHelper.SystemDriveId}'");
+                searcher.Query = relatedObjectQuery;
+                ManagementObjectCollection instances = searcher.Get();
+                Assert.True(instances.Count > 0);
+
+                string[] expectedAssociatedInstanceClasses =
+                {
+                    "Win32_Directory", "Win32_DiskPartition", "Win32_ComputerSystem", "Win32_QuotaSetting", "Win32_SystemAccount", "Win32_Group"
+                };
+
+                foreach (ManagementObject instance in instances)
+                    Assert.True(expectedAssociatedInstanceClasses.Contains(instance.Path.ClassName), $"Unexpected instance of class {instance.Path.ClassName}");
+            }
+        }
+
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
+        [OuterLoop]
+        public void Relationship_Classes()
+        {
+            using (var searcher = new ManagementObjectSearcher())
+            {
+                var relationshipQuery = new RelationshipQuery($"Win32_LogicalDisk.DeviceID='{WmiTestHelper.SystemDriveId}'");
+                searcher.Query = relationshipQuery;
+                ManagementObjectCollection instances = searcher.Get();
+                Assert.True(instances.Count > 0);
+
+                string[] expectedReferenceClasses =
+                {
+                    "Win32_LogicalDiskRootDirectory", "Win32_LogicalDiskToPartition", "Win32_SystemDevices", "Win32_VolumeQuotaSetting", "Win32_DiskQuota"
+                };
+
+                foreach (ManagementObject instance in instances)
+                    Assert.True(expectedReferenceClasses.Contains(instance.Path.ClassName), $"Unexpected instance of class {instance.Path.ClassName}");
+            }
+        }
+    }
+}
diff --git a/src/libraries/System.Management/tests/System/Management/ManagementObjectSearcherTestsMofRequired.cs b/src/libraries/System.Management/tests/System/Management/ManagementObjectSearcherTestsMofRequired.cs
new file mode 100644 (file)
index 0000000..f8a5f91
--- /dev/null
@@ -0,0 +1,64 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Xunit;
+
+namespace System.Management.Tests
+{
+    [Collection("Mof Collection")]
+    public class ManagementObjectSearcherTestsMofRequired
+    {
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsElevatedAndSupportsWmi))]
+        [OuterLoop]
+        public void Static_Instances()
+        {
+            using (var searcher = new ManagementObjectSearcher())
+            {
+                const string TestClass = "Class2";
+                searcher.Scope.Path.NamespacePath = WmiTestHelper.Namespace;
+                var selectQuery = new SelectQuery(TestClass);
+                searcher.Query = selectQuery;
+
+                ManagementObjectCollection instances = searcher.Get();
+                Assert.Equal(2, instances.Count);
+                foreach (ManagementObject instance in instances)
+                    Assert.Equal(TestClass, instance.Path.ClassName);
+            }
+        }
+
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsElevatedAndSupportsWmi))]
+        [OuterLoop]
+        public void Static_Related_Instances()
+        {
+            using (var searcher = new ManagementObjectSearcher())
+            {
+                var relatedObjectQuery = new RelatedObjectQuery("Class3.Class3Key='Three2'");
+                searcher.Scope.Path.NamespacePath = WmiTestHelper.Namespace;
+                searcher.Query = relatedObjectQuery;
+                ManagementObjectCollection instances = searcher.Get();
+                Assert.Equal(1, instances.Count);
+
+                foreach (ManagementObject instance in instances)
+                    Assert.Equal("Class4", instance.Path.ClassName);
+            }
+        }
+
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsElevatedAndSupportsWmi))]
+        [OuterLoop]
+        public void Static_Relationship_Classes()
+        {
+            using (var searcher = new ManagementObjectSearcher())
+            {
+                var relationshipQuery = new RelationshipQuery("Class1.MyKey='One2'");
+                searcher.Scope.Path.NamespacePath = WmiTestHelper.Namespace;
+                searcher.Query = relationshipQuery;
+                ManagementObjectCollection instances = searcher.Get();
+                Assert.Equal(1, instances.Count);
+
+                foreach (ManagementObject instance in instances)
+                    Assert.Equal("AssocA", instance.Path.ClassName);
+            }
+        }
+    }
+}
index fdd4e5b..1d28da4 100644 (file)
@@ -2,20 +2,16 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
-using System.Management;
 using Xunit;
 
 namespace System.Management.Tests
 {
-    [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "WMI not supported via UAP")]
     public class ManagementObjectTests
     {
-        private static string s_systemDriveId = Environment.GetEnvironmentVariable("SystemDrive");
-
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
         public void Get_Win32_LogicalDisk()
         {
-            using (ManagementObject obj = new ManagementObject($"Win32_LogicalDisk.DeviceID=\"{s_systemDriveId}\""))
+            using (ManagementObject obj = new ManagementObject($"Win32_LogicalDisk.DeviceID=\"{WmiTestHelper.SystemDriveId}\""))
             {
                 obj.Get();
                 Assert.True(obj.Properties.Count > 0);
@@ -29,10 +25,11 @@ namespace System.Management.Tests
             }
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
+        [OuterLoop]
         public void GetRelated_For_Win32_LogicalDisk()
         {
-            using (ManagementObject obj = new ManagementObject($"Win32_LogicalDisk.DeviceID=\"{s_systemDriveId}\""))
+            using (ManagementObject obj = new ManagementObject($"Win32_LogicalDisk.DeviceID=\"{WmiTestHelper.SystemDriveId}\""))
             using (ManagementObjectCollection relatedCollection = obj.GetRelated())
             {
                 Assert.True(relatedCollection.Count > 0);
@@ -41,7 +38,7 @@ namespace System.Management.Tests
             }
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
         public void Set_Property_Win32_ComputerSystem()
         {
             using (ManagementObject obj = new ManagementObject($"Win32_ComputerSystem.Name=\"{Environment.MachineName}\""))
@@ -50,5 +47,29 @@ namespace System.Management.Tests
                 obj.SetPropertyValue("Workgroup", "WmiTests");
             }
         }
+
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
+        [OuterLoop]
+        public void Invoke_Instance_And_Static_Method_Win32_Process()
+        {
+            var processClass = new ManagementClass("Win32_Process");
+            object[] methodArgs = { "notepad.exe", null, null, 0 };
+
+            object resultObj = processClass.InvokeMethod("Create", methodArgs);
+
+            var resultCode = (uint)resultObj;
+            Assert.Equal(0u, resultCode);
+
+            var processId = (uint)methodArgs[3];
+            Assert.True(0u != processId, $"Unexpected process ID: {processId}");
+
+            var process = new ManagementObject($"Win32_Process.Handle=\"{processId}\"");
+            resultObj = process.InvokeMethod("Terminate", new object[]{ 0 });
+            resultCode = (uint)resultObj;
+            Assert.Equal(0u, resultCode);
+
+            ManagementException managementException = Assert.Throws<ManagementException>(() => process.Get());
+            Assert.Equal(ManagementStatus.NotFound, managementException.ErrorCode);
+        }
     }
 }
index ad5e9fe..c5245f4 100644 (file)
@@ -7,10 +7,9 @@ using Xunit;
 
 namespace System.Management.Tests
 {
-    [SkipOnTargetFramework(TargetFrameworkMonikers.Uap, "WMI not supported via UAP")]
     public class SelectQueryTests
     {
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
         public void Select_Win32_LogicalDisk_ClassName()
         {
             var query = new SelectQuery("Win32_LogicalDisk");
@@ -29,7 +28,7 @@ namespace System.Management.Tests
             }
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
         public void Select_Win32_LogicalDisk_ClassName_Condition()
         {
             var query = new SelectQuery("Win32_LogicalDisk", "DriveType=3");
@@ -47,7 +46,7 @@ namespace System.Management.Tests
             }
         }
 
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+        [ConditionalFact(typeof(WmiTestHelper), nameof(WmiTestHelper.IsWmiSupported))]
         public void Select_All_Win32_LogicalDisk_Wql()
         {
             var query = new SelectQuery("select * from Win32_LogicalDisk");
diff --git a/src/libraries/System.Management/tests/WmiTestHelper.cs b/src/libraries/System.Management/tests/WmiTestHelper.cs
new file mode 100644 (file)
index 0000000..6ca880a
--- /dev/null
@@ -0,0 +1,20 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.IO;
+
+namespace System.Management.Tests
+{
+    public static class WmiTestHelper
+    {
+        private static readonly bool s_isElevated = AdminHelpers.IsProcessElevated();
+        private static readonly bool s_isWmiSupported = PlatformDetection.IsWindows && PlatformDetection.IsNotWindowsNanoServer && !PlatformDetection.IsUap;
+        private static readonly string s_systemDriveId = Path.GetPathRoot(Environment.GetEnvironmentVariable("SystemDrive"));
+
+        public static string Namespace => "root/WmiEBvt";
+        public static string SystemDriveId => s_systemDriveId;
+        public static bool IsWmiSupported => s_isWmiSupported;
+        public static bool IsElevatedAndSupportsWmi => s_isElevated && IsWmiSupported;
+    }
+}