Skip to content
This repository has been archived by the owner on Jul 29, 2022. It is now read-only.

Commit

Permalink
Merge branch 'feature/configurable_loglevel' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Jericho committed Jul 3, 2019
2 parents 4a85673 + 6e1eb68 commit a5b9d07
Show file tree
Hide file tree
Showing 25 changed files with 431 additions and 238 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Logzio.DotNet.NLog" Version="1.0.6" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\CakeMail.RestClient\CakeMail.RestClient.csproj" />
</ItemGroup>
Expand Down
32 changes: 32 additions & 0 deletions Source/CakeMail.RestClient.IntegrationTests/ConsoleUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;

namespace CakeMail.RestClient.IntegrationTests
{
public static class ConsoleUtils
{
public static void CenterConsole()
{
var hWin = NativeMethods.GetConsoleWindow();
if (hWin == IntPtr.Zero) return;

var monitor = NativeMethods.MonitorFromWindow(hWin, NativeMethods.MONITOR_DEFAULT_TO_NEAREST);
if (monitor == IntPtr.Zero) return;

var monitorInfo = new NativeMethods.NativeMonitorInfo();
NativeMethods.GetMonitorInfo(monitor, monitorInfo);

NativeMethods.GetWindowRect(hWin, out NativeMethods.NativeRectangle consoleInfo);

var monitorWidth = monitorInfo.Monitor.Right - monitorInfo.Monitor.Left;
var monitorHeight = monitorInfo.Monitor.Bottom - monitorInfo.Monitor.Top;

var consoleWidth = consoleInfo.Right - consoleInfo.Left;
var consoleHeight = consoleInfo.Bottom - consoleInfo.Top;

var left = monitorInfo.Monitor.Left + ((monitorWidth - consoleWidth) / 2);
var top = monitorInfo.Monitor.Top + ((monitorHeight - consoleHeight) / 2);

NativeMethods.MoveWindow(hWin, left, top, consoleWidth, consoleHeight, false);
}
}
}
11 changes: 11 additions & 0 deletions Source/CakeMail.RestClient.IntegrationTests/IIntegrationTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace CakeMail.RestClient.IntegrationTests
{
public interface IIntegrationTest
{
Task Execute(ICakeMailRestClient client, string userKey, long clientId, TextWriter log, CancellationToken cancellationToken);
}
}
52 changes: 52 additions & 0 deletions Source/CakeMail.RestClient.IntegrationTests/NativeMethods.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using System.Runtime.InteropServices;

