2014-03-14 10:15:30 +00:00
using System ;
2014-08-28 17:35:23 +00:00
using System.Linq ;
using System.Reflection ;
2014-03-14 10:15:30 +00:00
using System.Text.RegularExpressions ;
using NLog ;
using NzbDrone.Common.EnvironmentInfo ;
namespace NzbDrone.Core.HealthCheck.Checks
{
2014-04-10 00:15:13 +00:00
public class MonoVersionCheck : HealthCheckBase
2014-03-14 10:15:30 +00:00
{
2014-07-30 06:23:43 +00:00
private readonly IRuntimeInfo _runtimeInfo ;
2014-03-14 10:15:30 +00:00
private readonly Logger _logger ;
2014-09-14 15:27:11 +00:00
private static readonly Regex VersionRegex = new Regex ( @"(?<=\W|^)(?<version>\d+\.\d+(\.\d+)?(\.\d+)?)(?=\W)" , RegexOptions . Compiled | RegexOptions . IgnoreCase ) ;
2014-03-14 10:15:30 +00:00
2014-07-30 06:23:43 +00:00
public MonoVersionCheck ( IRuntimeInfo runtimeInfo , Logger logger )
2014-03-14 10:15:30 +00:00
{
2014-07-30 06:23:43 +00:00
_runtimeInfo = runtimeInfo ;
2014-03-14 10:15:30 +00:00
_logger = logger ;
}
2014-04-10 00:15:13 +00:00
public override HealthCheck Check ( )
2014-03-14 10:15:30 +00:00
{
2014-12-07 20:54:07 +00:00
if ( OsInfo . IsWindows )
2014-03-14 10:15:30 +00:00
{
2014-04-10 00:15:13 +00:00
return new HealthCheck ( GetType ( ) ) ;
2014-03-14 10:15:30 +00:00
}
2014-07-30 06:23:43 +00:00
var versionString = _runtimeInfo . RuntimeVersion ;
2014-07-25 06:57:54 +00:00
var versionMatch = VersionRegex . Match ( versionString ) ;
2014-03-14 10:15:30 +00:00
2014-07-25 06:37:32 +00:00
if ( versionMatch . Success )
2014-03-14 10:15:30 +00:00
{
2014-07-25 06:37:32 +00:00
var version = new Version ( versionMatch . Groups [ "version" ] . Value ) ;
2014-03-14 10:15:30 +00:00
2014-08-28 17:35:23 +00:00
if ( version = = new Version ( 3 , 4 , 0 ) & & HasMonoBug18599 ( ) )
{
_logger . Debug ( "mono version 3.4.0, checking for mono bug #18599 returned positive." ) ;
return new HealthCheck ( GetType ( ) , HealthCheckResult . Error , "your mono version 3.4.0 has a critical bug, you should upgrade to a higher version" ) ;
}
2016-11-01 20:08:37 +00:00
if ( version = = new Version ( 4 , 4 , 0 ) | | version = = new Version ( 4 , 4 , 1 ) )
2014-03-14 10:15:30 +00:00
{
2016-09-27 01:47:33 +00:00
_logger . Debug ( "mono version {0}" , version ) ;
return new HealthCheck ( GetType ( ) , HealthCheckResult . Error , $"your mono version {version} has a bug that causes issues connecting to indexers/download clients" ) ;
}
if ( version > = new Version ( 3 , 10 ) )
{
_logger . Debug ( "mono version is 3.10 or better: {0}" , version . ToString ( ) ) ;
2014-07-25 06:37:32 +00:00
return new HealthCheck ( GetType ( ) ) ;
2014-03-14 10:15:30 +00:00
}
}
2016-09-27 01:47:33 +00:00
return new HealthCheck ( GetType ( ) , HealthCheckResult . Warning , "mono version is less than 3.10, upgrade for improved stability" ) ;
2014-04-10 00:15:13 +00:00
}
public override bool CheckOnConfigChange
{
get
{
return false ;
}
}
public override bool CheckOnSchedule
{
get
{
return false ;
}
2014-03-14 10:15:30 +00:00
}
2014-08-28 17:35:23 +00:00
private bool HasMonoBug18599 ( )
{
_logger . Debug ( "mono version 3.4.0, checking for mono bug #18599." ) ;
var numberFormatterType = Type . GetType ( "System.NumberFormatter" ) ;
if ( numberFormatterType = = null )
{
_logger . Debug ( "Couldn't find System.NumberFormatter. Aborting test." ) ;
return false ;
}
var fieldInfo = numberFormatterType . GetField ( "userFormatProvider" , BindingFlags . Static | BindingFlags . NonPublic ) ;
if ( fieldInfo = = null )
{
_logger . Debug ( "userFormatProvider field not found, version likely preceeds the official v3.4.0." ) ;
return false ;
}
if ( fieldInfo . GetCustomAttributes ( false ) . Any ( v = > v is ThreadStaticAttribute ) )
{
_logger . Debug ( "userFormatProvider field doesn't contain the ThreadStatic Attribute, version is affected by the critical bug #18599." ) ;
return true ;
}
return false ;
}
2014-03-14 10:15:30 +00:00
}
}