Skip to content

Commit 56e5ebe

Browse files
authored
Ensure PluginOptionsSystem.CreateForFile creates the directory containing the specified file. (#414)
1 parent 518de8c commit 56e5ebe

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

src/Microsoft.Performance.SDK.Runtime.Tests/Options/PluginOptionsSystemTests.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.IO;
67
using System.Linq;
78
using System.Threading.Tasks;
89
using Microsoft.Performance.SDK.Options;
@@ -125,6 +126,42 @@ public async Task TrySaveCurrentRegistry_LoaderFails_FailsToSave()
125126
Assert.IsFalse(await sut.TrySaveCurrentRegistry());
126127
}
127128

129+
[TestMethod]
130+
[DataRow(null)]
131+
[DataRow("")]
132+
[DataRow(" ")]
133+
[DataRow("\t")]
134+
[DataRow(@"C:\Foo?<>.json")]
135+
[DataRow(@"C:\")]
136+
[DataRow(@"bar.json")]
137+
[DataRow(@":C:\Foo\bar.json")]
138+
[DataRow(@"C:\Foo\:bar.json")]
139+
public void BadFilePath_ThrowsArgumentException(string filePath)
140+
{
141+
Assert.ThrowsException<ArgumentException>(() =>
142+
{
143+
PluginOptionsSystem.CreateForFile(null, (_) => new NullLogger());
144+
});
145+
}
146+
147+
[TestMethod]
148+
public void LongFilePath_ThrowsPathTooLongException()
149+
{
150+
Assert.ThrowsException<PathTooLongException>(() =>
151+
{
152+
PluginOptionsSystem.CreateForFile(Path.Combine(@"C:\", new string('a', 50000), "foo.json"), (_) => new NullLogger());
153+
});
154+
}
155+
156+
[TestMethod]
157+
public void UnknownNetworkPath_ThrowsDirectoryNotFoundException()
158+
{
159+
Assert.ThrowsException<DirectoryNotFoundException>(() =>
160+
{
161+
PluginOptionsSystem.CreateForFile(@"\\randomServer\C$\foo.json", (_) => new NullLogger());
162+
});
163+
}
164+
128165
private PluginOptionsSystem CreateSut(params IProcessingSource[] processingSources)
129166
{
130167
var sut = PluginOptionsSystem.CreateUnsaved((_) => new NullLogger());

src/Microsoft.Performance.SDK.Runtime/Options/PluginOptionsSystem.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.IO;
67
using System.Linq;
78
using System.Threading.Tasks;
89
using Microsoft.Performance.SDK.Options;
@@ -32,10 +33,46 @@ public sealed class PluginOptionsSystem
3233
/// <returns>
3334
/// A new instance of <see cref="PluginOptionsSystem"/> that persists options to a file.
3435
/// </returns>
36+
/// <exception cref="T:System.ArgumentException">
37+
/// The <paramref name="filePath" /> parameter contains invalid characters, is empty, is null, or contains only white spaces.
38+
///
39+
/// -- or --
40+
///
41+
/// The <paramref name="filePath" /> parameter is prefixed with, or contains, only a colon character (:)
42+
///
43+
/// -- or --
44+
///
45+
/// The <paramref name="filePath" /> parameter refers to the root directory of a volume.
46+
///
47+
/// -- or --
48+
///
49+
/// The <paramref name="filePath" /> parameter does not contain directory information.
50+
/// </exception>
51+
/// <exception cref="T:System.IO.PathTooLongException">
52+
/// The <paramref name="filePath" /> parameter is longer than the system-defined maximum length.
53+
/// </exception>
54+
/// <exception cref="T:System.IO.IOException">
55+
/// The <paramref name="filePath"/> maps to a network whose name is not known.
56+
/// </exception>
57+
/// <exception cref="T:System.UnauthorizedAccessException">
58+
/// The caller does not have the required permission to access <paramref name="filePath"/>.
59+
/// </exception>
60+
/// <exception cref="T:System.IO.DirectoryNotFoundException">
61+
/// The specified <paramref name="filePath" /> is invalid (for example, it is on an unmapped drive).
62+
/// </exception>
3563
public static PluginOptionsSystem CreateForFile(
3664
string filePath,
3765
Func<Type, ILogger> loggerFactory)
3866
{
67+
var directory = Path.GetDirectoryName(filePath);
68+
69+
if (string.IsNullOrEmpty(directory))
70+
{
71+
throw new ArgumentException("Cannot get directory from file path.", nameof(filePath));
72+
}
73+
74+
Directory.CreateDirectory(directory);
75+
3976
var loader = new FilePluginOptionsLoader(filePath, loggerFactory(typeof(FilePluginOptionsLoader)));
4077
var saver = new FilePluginOptionsSaver(filePath, loggerFactory(typeof(FilePluginOptionsSaver)));
4178
var registry = new PluginOptionsRegistry(loggerFactory(typeof(PluginOptionsRegistry)));

0 commit comments

Comments
 (0)