namespace CakeMail.RestClient.IntegrationTests
{
public static class NativeMethods
{
public const Int32 MONITOR_DEFAULT_TO_PRIMARY = 0x00000001;
public const Int32 MONITOR_DEFAULT_TO_NEAREST = 0x00000002;

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetConsoleWindow();

[DllImport("user32.dll", SetLastError = true)]
public static extern bool GetWindowRect(IntPtr hWnd, out NativeRectangle rc);

[DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hWnd, int x, int y, int w, int h, bool repaint);

[DllImport("user32.dll")]
public static extern IntPtr MonitorFromWindow(IntPtr handle, Int32 flags);

[DllImport("user32.dll")]
public static extern Boolean GetMonitorInfo(IntPtr hMonitor, NativeMonitorInfo lpmi);

[Serializable, StructLayout(LayoutKind.Sequential)]
public struct NativeRectangle
{
public Int32 Left;
public Int32 Top;
public Int32 Right;
public Int32 Bottom;

public NativeRectangle(Int32 left, Int32 top, Int32 right, Int32 bottom)
{
this.Left = left;
this.Top = top;
this.Right = right;
this.Bottom = bottom;
}
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public sealed class NativeMonitorInfo
{
public Int32 Size = Marshal.SizeOf(typeof(NativeMonitorInfo));
public NativeRectangle Monitor;
public NativeRectangle Work;
public Int32 Flags;
}
}
}
215 changes: 136 additions & 79 deletions Source/CakeMail.RestClient.IntegrationTests/Program.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
using CakeMail.RestClient.IntegrationTests.Tests;
using CakeMail.RestClient.Logging;
using CakeMail.RestClient.Utilities;
using Logzio.DotNet.NLog;
using NLog;
using NLog.Config;
using NLog.Targets;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -10,86 +15,164 @@ namespace CakeMail.RestClient.IntegrationTests
{
public class Program
{
private const int MAX_CAKEMAIL_API_CONCURRENCY = 5;

private enum ResultCodes
{
Success = 0,
Exception = 1,
Cancelled = 1223
}

static async Task<int> Main()
{
// -----------------------------------------------------------------------------

// Do you want to proxy requests through Fiddler (useful for debugging)?
// Do you want to proxy requests through Fiddler? Can be useful for debugging.
var useFiddler = false;

// As an alternative to Fiddler, you can display debug information about
// every HTTP request/response in the console. This is useful for debugging
// purposes but the amount of information can be overwhelming.
var debugHttpMessagesToConsole = false;
// Logging options.
var options = new CakeMailClientOptions()
{
LogLevelFailedCalls = CakeMail.RestClient.Logging.LogLevel.Error,
LogLevelSuccessfulCalls = CakeMail.RestClient.Logging.LogLevel.Debug
};
// -----------------------------------------------------------------------------

var proxy = useFiddler ? new WebProxy("http://localhost:8888") : null;
// Configure logging
var nLogConfig = new LoggingConfiguration();

// Send logs to logz.io
var logzioToken = Environment.GetEnvironmentVariable("LOGZIO_TOKEN");
if (!string.IsNullOrEmpty(logzioToken))
{
var logzioTarget = new LogzioTarget { Token = logzioToken };
logzioTarget.ContextProperties.Add(new TargetPropertyWithContext("source", "StrongGrid_integration_tests"));
logzioTarget.ContextProperties.Add(new TargetPropertyWithContext("StrongGrid-Version", CakeMailRestClient.Version));

nLogConfig.AddTarget("Logzio", logzioTarget);
nLogConfig.AddRule(NLog.LogLevel.Debug, NLog.LogLevel.Fatal, "Logzio", "*");
}

// Send logs to console
var consoleTarget = new ColoredConsoleTarget();
nLogConfig.AddTarget("ColoredConsole", consoleTarget);
nLogConfig.AddRule(NLog.LogLevel.Warn, NLog.LogLevel.Fatal, "ColoredConsole", "*");

LogManager.Configuration = nLogConfig;

// Configure CakeMail client
var apiKey = Environment.GetEnvironmentVariable("CAKEMAIL_APIKEY");
var userName = Environment.GetEnvironmentVariable("CAKEMAIL_USERNAME");
var password = Environment.GetEnvironmentVariable("CAKEMAIL_PASSWORD");
var overrideClientId = Environment.GetEnvironmentVariable("CAKEMAIL_OVERRIDECLIENTID");
var proxy = useFiddler ? new WebProxy("http://localhost:8888") : null;
var client = new CakeMailRestClient(apiKey, proxy);
var loginInfo = client.Users.LoginAsync(userName, password).Result;
var clientId = string.IsNullOrEmpty(overrideClientId) ? loginInfo.ClientId : long.Parse(overrideClientId);
var userKey = loginInfo.UserKey;

if (debugHttpMessagesToConsole)
{
LogProvider.SetCurrentLogProvider(new ColoredConsoleLogProvider());
}

// Configure Console
var source = new CancellationTokenSource();
Console.CancelKeyPress += (s, e) =>
{
e.Cancel = true;
source.Cancel();
};

try
// Ensure the Console is tall enough and centered on the screen
Console.WindowHeight = Math.Min(60, Console.LargestWindowHeight);
ConsoleUtils.CenterConsole();

// These are the integration tests that we will execute
var integrationTests = new Type[]
{
var client = new CakeMailRestClient(apiKey, proxy);
var loginInfo = client.Users.LoginAsync(userName, password).Result;
var clientId = string.IsNullOrEmpty(overrideClientId) ? loginInfo.ClientId : long.Parse(overrideClientId);
var userKey = loginInfo.UserKey;
typeof(CampaignsTests),
typeof(ClientsTests),
typeof(CountriesTests),
typeof(ListsTests),
typeof(MailingsTests),
typeof(PermissionsTests),
typeof(RelaysTests),
typeof(SuppressionListsTests),
typeof(TemplatesTests),
typeof(TimezonesTests),
typeof(TriggersTests),
typeof(UsersTests),
};

var tasks = new Task[]
// Execute the async tests in parallel (with max degree of parallelism)
var results = await integrationTests.ForEachAsync(
async integrationTestType =>
{
ExecuteAsync(client, userKey, clientId, source, TimezonesTests.ExecuteAllMethods),
ExecuteAsync(client, userKey, clientId, source, CountriesTests.ExecuteAllMethods),
ExecuteAsync(client, userKey, clientId, source, ClientsTests.ExecuteAllMethods),
ExecuteAsync(client, userKey, clientId, source, UsersTests.ExecuteAllMethods),
ExecuteAsync(client, userKey, clientId, source, PermissionsTests.ExecuteAllMethods),
ExecuteAsync(client, userKey, clientId, source, CampaignsTests.ExecuteAllMethods),
ExecuteAsync(client, userKey, clientId, source, ListsTests.ExecuteAllMethods),
ExecuteAsync(client, userKey, clientId, source, TemplatesTests.ExecuteAllMethods),
ExecuteAsync(client, userKey, clientId, source, SuppressionListsTests.ExecuteAllMethods),
ExecuteAsync(client, userKey, clientId, source, RelaysTests.ExecuteAllMethods),
ExecuteAsync(client, userKey, clientId, source, TriggersTests.ExecuteAllMethods),
ExecuteAsync(client, userKey, clientId, source, MailingsTests.ExecuteAllMethods)
};
await Task.WhenAll(tasks).ConfigureAwait(false);
return await Task.FromResult(0); // Success.
}
catch (OperationCanceledException)
var log = new StringWriter();
try
{
var integrationTest = (IIntegrationTest)Activator.CreateInstance(integrationTestType);
await integrationTest.Execute(client, userKey, clientId, log, source.Token).ConfigureAwait(false);
return (TestName: integrationTestType.Name, ResultCode: ResultCodes.Success, Message: string.Empty);
}
catch (OperationCanceledException)
{
await log.WriteLineAsync($"-----> TASK CANCELLED").ConfigureAwait(false);
return (TestName: integrationTestType.Name, ResultCode: ResultCodes.Cancelled, Message: "Task cancelled");
}
catch (Exception e)
{
var exceptionMessage = e.GetBaseException().Message;
await log.WriteLineAsync($"-----> AN EXCEPTION OCCURRED: {exceptionMessage}").ConfigureAwait(false);
return (TestName: integrationTestType.Name, ResultCode: ResultCodes.Exception, Message: exceptionMessage);
}
finally
{
await Console.Out.WriteLineAsync(log.ToString()).ConfigureAwait(false);
}
}, MAX_CAKEMAIL_API_CONCURRENCY)
.ConfigureAwait(false);

// Display summary
var summary = new StringWriter();
await summary.WriteLineAsync("\n\n**************************************************").ConfigureAwait(false);
await summary.WriteLineAsync("******************** SUMMARY *********************").ConfigureAwait(false);
await summary.WriteLineAsync("**************************************************").ConfigureAwait(false);

var resultsWithMessage = results
.Where(r => !string.IsNullOrEmpty(r.Message))
.ToArray();

if (resultsWithMessage.Any())
{
return 1223; // Cancelled.
foreach (var (TestName, ResultCode, Message) in resultsWithMessage)
{
const int TEST_NAME_MAX_LENGTH = 25;
var name = TestName.Length <= TEST_NAME_MAX_LENGTH ? TestName : TestName.Substring(0, TEST_NAME_MAX_LENGTH - 3) + "...";
await summary.WriteLineAsync($"{name.PadRight(TEST_NAME_MAX_LENGTH, ' ')} : {Message}").ConfigureAwait(false);
}
}
catch (Exception e)
else
{
source.Cancel();
var log = new StringWriter();
await log.WriteLineAsync("\n\n**************************************************").ConfigureAwait(false);
await log.WriteLineAsync("**************************************************").ConfigureAwait(false);
await log.WriteLineAsync($"AN EXCEPTION OCCURED: {e.GetBaseException().Message}").ConfigureAwait(false);
await log.WriteLineAsync("**************************************************").ConfigureAwait(false);
await log.WriteLineAsync("**************************************************").ConfigureAwait(false);
await Console.Out.WriteLineAsync(log.ToString()).ConfigureAwait(false);
return 1; // Exception
await summary.WriteLineAsync("All tests completed succesfully").ConfigureAwait(false);
}
finally

await summary.WriteLineAsync("**************************************************").ConfigureAwait(false);
await Console.Out.WriteLineAsync(summary.ToString()).ConfigureAwait(false);

// Prompt user to press a key in order to allow reading the log in the console
var promptLog = new StringWriter();
await promptLog.WriteLineAsync("\n\n**************************************************").ConfigureAwait(false);
await promptLog.WriteLineAsync("Press any key to exit").ConfigureAwait(false);
Prompt(promptLog.ToString());

// Return code indicating success/failure
var resultCode = (int)ResultCodes.Success;
if (results.Any(result => result.ResultCode != ResultCodes.Success))
{
var log = new StringWriter();
await log.WriteLineAsync("\n\n**************************************************").ConfigureAwait(false);
await log.WriteLineAsync("All tests completed").ConfigureAwait(false);
await log.WriteLineAsync("Press any key to exit").ConfigureAwait(false);
Prompt(log.ToString());
if (results.Any(result => result.ResultCode == ResultCodes.Exception)) resultCode = (int)ResultCodes.Exception;
else if (results.Any(result => result.ResultCode == ResultCodes.Cancelled)) resultCode = (int)ResultCodes.Cancelled;
else resultCode = (int)results.First(result => result.ResultCode != ResultCodes.Success).ResultCode;
}

return await Task.FromResult(resultCode);
}

private static char Prompt(string prompt)
Expand All @@ -102,31 +185,5 @@ private static char Prompt(string prompt)
var result = Console.ReadKey();
return result.KeyChar;
}

