1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System;
6 using System.Collections.Generic;
7 using Xunit;
8 
9 namespace Microsoft.Win32.RegistryTests
10 {
11     public class Registry_SetValue_str_str_obj_valueKind : RegistryTestsBase
12     {
13         public static IEnumerable<object[]> TestObjects { get { return TestData.TestObjects; } }
14 
15         [Theory]
16         [MemberData(nameof(TestObjects))]
SetValueWithUnknownValueKind(int testIndex, object testValue, RegistryValueKind expectedValueKind)17         public void SetValueWithUnknownValueKind(int testIndex, object testValue, RegistryValueKind expectedValueKind)
18         {
19             string valueName = "Testing_" + testIndex.ToString();
20 
21             Registry.SetValue(TestRegistryKey.Name, valueName, testValue, RegistryValueKind.Unknown);
22             Assert.Equal(testValue.ToString(), TestRegistryKey.GetValue(valueName).ToString());
23             Assert.Equal(expectedValueKind, TestRegistryKey.GetValueKind(valueName));
24             TestRegistryKey.DeleteValue(valueName);
25         }
26 
27         [Theory]
28         [MemberData(nameof(TestObjects))]
SetValueWithStringValueKind(int testIndex, object testValue, RegistryValueKind expectedValueKind)29         public void SetValueWithStringValueKind(int testIndex, object testValue, RegistryValueKind expectedValueKind)
30         {
31             string valueName = "Testing_" + testIndex.ToString();
32             expectedValueKind = RegistryValueKind.String;
33 
34             Registry.SetValue(TestRegistryKey.Name, valueName, testValue, expectedValueKind);
35             Assert.Equal(testValue.ToString(), TestRegistryKey.GetValue(valueName).ToString());
36             Assert.Equal(expectedValueKind, TestRegistryKey.GetValueKind(valueName));
37             TestRegistryKey.DeleteValue(valueName);
38         }
39 
40         [Theory]
41         [MemberData(nameof(TestObjects))]
SetValueWithExpandStringValueKind(int testIndex, object testValue, RegistryValueKind expectedValueKind)42         public void SetValueWithExpandStringValueKind(int testIndex, object testValue, RegistryValueKind expectedValueKind)
43         {
44             string valueName = "Testing_" + testIndex.ToString();
45             expectedValueKind = RegistryValueKind.ExpandString;
46 
47             Registry.SetValue(TestRegistryKey.Name, valueName, testValue, expectedValueKind);
48             Assert.Equal(testValue.ToString(), TestRegistryKey.GetValue(valueName).ToString());
49             Assert.Equal(expectedValueKind, TestRegistryKey.GetValueKind(valueName));
50             TestRegistryKey.DeleteValue(valueName);
51         }
52 
53         [Theory]
54         [MemberData(nameof(TestObjects))]
SetValueWithMultiStringValeKind(int testIndex, object testValue, RegistryValueKind expectedValueKind)55         public void SetValueWithMultiStringValeKind(int testIndex, object testValue, RegistryValueKind expectedValueKind)
56         {
57             try
58             {
59                 string valueName = "Testing_" + testIndex.ToString();
60                 expectedValueKind = RegistryValueKind.MultiString;
61 
62                 Registry.SetValue(TestRegistryKey.Name, valueName, testValue, expectedValueKind);
63                 Assert.Equal(testValue.ToString(), TestRegistryKey.GetValue(valueName).ToString());
64                 Assert.Equal(expectedValueKind, TestRegistryKey.GetValueKind(valueName));
65                 TestRegistryKey.DeleteValue(valueName);
66             }
67             catch (ArgumentException)
68             {
69                 Assert.IsNotType<string[]>(testValue);
70             }
71         }
72 
73         [Theory]
74         [MemberData(nameof(TestObjects))]
SetValueWithBinaryValueKind(int testIndex, object testValue, RegistryValueKind expectedValueKind)75         public void SetValueWithBinaryValueKind(int testIndex, object testValue, RegistryValueKind expectedValueKind)
76         {
77             try
78             {
79                 string valueName = "Testing_" + testIndex.ToString();
80                 expectedValueKind = RegistryValueKind.Binary;
81 
82                 Registry.SetValue(TestRegistryKey.Name, valueName, testValue, expectedValueKind);
83                 Assert.Equal(testValue.ToString(), TestRegistryKey.GetValue(valueName).ToString());
84                 Assert.Equal(expectedValueKind, TestRegistryKey.GetValueKind(valueName));
85                 TestRegistryKey.DeleteValue(valueName);
86             }
87             catch (ArgumentException)
88             {
89                 Assert.IsNotType<byte[]>(testValue);
90             }
91         }
92 
93         [Theory]
94         [MemberData(nameof(TestObjects))]
SetValueWithDWordValueKind(int testIndex, object testValue, RegistryValueKind expectedValueKind)95         public void SetValueWithDWordValueKind(int testIndex, object testValue, RegistryValueKind expectedValueKind)
96         {
97             try
98             {
99                 string valueName = "Testing_" + testIndex.ToString();
100                 expectedValueKind = RegistryValueKind.DWord;
101 
102                 Registry.SetValue(TestRegistryKey.Name, valueName, testValue, expectedValueKind);
103                 Assert.Equal(Convert.ToInt32(testValue).ToString(), TestRegistryKey.GetValue(valueName).ToString());
104                 Assert.Equal(expectedValueKind, TestRegistryKey.GetValueKind(valueName));
105                 Assert.True(testIndex <= 15);
106                 TestRegistryKey.DeleteValue(valueName);
107             }
108             catch (ArgumentException ioe)
109             {
110                 Assert.False(testIndex <= 15, ioe.ToString());
111             }
112         }
113 
114         [Theory]
115         [MemberData(nameof(TestObjects))]
SetValueWithQWordValueKind(int testIndex, object testValue, RegistryValueKind expectedValueKind)116         public void SetValueWithQWordValueKind(int testIndex, object testValue, RegistryValueKind expectedValueKind)
117         {
118             try
119             {
120                 string valueName = "Testing_" + testIndex.ToString();
121                 expectedValueKind = RegistryValueKind.QWord;
122 
123                 Registry.SetValue(TestRegistryKey.Name, valueName, testValue, expectedValueKind);
124                 Assert.Equal(Convert.ToInt64(testValue).ToString(), TestRegistryKey.GetValue(valueName).ToString());
125                 Assert.Equal(expectedValueKind, TestRegistryKey.GetValueKind(valueName));
126                 Assert.True(testIndex <= 25);
127                 TestRegistryKey.DeleteValue(valueName);
128             }
129             catch (ArgumentException ioe)
130             {
131                 Assert.False(testIndex <= 25, ioe.ToString());
132             }
133         }
134 
135         [Fact]
SetValueForNonExistingKey()136         public void SetValueForNonExistingKey()
137         {
138             const string valueName = "FooBar";
139             const int expectedValue1 = int.MaxValue;
140             const long expectedValue2 = long.MinValue;
141             const RegistryValueKind expectedValueKind1 = RegistryValueKind.DWord;
142             const RegistryValueKind expectedValueKind2 = RegistryValueKind.QWord;
143 
144             Assert.True(TestRegistryKey.GetValue(valueName) == null, "Registry key already exists");
145             Registry.SetValue(TestRegistryKey.Name, valueName, expectedValue1, expectedValueKind1);
146             Assert.True(TestRegistryKey.GetValue(valueName) != null, "Registry key doesn't exists");
147             Assert.Equal(expectedValue1, (int)TestRegistryKey.GetValue(valueName));
148             Assert.Equal(expectedValueKind1, TestRegistryKey.GetValueKind(valueName));
149 
150             Registry.SetValue(TestRegistryKey.Name, valueName, expectedValue2, expectedValueKind2);
151             Assert.Equal(expectedValue2, (long)TestRegistryKey.GetValue(valueName));
152             Assert.Equal(expectedValueKind2, TestRegistryKey.GetValueKind(valueName));
153         }
154 
155         public static IEnumerable<object[]> TestValueNames { get { return TestData.TestValueNames; } }
156 
157         [Theory]
158         [MemberData(nameof(TestValueNames))]
SetValueWithNameTest(string valueName)159         public void SetValueWithNameTest(string valueName)
160         {
161             const long expectedValue = long.MaxValue;
162             const RegistryValueKind expectedValueKind = RegistryValueKind.QWord;
163 
164             Registry.SetValue(TestRegistryKey.Name, valueName, expectedValue, expectedValueKind);
165             Assert.Equal(expectedValue, (long)TestRegistryKey.GetValue(valueName));
166             Assert.Equal(expectedValueKind, TestRegistryKey.GetValueKind(valueName));
167         }
168 
169         [Fact]
NegativeTests()170         public void NegativeTests()
171         {
172             // Should throw if key length above 255 characters but prior to V4 the limit is 16383
173             const int maxValueNameLength = 16383;
174             var valueName = new string('a', maxValueNameLength + 1);
175             AssertExtensions.Throws<ArgumentException>("name", null, () => Registry.SetValue(TestRegistryKey.Name, valueName, ulong.MaxValue, RegistryValueKind.String));
176 
177             valueName = "FooBar";
178             // Should throw if passed value is null
179             Assert.Throws<ArgumentNullException>(() => Registry.SetValue(TestRegistryKey.Name, valueName, null, RegistryValueKind.QWord));
180 
181             // Should throw because valueKind is equal to -2 which is not an acceptable value
182             AssertExtensions.Throws<ArgumentException>("valueKind", () => Registry.SetValue(TestRegistryKey.Name, valueName, int.MinValue, (RegistryValueKind)(-2)));
183 
184             // Should throw because passed array contains null
185             string[] strArr = { "one", "two", null, "three" };
186             AssertExtensions.Throws<ArgumentException>(null, () => Registry.SetValue(TestRegistryKey.Name, valueName, strArr, RegistryValueKind.MultiString));
187 
188             // Should throw because passed array has wrong type
189             AssertExtensions.Throws<ArgumentException>(null, () => Registry.SetValue(TestRegistryKey.Name, valueName, new[] { new object() }, RegistryValueKind.MultiString));
190 
191             // Should throw because passed array has wrong type
192             object[] objTemp = { "my string", "your string", "Any once string" };
193             AssertExtensions.Throws<ArgumentException>(null, () => Registry.SetValue(TestRegistryKey.Name, valueName, objTemp, RegistryValueKind.Unknown));
194         }
195     }
196 }
197