Skip to content

Commit 47c87f2

Browse files
author
BRUNER Patrick
committed
update unit tests and missing function
1 parent a78d204 commit 47c87f2

3 files changed

Lines changed: 103 additions & 82 deletions

File tree

src/PluginRegistry/PluginRegistry.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -673,10 +673,27 @@ private bool LoadPluginAssemblySafe (string dllName, PluginManifest? manifest)
673673
if (_usePluginCache && _pluginCache != null)
674674
{
675675
var result = _pluginCache.LoadPluginWithCache(dllName);
676-
if (result.Success && result.Plugin != null)
676+
677+
if (result.Success)
677678
{
678-
ProcessLoadedPlugin(result.Plugin, manifest, dllName);
679-
return true;
679+
// Process ALL plugins from the result, not just the first one
680+
if (result.AllPlugins != null && result.AllPlugins.Count > 0)
681+
{
682+
_logger.Info("Processing {Count} plugin(s) from cache for {FileName}", result.AllPlugins.Count, Path.GetFileName(dllName));
683+
684+
foreach (var plugin in result.AllPlugins)
685+
{
686+
ProcessLoadedPlugin(plugin, manifest, dllName);
687+
}
688+
689+
return true;
690+
}
691+
else if (result.Plugin != null)
692+
{
693+
// Fallback for backward compatibility
694+
ProcessLoadedPlugin(result.Plugin, manifest, dllName);
695+
return true;
696+
}
680697
}
681698

682699
_logger.Warn("Cache load failed for {Plugin}, falling back to direct load", Path.GetFileName(dllName));

src/RegexColumnizer.UnitTests/RegexColumnizerErrorHandlingTests.cs

Lines changed: 52 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using System.Runtime.Versioning;
2+
23
using LogExpert;
4+
35
using Moq;
6+
47
using NUnit.Framework;
58

69
[assembly: SupportedOSPlatform("windows")]
@@ -12,14 +15,14 @@ public class RegexColumnizerErrorHandlingTests
1215
private string _testDirectory;
1316

1417
[SetUp]
15-
public void SetUp()
18+
public void SetUp ()
1619
{
17-
_testDirectory = Path.Combine(Path.GetTempPath(), $"LogExpertTest_{Guid.NewGuid()}");
18-
Directory.CreateDirectory(_testDirectory);
20+
_testDirectory = Path.Join(Path.GetTempPath(), $"LogExpertTest_{Guid.NewGuid()}");
21+
_ = Directory.CreateDirectory(_testDirectory);
1922
}
2023

2124
[TearDown]
22-
public void TearDown()
25+
public void TearDown ()
2326
{
2427
if (Directory.Exists(_testDirectory))
2528
{
@@ -35,7 +38,7 @@ public void TearDown()
3538
}
3639

3740
[Test]
38-
public void Init_InvalidRegex_SetsRegexToNullAndUsesEmptyColumns()
41+
public void Init_InvalidRegex_SetsRegexToNullAndUsesEmptyColumns ()
3942
{
4043
// Arrange
4144
var config = new RegexColumnizerConfig
@@ -45,8 +48,8 @@ public void Init_InvalidRegex_SetsRegexToNullAndUsesEmptyColumns()
4548
};
4649

4750
var columnizer = new Regex1Columnizer();
48-
49-
var configField = typeof(BaseRegexColumnizer).GetField("_config",
51+
52+
var configField = typeof(BaseRegexColumnizer).GetField("_config",
5053
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
5154
configField?.SetValue(columnizer, config);
5255

@@ -60,7 +63,7 @@ public void Init_InvalidRegex_SetsRegexToNullAndUsesEmptyColumns()
6063
}
6164

6265
[Test]
63-
public void Init_CatastrophicBacktracking_HandledByRegexHelper()
66+
public void Init_CatastrophicBacktracking_HandledByRegexHelper ()
6467
{
6568
// Arrange - This pattern can cause catastrophic backtracking
6669
var config = new RegexColumnizerConfig
@@ -70,8 +73,8 @@ public void Init_CatastrophicBacktracking_HandledByRegexHelper()
7073
};
7174

7275
var columnizer = new Regex1Columnizer();
73-
74-
var configField = typeof(BaseRegexColumnizer).GetField("_config",
76+
77+
var configField = typeof(BaseRegexColumnizer).GetField("_config",
7578
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
7679
configField?.SetValue(columnizer, config);
7780

@@ -85,19 +88,19 @@ public void Init_CatastrophicBacktracking_HandledByRegexHelper()
8588
}
8689

8790
[Test]
88-
public void SplitLine_NullRegex_PlacesEntireLineInFirstColumn()
91+
public void SplitLine_NullRegex_PlacesEntireLineInFirstColumn ()
8992
{
9093
// Arrange
9194
var columnizer = new Regex1Columnizer();
92-
95+
9396
// Set invalid regex to make Regex null
9497
var config = new RegexColumnizerConfig
9598
{
9699
Expression = "(?<invalid",
97100
Name = "Test"
98101
};
99-
100-
var configField = typeof(BaseRegexColumnizer).GetField("_config",
102+
103+
var configField = typeof(BaseRegexColumnizer).GetField("_config",
101104
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
102105
configField?.SetValue(columnizer, config);
103106
columnizer.Init();
@@ -115,10 +118,10 @@ public void SplitLine_NullRegex_PlacesEntireLineInFirstColumn()
115118
}
116119

117120
[Test]
118-
public void LoadConfig_CorruptJsonFile_DisplaysErrorAndUsesDefaults()
121+
public void LoadConfig_CorruptJsonFile_DisplaysErrorAndUsesDefaults ()
119122
{
120123
// Arrange
121-
string jsonPath = Path.Combine(_testDirectory, "Regex1Columnizer.json");
124+
string jsonPath = Path.Join(_testDirectory, "Regex1Columnizer.json");
122125
File.WriteAllText(jsonPath, "{ corrupt json content }");
123126

124127
var columnizer = new Regex1Columnizer();
@@ -132,7 +135,7 @@ public void LoadConfig_CorruptJsonFile_DisplaysErrorAndUsesDefaults()
132135
}
133136

134137
[Test]
135-
public void LoadConfig_FileSystemError_HandlesGracefully()
138+
public void LoadConfig_FileSystemError_HandlesGracefully ()
136139
{
137140
// Arrange
138141
string invalidPath = "Z:\\NonExistent\\Path\\That\\Does\\Not\\Exist";
@@ -147,7 +150,7 @@ public void LoadConfig_FileSystemError_HandlesGracefully()
147150
}
148151

149152
[Test]
150-
public void LoadConfig_EmptyConfigDirectory_UsesDefaults()
153+
public void LoadConfig_EmptyConfigDirectory_UsesDefaults ()
151154
{
152155
// Arrange
153156
var columnizer = new Regex1Columnizer();
@@ -161,10 +164,10 @@ public void LoadConfig_EmptyConfigDirectory_UsesDefaults()
161164
}
162165

163166
[Test]
164-
public void LoadConfig_CorruptXmlFile_DisplaysErrorAndUsesDefaults()
167+
public void LoadConfig_CorruptXmlFile_DisplaysErrorAndUsesDefaults ()
165168
{
166169
// Arrange
167-
string xmlPath = Path.Combine(_testDirectory, "Regex1Columnizer.xml");
170+
string xmlPath = Path.Join(_testDirectory, "Regex1Columnizer.xml");
168171
File.WriteAllText(xmlPath, "<InvalidXml>No closing tag");
169172

170173
var columnizer = new Regex1Columnizer();
@@ -177,7 +180,7 @@ public void LoadConfig_CorruptXmlFile_DisplaysErrorAndUsesDefaults()
177180
}
178181

179182
[Test]
180-
public void SplitLine_EmptyColumnValues_HandlesGracefully()
183+
public void SplitLine_EmptyColumnValues_HandlesGracefully ()
181184
{
182185
// Arrange
183186
var columnizer = CreateColumnizer(@"^(?<col1>\d*)\s+(?<col2>\w*)$");
@@ -192,7 +195,7 @@ public void SplitLine_EmptyColumnValues_HandlesGracefully()
192195
}
193196

194197
[Test]
195-
public void SplitLine_VeryComplexRegex_CompletesInReasonableTime()
198+
public void SplitLine_VeryComplexRegex_CompletesInReasonableTime ()
196199
{
197200
// Arrange - Complex but safe regex
198201
var columnizer = CreateColumnizer(
@@ -201,8 +204,8 @@ public void SplitLine_VeryComplexRegex_CompletesInReasonableTime()
201204
@"\[(?<thread>[^\]]+)\]\s+" +
202205
@"(?<logger>[^\s]+)\s+" +
203206
@"(?<message>.*)$");
204-
205-
var testLogLine = new TestLogLine(1,
207+
208+
var testLogLine = new TestLogLine(1,
206209
"2023-11-21 14:30:45,123 ERROR [main-thread-1] com.example.MyClass Error message here");
207210

208211
// Act
@@ -216,7 +219,7 @@ public void SplitLine_VeryComplexRegex_CompletesInReasonableTime()
216219
}
217220

218221
[Test]
219-
public void GetName_ConfigNameIsNull_ReturnsDefaultName()
222+
public void GetName_ConfigNameIsNull_ReturnsDefaultName ()
220223
{
221224
// Arrange
222225
var config = new RegexColumnizerConfig
@@ -226,8 +229,8 @@ public void GetName_ConfigNameIsNull_ReturnsDefaultName()
226229
};
227230

228231
var columnizer = new Regex1Columnizer();
229-
230-
var configField = typeof(BaseRegexColumnizer).GetField("_config",
232+
233+
var configField = typeof(BaseRegexColumnizer).GetField("_config",
231234
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
232235
configField?.SetValue(columnizer, config);
233236

@@ -239,7 +242,7 @@ public void GetName_ConfigNameIsNull_ReturnsDefaultName()
239242
}
240243

241244
[Test]
242-
public void GetName_ConfigNameIsWhitespace_ReturnsDefaultName()
245+
public void GetName_ConfigNameIsWhitespace_ReturnsDefaultName ()
243246
{
244247
// Arrange
245248
var config = new RegexColumnizerConfig
@@ -249,8 +252,8 @@ public void GetName_ConfigNameIsWhitespace_ReturnsDefaultName()
249252
};
250253

251254
var columnizer = new Regex1Columnizer();
252-
253-
var configField = typeof(BaseRegexColumnizer).GetField("_config",
255+
256+
var configField = typeof(BaseRegexColumnizer).GetField("_config",
254257
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
255258
configField?.SetValue(columnizer, config);
256259

@@ -262,7 +265,7 @@ public void GetName_ConfigNameIsWhitespace_ReturnsDefaultName()
262265
}
263266

264267
[Test]
265-
public void Init_EmptyExpression_HandlesGracefully()
268+
public void Init_EmptyExpression_HandlesGracefully ()
266269
{
267270
// Arrange
268271
var config = new RegexColumnizerConfig
@@ -272,8 +275,8 @@ public void Init_EmptyExpression_HandlesGracefully()
272275
};
273276

274277
var columnizer = new Regex1Columnizer();
275-
276-
var configField = typeof(BaseRegexColumnizer).GetField("_config",
278+
279+
var configField = typeof(BaseRegexColumnizer).GetField("_config",
277280
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
278281
configField?.SetValue(columnizer, config);
279282

@@ -288,7 +291,7 @@ public void Init_EmptyExpression_HandlesGracefully()
288291
}
289292

290293
[Test]
291-
public void SplitLine_MultipleNonMatchingLines_HandlesConsistently()
294+
public void SplitLine_MultipleNonMatchingLines_HandlesConsistently ()
292295
{
293296
// Arrange
294297
var columnizer = CreateColumnizer(@"^(?<number>\d+)\s+(?<text>.*)$");
@@ -303,14 +306,14 @@ public void SplitLine_MultipleNonMatchingLines_HandlesConsistently()
303306
foreach (var line in lines)
304307
{
305308
var result = columnizer.SplitLine(Mock.Of<ILogLineColumnizerCallback>(), line);
306-
309+
307310
Assert.That(result.ColumnValues.Length, Is.EqualTo(2));
308311
Assert.That(result.ColumnValues[0].Text, Is.Empty); // First column empty
309312
Assert.That(result.ColumnValues[1].Text, Is.EqualTo(line.FullLine)); // Full line in last column
310313
}
311314
}
312315

313-
private Regex1Columnizer CreateColumnizer(string regex)
316+
private Regex1Columnizer CreateColumnizer (string regex)
314317
{
315318
var config = new RegexColumnizerConfig
316319
{
@@ -319,34 +322,34 @@ private Regex1Columnizer CreateColumnizer(string regex)
319322
};
320323

321324
var columnizer = new Regex1Columnizer();
322-
323-
var configField = typeof(BaseRegexColumnizer).GetField("_config",
325+
326+
var configField = typeof(BaseRegexColumnizer).GetField("_config",
324327
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
325328
configField?.SetValue(columnizer, config);
326-
329+
327330
columnizer.Init();
328-
331+
329332
return columnizer;
330333
}
331334

332335
#region Security Tests (SEC-02)
333336

334337
[Test]
335-
public void Configure_ValidatesPathTraversal_WithDoubleDots()
338+
public void Configure_ValidatesPathTraversal_WithDoubleDots ()
336339
{
337340
// This test ensures that GetConfigFileJSON validates the columnizer name
338341
// We can't directly test private methods, but Configure calls GetConfigFileJSON
339342
// Since columnizer name comes from GetType().Name, this is more of a defensive test
340-
343+
341344
// Arrange
342345
var columnizer = new Regex1Columnizer();
343-
string testDir = Path.Combine(_testDirectory, "security_test");
346+
string testDir = Path.Join(_testDirectory, "security_test");
344347
_ = Directory.CreateDirectory(testDir);
345348

346349
// Act & Assert - Normal operation should work fine
347350
// The security validation happens inside GetConfigFileJSON
348351
Assert.DoesNotThrow(() => columnizer.LoadConfig(testDir));
349-
352+
350353
// Cleanup
351354
if (Directory.Exists(testDir))
352355
{
@@ -355,18 +358,18 @@ public void Configure_ValidatesPathTraversal_WithDoubleDots()
355358
}
356359

357360
[Test]
358-
public void Configure_ConfigDirectoryWithSpecialChars_HandledCorrectly()
361+
public void Configure_ConfigDirectoryWithSpecialChars_HandledCorrectly ()
359362
{
360363
// Arrange
361364
var columnizer = new Regex1Columnizer();
362-
365+
363366
// Test with directory containing spaces and valid special characters
364-
string testDir = Path.Combine(_testDirectory, "test config (v1.0)");
367+
string testDir = Path.Join(_testDirectory, "test config (v1.0)");
365368
_ = Directory.CreateDirectory(testDir);
366369

367370
// Act & Assert - Should handle directory names with spaces and parentheses
368371
Assert.DoesNotThrow(() => columnizer.LoadConfig(testDir));
369-
372+
370373
// Cleanup
371374
if (Directory.Exists(testDir))
372375
{
@@ -378,7 +381,7 @@ public void Configure_ConfigDirectoryWithSpecialChars_HandledCorrectly()
378381

379382
private class TestLogLine : ILogLine
380383
{
381-
public TestLogLine(int lineNumber, string fullLine)
384+
public TestLogLine (int lineNumber, string fullLine)
382385
{
383386
LineNumber = lineNumber;
384387
FullLine = fullLine;

0 commit comments

Comments
 (0)