OpenTelemetrySdkMinimumVersionRule tests (#2420)
* Test changes. * PR feedback
This commit is contained in:
parent
782bf618cf
commit
d2df8de6f5
|
@ -22,7 +22,7 @@ namespace OpenTelemetry.AutoInstrumentation.RulesEngine;
|
|||
|
||||
internal class OpenTelemetrySdkMinimumVersionRule : Rule
|
||||
{
|
||||
private static readonly IOtelLogger Logger = OtelLogging.GetLogger("StartupHook");
|
||||
private static IOtelLogger logger = OtelLogging.GetLogger("StartupHook");
|
||||
|
||||
public OpenTelemetrySdkMinimumVersionRule()
|
||||
{
|
||||
|
@ -30,41 +30,67 @@ internal class OpenTelemetrySdkMinimumVersionRule : Rule
|
|||
Description = "Ensure that the OpenTelemetry SDK version is not older than the version used by the Auto-Instrumentation";
|
||||
}
|
||||
|
||||
// This constructor is used for test purpose.
|
||||
protected OpenTelemetrySdkMinimumVersionRule(IOtelLogger otelLogger)
|
||||
: this()
|
||||
{
|
||||
logger = otelLogger;
|
||||
}
|
||||
|
||||
internal override bool Evaluate()
|
||||
{
|
||||
string? oTelPackageVersion = null;
|
||||
|
||||
try
|
||||
{
|
||||
var openTelemetryType = Type.GetType("OpenTelemetry.Sdk, OpenTelemetry");
|
||||
if (openTelemetryType != null)
|
||||
var loadedOTelFileVersion = GetVersionFromApp();
|
||||
if (loadedOTelFileVersion != null)
|
||||
{
|
||||
var loadedOTelAssembly = Assembly.GetAssembly(openTelemetryType);
|
||||
var loadedOTelFileVersionInfo = FileVersionInfo.GetVersionInfo(loadedOTelAssembly?.Location);
|
||||
var loadedOTelFileVersion = new Version(loadedOTelFileVersionInfo.FileVersion);
|
||||
|
||||
var autoInstrumentationOTelLocation = Path.Combine(StartupHook.LoaderAssemblyLocation ?? string.Empty, "OpenTelemetry.dll");
|
||||
var autoInstrumentationOTelFileVersionInfo = FileVersionInfo.GetVersionInfo(autoInstrumentationOTelLocation);
|
||||
var autoInstrumentationOTelFileVersion = new Version(autoInstrumentationOTelFileVersionInfo.FileVersion);
|
||||
|
||||
var autoInstrumentationOTelFileVersion = GetVersionFromAutoInstrumentation();
|
||||
if (loadedOTelFileVersion < autoInstrumentationOTelFileVersion)
|
||||
{
|
||||
oTelPackageVersion = loadedOTelFileVersionInfo.FileVersion;
|
||||
oTelPackageVersion = loadedOTelFileVersion.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Exception in evaluation should not throw or crash the process.
|
||||
Logger.Information($"Couldn't evaluate reference to OpenTelemetry Sdk in an app. Exception: {ex}");
|
||||
logger.Information($"Rule Engine: Couldn't evaluate reference to OpenTelemetry Sdk in an app. Exception: {ex}");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (oTelPackageVersion != null)
|
||||
{
|
||||
Logger.Error($"Application has direct or indirect reference to older version of OpenTelemetry package {oTelPackageVersion}.");
|
||||
logger.Error($"Rule Engine: Application has direct or indirect reference to older version of OpenTelemetry package {oTelPackageVersion}.");
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.Information("Rule Engine: OpenTelemetrySdkMinimumVersionRule evaluation success.");
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual Version? GetVersionFromApp()
|
||||
{
|
||||
var openTelemetryType = Type.GetType("OpenTelemetry.Sdk, OpenTelemetry");
|
||||
if (openTelemetryType != null)
|
||||
{
|
||||
var loadedOTelAssembly = Assembly.GetAssembly(openTelemetryType);
|
||||
var loadedOTelFileVersionInfo = FileVersionInfo.GetVersionInfo(loadedOTelAssembly?.Location);
|
||||
var loadedOTelFileVersion = new Version(loadedOTelFileVersionInfo.FileVersion);
|
||||
|
||||
return loadedOTelFileVersion;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual Version? GetVersionFromAutoInstrumentation()
|
||||
{
|
||||
var autoInstrumentationOTelLocation = Path.Combine(StartupHook.LoaderAssemblyLocation ?? string.Empty, "OpenTelemetry.dll");
|
||||
var autoInstrumentationOTelFileVersionInfo = FileVersionInfo.GetVersionInfo(autoInstrumentationOTelLocation);
|
||||
var autoInstrumentationOTelFileVersion = new Version(autoInstrumentationOTelFileVersionInfo.FileVersion);
|
||||
|
||||
return autoInstrumentationOTelFileVersion;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
// <copyright file="OpenTelemetrySdkMinimumVersionRuleTests.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using OpenTelemetry.AutoInstrumentation.Logging;
|
||||
using OpenTelemetry.AutoInstrumentation.RulesEngine;
|
||||
using Xunit;
|
||||
|
||||
namespace OpenTelemetry.AutoInstrumentation.StartupHook.Tests;
|
||||
|
||||
public class OpenTelemetrySdkMinimumVersionRuleTests
|
||||
{
|
||||
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
|
||||
public static IEnumerable<object[]> RuleTestData =>
|
||||
new List<object[]>
|
||||
{
|
||||
new object[] { new Version("1.0.0.0"), new Version("2.0.0.0"), "Rule Engine: Application has direct or indirect reference to older version of OpenTelemetry package 1.0.0.0.", false },
|
||||
new object[] { new Version("2.0.0.0"), new Version("1.0.0.0"), "Rule Engine: OpenTelemetrySdkMinimumVersionRule evaluation success.", true },
|
||||
new object[] { new Version("1.0.0.0"), new Version("1.0.0.0"), "Rule Engine: OpenTelemetrySdkMinimumVersionRule evaluation success.", true },
|
||||
new object[] { null, new Version("1.0.0.0"), "Rule Engine: OpenTelemetrySdkMinimumVersionRule evaluation success.", true },
|
||||
new object[] { new Version("1.0.0.0"), null, "Rule Engine: OpenTelemetrySdkMinimumVersionRule evaluation success.", true },
|
||||
new object[] { null, null, "Rule Engine: OpenTelemetrySdkMinimumVersionRule evaluation success.", true },
|
||||
};
|
||||
#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RuleTestData))]
|
||||
public void OpenTelemetrySdkMinimumVersionRuleValidation(Version appVersion, Version autoInstrumentationVersion, string logMessage, bool result)
|
||||
{
|
||||
var logger = new TestLogger();
|
||||
var rule = new OpenTelemetrySdkMinimumVersionTestRule(appVersion, autoInstrumentationVersion, logger);
|
||||
var ruleResult = rule.Evaluate();
|
||||
Assert.Equal(logMessage, logger.LogRecords[0].Message);
|
||||
Assert.Equal(result, ruleResult);
|
||||
}
|
||||
|
||||
private class OpenTelemetrySdkMinimumVersionTestRule : OpenTelemetrySdkMinimumVersionRule
|
||||
{
|
||||
private readonly Version _appVersion;
|
||||
private readonly Version _autoInstrumentationVersion;
|
||||
|
||||
public OpenTelemetrySdkMinimumVersionTestRule(Version appVersion, Version autoInstrumentationVersion, IOtelLogger otelLogger)
|
||||
: base(otelLogger)
|
||||
{
|
||||
_appVersion = appVersion;
|
||||
_autoInstrumentationVersion = autoInstrumentationVersion;
|
||||
}
|
||||
|
||||
protected override Version? GetVersionFromApp()
|
||||
{
|
||||
return _appVersion;
|
||||
}
|
||||
|
||||
protected override Version? GetVersionFromAutoInstrumentation()
|
||||
{
|
||||
return _autoInstrumentationVersion;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
// <copyright file="TestLogger.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
namespace OpenTelemetry.AutoInstrumentation.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// Test implementation.
|
||||
/// </summary>
|
||||
internal class TestLogger : IOtelLogger
|
||||
{
|
||||
public List<LogRecord> LogRecords { get; } = new List<LogRecord>();
|
||||
|
||||
public LogLevel Level => default;
|
||||
|
||||
public bool IsEnabled(LogLevel level)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Debug(string messageTemplate, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Debug<T>(string messageTemplate, T property, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Debug<T0, T1>(string messageTemplate, T0 property0, T1 property1, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Debug<T0, T1, T2>(string messageTemplate, T0 property0, T1 property1, T2 property2, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Debug(string messageTemplate, object[] args, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Debug(Exception exception, string messageTemplate, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Debug<T>(Exception exception, string messageTemplate, T property, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Debug<T0, T1>(Exception exception, string messageTemplate, T0 property0, T1 property1, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Debug<T0, T1, T2>(Exception exception, string messageTemplate, T0 property0, T1 property1, T2 property2, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Debug(Exception exception, string messageTemplate, object[] args, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Information(string messageTemplate, bool writeToEventLog = true)
|
||||
{
|
||||
var logRecord = new LogRecord(LogLevel.Information, messageTemplate);
|
||||
LogRecords.Add(logRecord);
|
||||
}
|
||||
|
||||
public void Information<T>(string messageTemplate, T property, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Information<T0, T1>(string messageTemplate, T0 property0, T1 property1, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Information<T0, T1, T2>(string messageTemplate, T0 property0, T1 property1, T2 property2, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Information(string messageTemplate, object[] args, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Information(Exception exception, string messageTemplate, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Information<T>(Exception exception, string messageTemplate, T property, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Information<T0, T1>(Exception exception, string messageTemplate, T0 property0, T1 property1, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Information<T0, T1, T2>(Exception exception, string messageTemplate, T0 property0, T1 property1, T2 property2, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Information(Exception exception, string messageTemplate, object[] args, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Warning(string messageTemplate, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Warning<T>(string messageTemplate, T property, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Warning<T0, T1>(string messageTemplate, T0 property0, T1 property1, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Warning<T0, T1, T2>(string messageTemplate, T0 property0, T1 property1, T2 property2, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Warning(string messageTemplate, object[] args, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Warning(Exception exception, string messageTemplate, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Warning<T>(Exception exception, string messageTemplate, T property, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Warning<T0, T1>(Exception exception, string messageTemplate, T0 property0, T1 property1, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Warning<T0, T1, T2>(Exception exception, string messageTemplate, T0 property0, T1 property1, T2 property2, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Warning(Exception exception, string messageTemplate, object[] args, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Error(string messageTemplate, bool writeToEventLog = true)
|
||||
{
|
||||
var logRecord = new LogRecord(LogLevel.Error, messageTemplate);
|
||||
LogRecords.Add(logRecord);
|
||||
}
|
||||
|
||||
public void Error<T>(string messageTemplate, T property, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Error<T0, T1>(string messageTemplate, T0 property0, T1 property1, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Error<T0, T1, T2>(string messageTemplate, T0 property0, T1 property1, T2 property2, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Error(string messageTemplate, object[] args, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Error(Exception exception, string messageTemplate, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Error<T>(Exception exception, string messageTemplate, T property, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Error<T0, T1>(Exception exception, string messageTemplate, T0 property0, T1 property1, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Error<T0, T1, T2>(Exception exception, string messageTemplate, T0 property0, T1 property1, T2 property2, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
public void Error(Exception exception, string messageTemplate, object[] args, bool writeToEventLog = true)
|
||||
{
|
||||
}
|
||||
|
||||
internal class LogRecord
|
||||
{
|
||||
public LogRecord(LogLevel logLevel, string message, Exception? exception = null)
|
||||
{
|
||||
LogLevel = logLevel;
|
||||
Message = message;
|
||||
Exception = exception;
|
||||
}
|
||||
|
||||
public LogLevel LogLevel { get; }
|
||||
|
||||
public string Message { get; }
|
||||
|
||||
public Exception? Exception { get; }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue