-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIntegrationTests.cs
More file actions
260 lines (223 loc) · 8.31 KB
/
IntegrationTests.cs
File metadata and controls
260 lines (223 loc) · 8.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
using System.Runtime.InteropServices;
using System.Text.Json;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace DemaConsulting.DotnetToolWrapper.Tests;
/// <summary>
/// Integration tests for the DotnetToolWrapper application
/// </summary>
[TestClass]
public class IntegrationTests
{
/// <summary>
/// Test setup directory
/// </summary>
private string _testDirectory = string.Empty;
/// <summary>
/// Initialize test
/// </summary>
[TestInitialize]
public void TestInitialize()
{
// Create a unique test directory
_testDirectory = Path.Combine(Path.GetTempPath(), $"DotnetToolWrapperTests_{Guid.NewGuid()}");
Directory.CreateDirectory(_testDirectory);
}
/// <summary>
/// Cleanup test
/// </summary>
[TestCleanup]
public void TestCleanup()
{
// Clean up test directory
if (Directory.Exists(_testDirectory))
{
Directory.Delete(_testDirectory, true);
}
// Clean up config file next to DLL
var dllPath = GetDotnetToolWrapperDllPath();
var dllDirectory = Path.GetDirectoryName(dllPath);
if (dllDirectory != null)
{
var configPath = Path.Combine(dllDirectory, "DotnetToolWrapper.json");
if (File.Exists(configPath))
{
File.Delete(configPath);
}
}
}
/// <summary>
/// Get the path to the DotnetToolWrapper DLL
/// </summary>
/// <returns>Path to DLL</returns>
private static string GetDotnetToolWrapperDllPath()
{
var assemblyLocation = Path.GetDirectoryName(typeof(IntegrationTests).Assembly.Location);
Assert.IsNotNull(assemblyLocation, "Assembly location should not be null");
return Path.Combine(assemblyLocation, "DemaConsulting.DotnetToolWrapper.dll");
}
/// <summary>
/// Create a DotnetToolWrapper.json configuration file
/// </summary>
/// <param name="program">Program to execute</param>
/// <param name="directory">Directory for config file (defaults to DLL directory)</param>
private static void CreateConfigFile(string program, string? directory = null)
{
// Default to DLL directory
if (directory == null)
{
var dllPath = GetDotnetToolWrapperDllPath();
directory = Path.GetDirectoryName(dllPath);
Assert.IsNotNull(directory, "DLL directory should not be null");
}
var target = Program.GetTarget();
var json = JsonSerializer.Serialize(new Dictionary<string, object>
{
{ target, new { program } }
});
File.WriteAllText(Path.Combine(directory, "DotnetToolWrapper.json"), json);
}
/// <summary>
/// Get the shell program name for the current OS
/// </summary>
/// <returns>Shell program name</returns>
private static string GetShellProgram()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// Use COMSPEC environment variable to get full path to cmd.exe
var comspec = Environment.GetEnvironmentVariable("COMSPEC");
return comspec ?? throw new InvalidOperationException("COMSPEC environment variable not found");
}
return "/bin/sh";
}
/// <summary>
/// Get shell arguments for exit code test
/// </summary>
/// <param name="exitCode">Exit code to test</param>
/// <returns>Shell arguments</returns>
private static string[] GetExitCodeArgs(int exitCode)
{
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? ["/c", $"exit {exitCode}"]
: ["-c", $"exit {exitCode}"];
}
/// <summary>
/// Get shell arguments for echo test
/// </summary>
/// <param name="text">Text to echo</param>
/// <returns>Shell arguments</returns>
private static string[] GetEchoArgs(string text)
{
return RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? ["/c", $"echo {text}"]
: ["-c", $"echo {text}"];
}
/// <summary>
/// Test that missing configuration file results in expected error
/// </summary>
[TestMethod]
public void TestMissingConfigFile()
{
// Arrange
var dllPath = GetDotnetToolWrapperDllPath();
// Act
var exitCode = Runner.Run(out var output, "dotnet", dllPath);
// Assert
Assert.AreEqual(1, exitCode, "Exit code should be 1 for missing config file");
Assert.Contains("Missing configuration file", output, "Output should mention missing config file");
Assert.Contains("DotnetToolWrapper.json", output, "Output should mention config file name");
}
/// <summary>
/// Test that exit codes are properly passed through
/// </summary>
[TestMethod]
[DataRow(0)]
[DataRow(1)]
[DataRow(42)]
[DataRow(255)]
public void TestExitCodes(int expectedExitCode)
{
// Arrange
var dllPath = GetDotnetToolWrapperDllPath();
var shellProgram = GetShellProgram();
// Create config file pointing to shell
CreateConfigFile(shellProgram);
// Get shell arguments to exit with specific code
var shellArgs = GetExitCodeArgs(expectedExitCode);
// Prepare arguments for dotnet command
var args = new List<string> { dllPath };
args.AddRange(shellArgs);
// Act
var exitCode = Runner.Run(out _, "dotnet", args.ToArray());
// Assert
Assert.AreEqual(expectedExitCode, exitCode, $"Exit code should be {expectedExitCode}");
}
/// <summary>
/// Test that arguments are properly passed through
/// </summary>
[TestMethod]
public void TestArgumentPassing()
{
// Arrange
var dllPath = GetDotnetToolWrapperDllPath();
var shellProgram = GetShellProgram();
var testText = "HelloWorld";
// Create config file pointing to shell
CreateConfigFile(shellProgram);
// Get shell arguments to echo text
var shellArgs = GetEchoArgs(testText);
// Prepare arguments for dotnet command
var args = new List<string> { dllPath };
args.AddRange(shellArgs);
// Act
var exitCode = Runner.Run(out var output, "dotnet", args.ToArray());
// Assert
Assert.AreEqual(0, exitCode, "Exit code should be 0");
Assert.Contains(testText, output, $"Output should contain '{testText}'");
}
/// <summary>
/// Test that unsupported target results in expected error
/// </summary>
[TestMethod]
public void TestUnsupportedTarget()
{
// Arrange
var dllPath = GetDotnetToolWrapperDllPath();
var dllDirectory = Path.GetDirectoryName(dllPath);
Assert.IsNotNull(dllDirectory, "DLL directory should not be null");
// Create config file with fake target
var json = JsonSerializer.Serialize(new Dictionary<string, object>
{
{ "fake-target", new { program = "fake" } }
});
File.WriteAllText(Path.Combine(dllDirectory, "DotnetToolWrapper.json"), json);
// Act
var exitCode = Runner.Run(out var output, "dotnet", dllPath);
// Assert
Assert.AreEqual(1, exitCode, "Exit code should be 1 for unsupported target");
Assert.Contains("does not support", output, "Output should mention unsupported target");
}
/// <summary>
/// Test that bad configuration results in expected error
/// </summary>
[TestMethod]
public void TestBadConfiguration()
{
// Arrange
var dllPath = GetDotnetToolWrapperDllPath();
var dllDirectory = Path.GetDirectoryName(dllPath);
Assert.IsNotNull(dllDirectory, "DLL directory should not be null");
var target = Program.GetTarget();
// Create config file without program property
var json = JsonSerializer.Serialize(new Dictionary<string, object>
{
{ target, new { notprogram = "fake" } }
});
File.WriteAllText(Path.Combine(dllDirectory, "DotnetToolWrapper.json"), json);
// Act
var exitCode = Runner.Run(out var output, "dotnet", dllPath);
// Assert
Assert.AreEqual(1, exitCode, "Exit code should be 1 for bad configuration");
Assert.Contains("Bad configuration", output, "Output should mention bad configuration");
}
}