using CryptoExchange.Net.Objects; using Microsoft.Extensions.Logging; using System; using System.Diagnostics; using System.Linq.Expressions; using System.Threading.Tasks; namespace CryptoExchange.Net.Testing { /// /// Base class for executing REST API integration tests /// /// Client type public abstract class RestIntergrationTest { /// /// Get a client instance /// /// /// public abstract TClient GetClient(ILoggerFactory loggerFactory); /// /// Whether the test should be run. By default integration tests aren't executed, can be set to true to force execution. /// public virtual bool Run { get; set; } /// /// Whether API credentials are provided and thus authenticated calls can be executed. Should be set in the GetClient implementation. /// public bool Authenticated { get; set; } /// /// Create a client /// /// protected TClient CreateClient() { var fact = new LoggerFactory(); fact.AddProvider(new TraceLoggerProvider()); return GetClient(fact); } /// /// Check if integration tests should be executed /// /// protected bool ShouldRun() { var integrationTests = Environment.GetEnvironmentVariable("INTEGRATION"); if (!Run && integrationTests != "1") return false; return true; } /// /// Execute a REST endpoint call and check for any errors or warnings. /// /// Type of response /// The call expression /// Whether this is an authenticated request public async Task RunAndCheckResult(Expression>>> expression, bool authRequest) { if (!ShouldRun()) return; var client = CreateClient(); var expressionBody = (MethodCallExpression)expression.Body; if (authRequest && !Authenticated) { Debug.WriteLine($"Skipping {expressionBody.Method.Name}, not authenticated"); return; } var listener = new EnumValueTraceListener(); Trace.Listeners.Add(listener); WebCallResult result; try { result = await expression.Compile().Invoke(client).ConfigureAwait(false); } catch (Exception ex) { throw new Exception($"Method {expressionBody.Method.Name} threw an exception: " + ex.ToLogString()); } finally { Trace.Listeners.Remove(listener); } if (!result.Success) throw new Exception($"Method {expressionBody.Method.Name} returned error: " + result.Error); Debug.WriteLine($"{expressionBody.Method.Name} {result}"); } } }