private static async Task<int> ExecuteAsync(ICakeMailRestClient client, string userKey, long clientId, CancellationTokenSource cts, Func<ICakeMailRestClient, string, long, TextWriter, CancellationToken, Task> asyncTask)
{
var log = new StringWriter();

try
{
await asyncTask(client, userKey, clientId, log, cts.Token).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
await log.WriteLineAsync($"-----> TASK CANCELLED").ConfigureAwait(false);
return 1223; // Cancelled.
}
catch (Exception e)
{
await log.WriteLineAsync($"-----> AN EXCEPTION OCCURED: {e.GetBaseException().Message}").ConfigureAwait(false);
throw;
}
finally
{
await Console.Out.WriteLineAsync(log.ToString()).ConfigureAwait(false);
}

return 0; // Success
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

namespace CakeMail.RestClient.IntegrationTests.Tests
{
public static class CampaignsTests
public class CampaignsTests : IIntegrationTest
{
public static async Task ExecuteAllMethods(ICakeMailRestClient client, string userKey, long clientId, TextWriter log, CancellationToken cancellationToken)
public async Task Execute(ICakeMailRestClient client, string userKey, long clientId, TextWriter log, CancellationToken cancellationToken)
{
await log.WriteLineAsync("\n***** CAMPAIGNS *****").ConfigureAwait(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@

namespace CakeMail.RestClient.IntegrationTests.Tests
{
public static class ClientsTests
public class ClientsTests : IIntegrationTest
{
private const int UTC_TIMEZONE_ID = 542;

public static async Task ExecuteAllMethods(ICakeMailRestClient client, string userKey, long clientId, TextWriter log, CancellationToken cancellationToken)
public async Task Execute(ICakeMailRestClient client, string userKey, long clientId, TextWriter log, CancellationToken cancellationToken)
{
await log.WriteLineAsync("\n***** CLIENT *****").ConfigureAwait(false);

Expand Down
Loading

0 comments on commit a5b9d07

Please sign in to comment.