/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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.
*/
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Amazon.Runtime;
using System.IO;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace AWSSDK.UnitTests
{
///
/// Process credential provider unit tests.
///
[TestClass]
public class ProcessAWSCredentialsTest
{
private const string ArgumentsSession = "Session";
private const int InvalidVersionNumber = 2;
private const string ExitKey = "Exit";
private static readonly string ProjectPath =
Regex.Match(Directory.GetCurrentDirectory(), @"^.*?(?=\\bin\\)").Captures[0].Value;
public static readonly string ActualSecretKey = "SecretKey";
public static readonly string ActualAccessKey = "AccessKey";
public static readonly string ArgumentsBasic = "Basic";
public const int ValidVersionNumber = 1;
public static readonly string Executable = Path.Combine(ProjectPath, @"Custom\Util\linux-credentials-script.sh");
static ProcessAWSCredentialsTest()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Executable = $@"{ProjectPath}\Custom\Util\windows-credentials-script.bat";
}
}
[TestMethod]
public void ValidBasicProcessCredentialInput()
{
var processCredential = new ProcessAWSCredentials($"{Executable} {ArgumentsBasic} {ValidVersionNumber}");
var credentialsRefreshState = processCredential.DetermineProcessCredential();
Assert.AreEqual(DateTime.MaxValue, credentialsRefreshState.Expiration);
Assert.AreEqual(ActualAccessKey, credentialsRefreshState.Credentials.AccessKey);
Assert.AreEqual(ActualSecretKey, credentialsRefreshState.Credentials.SecretKey);
Assert.IsTrue(string.IsNullOrEmpty(credentialsRefreshState.Credentials.Token));
}
#if BCL45
[TestMethod]
public async Task ValidBasicProcessCredentialInputAsync()
{
var processCredential = new ProcessAWSCredentials($"{Executable} {ArgumentsBasic} {ValidVersionNumber}");
var credentialsRefreshState = await processCredential.DetermineProcessCredentialAsync().ConfigureAwait(false);
Assert.AreEqual(DateTime.MaxValue, credentialsRefreshState.Expiration);
Assert.AreEqual(ActualAccessKey, credentialsRefreshState.Credentials.AccessKey);
Assert.AreEqual(ActualSecretKey, credentialsRefreshState.Credentials.SecretKey);
Assert.IsTrue(string.IsNullOrEmpty(credentialsRefreshState.Credentials.Token));
}
[TestMethod]
public void ErrorExitCode()
{
Assert.ThrowsExceptionAsync(async () =>
await new ProcessAWSCredentials($"{Executable} {ExitKey} ").DetermineProcessCredentialAsync());
}
#endif
[TestMethod]
public void ValidSessionProcessCredentialInput()
{
var processCredential = new ProcessAWSCredentials($"{Executable} {ArgumentsSession} {ValidVersionNumber}");
var credentialsRefreshState = processCredential.DetermineProcessCredential();
Assert.AreNotEqual(DateTime.MaxValue, credentialsRefreshState.Expiration);
Assert.AreEqual(ActualAccessKey, credentialsRefreshState.Credentials.AccessKey);
Assert.AreEqual(ActualSecretKey, credentialsRefreshState.Credentials.SecretKey);
Assert.IsNotNull(credentialsRefreshState.Credentials.Token);
}
///
/// The test validates the credential refresh logic for session credentials.
/// The executable generates mock creds and Guid tokens with an expiration of
/// 1 min. Hence a delay of 1 min is added to allow successful credential refresh.
///
[TestMethod]
public void ValidateCredentialRefresh()
{
var processCredential = new ProcessAWSCredentials($"{Executable} {ArgumentsSession} {ValidVersionNumber}");
var credentialsRefreshState = processCredential.DetermineProcessCredential();
var oldToken = credentialsRefreshState.Credentials.Token;
Thread.Sleep(TimeSpan.FromSeconds(60));
credentialsRefreshState = processCredential.DetermineProcessCredential();
Assert.AreNotEqual(oldToken, credentialsRefreshState.Credentials.Token);
}
[TestMethod]
public void NoCredentialProcessConfigured()
{
Assert.ThrowsException(() =>
new ProcessAWSCredentials(string.Empty).DetermineProcessCredential());
}
[TestMethod]
public void InvalidCredentialProcessConfigured()
{
Assert.ThrowsException(() =>
new ProcessAWSCredentials("foobar").DetermineProcessCredential());
}
[TestMethod]
public void InvalidVersionNumberTest()
{
Assert.ThrowsException(() =>
new ProcessAWSCredentials($"{Executable} {ArgumentsSession} {InvalidVersionNumber}").DetermineProcessCredential());
}
[TestMethod]
public void NoVersionNumberSpecifiedTest()
{
Assert.ThrowsException(() =>
new ProcessAWSCredentials($"{Executable} {ArgumentsSession}").DetermineProcessCredential());
}
[TestMethod]
public void ValidateRequiredFieldsCheck()
{
try
{
new ProcessAWSCredentials($"{Executable} \"Junk\" {ValidVersionNumber}").DetermineProcessCredential();
}
catch (ProcessAWSCredentialException proc)
{
Assert.AreEqual("ThirdParty.Json.LitJson.JsonException", proc.InnerException.GetType().FullName);
Assert.IsTrue(proc.InnerException.ToString().Contains("ThirdParty.Json.LitJson.JsonException: The type Amazon.Runtime.Internal.ProcessCredentialVersion1 doesn't have the required property 'System.String AccessKeyId' set"));
}
}
}
}