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
|
internal class OpenTelemetrySdkMinimumVersionRule : Rule
|
||||||
{
|
{
|
||||||
private static readonly IOtelLogger Logger = OtelLogging.GetLogger("StartupHook");
|
private static IOtelLogger logger = OtelLogging.GetLogger("StartupHook");
|
||||||
|
|
||||||
public OpenTelemetrySdkMinimumVersionRule()
|
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";
|
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()
|
internal override bool Evaluate()
|
||||||
{
|
{
|
||||||
string? oTelPackageVersion = null;
|
string? oTelPackageVersion = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var openTelemetryType = Type.GetType("OpenTelemetry.Sdk, OpenTelemetry");
|
var loadedOTelFileVersion = GetVersionFromApp();
|
||||||
if (openTelemetryType != null)
|
if (loadedOTelFileVersion != null)
|
||||||
{
|
{
|
||||||
var loadedOTelAssembly = Assembly.GetAssembly(openTelemetryType);
|
var autoInstrumentationOTelFileVersion = GetVersionFromAutoInstrumentation();
|
||||||
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);
|
|
||||||
|
|
||||||
if (loadedOTelFileVersion < autoInstrumentationOTelFileVersion)
|
if (loadedOTelFileVersion < autoInstrumentationOTelFileVersion)
|
||||||
{
|
{
|
||||||
oTelPackageVersion = loadedOTelFileVersionInfo.FileVersion;
|
oTelPackageVersion = loadedOTelFileVersion.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// Exception in evaluation should not throw or crash the process.
|
// 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)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.Information("Rule Engine: OpenTelemetrySdkMinimumVersionRule evaluation success.");
|
||||||
return true;
|
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