PageRenderTime 188ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/sdk/test/CrossPlatformTests/CommonTests/IntegrationTests/LambdaTests.cs

https://gitlab.com/vectorci/aws-sdk-net
C# | 274 lines | 223 code | 21 blank | 30 comment | 1 complexity | d0e13fb7f6d30c3cd32f2593c0c2d44b MD5 | raw file
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using System.Collections.Generic;
  5. using System.Threading;
  6. using Amazon.Auth.AccessControlPolicy;
  7. using Amazon.Auth.AccessControlPolicy.ActionIdentifiers;
  8. using Amazon.IdentityManagement;
  9. using Amazon.IdentityManagement.Model;
  10. using Amazon.Lambda;
  11. using Amazon.Lambda.Model;
  12. using Amazon.Runtime;
  13. using CommonTests.Framework;
  14. using NUnit.Framework;
  15. using System.IO.Compression;
  16. using System.Text;
  17. namespace CommonTests.IntegrationTests
  18. {
  19. [TestFixture]
  20. public class LambdaTests : TestBase<AmazonLambdaClient>
  21. {
  22. static IAmazonIdentityManagementService iamClient = TestBase.CreateClient<AmazonIdentityManagementServiceClient>();
  23. static List<string> createdFunctionNames = new List<string>();
  24. [OneTimeTearDown]
  25. public void Cleanup()
  26. {
  27. BaseClean();
  28. }
  29. [TearDown]
  30. public void TestCleanup()
  31. {
  32. DeleteCreatedFunctions(Client);
  33. }
  34. public static void DeleteCreatedFunctions(IAmazonLambda lambdaClient)
  35. {
  36. var deletedFunctions = new List<string>();
  37. foreach(var function in createdFunctionNames)
  38. {
  39. try
  40. {
  41. lambdaClient.DeleteFunctionAsync(function).Wait();
  42. deletedFunctions.Add(function);
  43. }
  44. catch { }
  45. }
  46. foreach (var df in deletedFunctions)
  47. createdFunctionNames.Remove(df);
  48. }
  49. [Test]
  50. public void ListFunctionsTest()
  51. {
  52. var result = Client.ListFunctionsAsync().Result;
  53. Assert.IsNotNull(result);
  54. Assert.IsNotNull(result.ResponseMetadata);
  55. Assert.IsNotNull(result.ResponseMetadata.RequestId);
  56. }
  57. static readonly string LAMBDA_ASSUME_ROLE_POLICY =
  58. @"
  59. {
  60. ""Version"": ""2012-10-17"",
  61. ""Statement"": [
  62. {
  63. ""Sid"": """",
  64. ""Effect"": ""Allow"",
  65. ""Principal"": {
  66. ""Service"": ""lambda.amazonaws.com""
  67. },
  68. ""Action"": ""sts:AssumeRole""
  69. }
  70. ]
  71. }
  72. ".Trim();
  73. [Test]
  74. public void LambdaFunctionTest()
  75. {
  76. string functionName;
  77. string iamRoleName = null;
  78. bool iamRoleCreated = false;
  79. try
  80. {
  81. string iamRoleArn;
  82. string functionArn;
  83. CreateLambdaFunction(out functionName, out functionArn, out iamRoleName, out iamRoleArn);
  84. // List all the functions and make sure the newly uploaded function is in the collection
  85. var listResponse = Client.ListFunctionsAsync().Result;
  86. var function = listResponse.Functions.FirstOrDefault(x => x.FunctionName == functionName);
  87. Assert.IsNotNull(function);
  88. Assert.AreEqual("helloworld.handler", function.Handler);
  89. Assert.AreEqual(iamRoleArn, function.Role);
  90. // Get the function with a presigned URL to the uploaded code
  91. var getFunctionResponse = Client.GetFunctionAsync(functionName).Result;
  92. Assert.AreEqual("helloworld.handler", getFunctionResponse.Configuration.Handler);
  93. Assert.IsNotNull(getFunctionResponse.Code.Location);
  94. // Get the function's configuration only
  95. var getFunctionConfiguration = Client.GetFunctionConfigurationAsync(functionName).Result;
  96. Assert.AreEqual("helloworld.handler", getFunctionConfiguration.Handler);
  97. // Call the function
  98. #pragma warning disable 618
  99. var invokeAsyncResponse = Client.InvokeAsyncAsync(new InvokeAsyncRequest
  100. {
  101. FunctionName = functionName,
  102. InvokeArgs = "{}"
  103. }).Result;
  104. #pragma warning restore 618
  105. Assert.AreEqual(invokeAsyncResponse.Status, 202); // Status Code Accepted
  106. var clientContext = @"{""System"": ""Windows""}";
  107. var clientContextBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(clientContext));
  108. var request = new InvokeRequest
  109. {
  110. FunctionName = functionName,
  111. InvocationType = InvocationType.RequestResponse,
  112. LogType = LogType.None,
  113. ClientContext = clientContext,
  114. Payload = @"{""Key"": ""testing""}"
  115. };
  116. Assert.AreEqual(clientContext, request.ClientContext);
  117. Assert.AreEqual(clientContextBase64, request.ClientContextBase64);
  118. // Call the function sync
  119. var invokeSyncResponse = Client.InvokeAsync(request).Result;
  120. Assert.IsNull(invokeSyncResponse.FunctionError);
  121. Assert.IsNull(invokeSyncResponse.LogResult);
  122. Assert.IsNotNull(invokeSyncResponse.Payload);
  123. Assert.AreNotEqual(0, invokeSyncResponse.Payload.Length);
  124. Assert.AreNotEqual(0, invokeSyncResponse.StatusCode);
  125. // Call the function sync, dry run, no payload
  126. invokeSyncResponse = Client.InvokeAsync(new InvokeRequest
  127. {
  128. FunctionName = functionName,
  129. InvocationType = InvocationType.DryRun,
  130. LogType = LogType.None,
  131. ClientContext = clientContext,
  132. Payload = @"{""Key"": ""testing""}"
  133. }).Result;
  134. Assert.IsNull(invokeSyncResponse.FunctionError);
  135. Assert.IsNull(invokeSyncResponse.LogResult);
  136. Assert.IsNotNull(invokeSyncResponse.Payload);
  137. Assert.AreEqual(0, invokeSyncResponse.Payload.Length);
  138. Assert.AreNotEqual(0, invokeSyncResponse.StatusCode);
  139. // Call the function sync, pass non-JSON payload
  140. invokeSyncResponse = Client.InvokeAsync(new InvokeRequest
  141. {
  142. FunctionName = functionName,
  143. InvocationType = InvocationType.RequestResponse,
  144. LogType = LogType.None,
  145. ClientContext = clientContext,
  146. Payload = @"""Key"": ""testing"""
  147. }).Result;
  148. Assert.IsNotNull(invokeSyncResponse.FunctionError);
  149. Assert.IsNull(invokeSyncResponse.LogResult);
  150. Assert.IsNotNull(invokeSyncResponse.Payload);
  151. Assert.AreNotEqual(0, invokeSyncResponse.Payload.Length);
  152. Assert.AreNotEqual(0, invokeSyncResponse.StatusCode);
  153. }
  154. finally
  155. {
  156. if (iamRoleCreated)
  157. iamClient.DeleteRoleAsync(new DeleteRoleRequest { RoleName = iamRoleName }).Wait();
  158. }
  159. }
  160. public void CreateLambdaFunction(out string functionName, out string functionArn, out string iamRoleName, out string iamRoleArn)
  161. {
  162. functionName = "HelloWorld-" + DateTime.Now.Ticks;
  163. iamRoleName = "Lambda-" + DateTime.Now.Ticks;
  164. CreateLambdaFunction(functionName, iamRoleName, out iamRoleArn, out functionArn);
  165. }
  166. public void CreateLambdaFunction(string functionName, string iamRoleName, out string iamRoleArn, out string functionArn)
  167. {
  168. var iamCreateResponse = iamClient.CreateRoleAsync(new CreateRoleRequest
  169. {
  170. RoleName = iamRoleName,
  171. AssumeRolePolicyDocument = LAMBDA_ASSUME_ROLE_POLICY
  172. }).Result;
  173. iamRoleArn = iamCreateResponse.Role.Arn;
  174. var statement = new Amazon.Auth.AccessControlPolicy.Statement(
  175. Amazon.Auth.AccessControlPolicy.Statement.StatementEffect.Allow);
  176. statement.Actions.Add(S3ActionIdentifiers.PutObject);
  177. statement.Actions.Add(S3ActionIdentifiers.GetObject);
  178. statement.Resources.Add(new Resource("*"));
  179. var policy = new Amazon.Auth.AccessControlPolicy.Policy();
  180. policy.Statements.Add(statement);
  181. iamClient.PutRolePolicyAsync(new PutRolePolicyRequest
  182. {
  183. RoleName = iamRoleName,
  184. PolicyName = "admin",
  185. PolicyDocument = policy.ToJson()
  186. }).Wait();
  187. MemoryStream stream = GetScriptStream();
  188. var uploadRequest = new CreateFunctionRequest
  189. {
  190. FunctionName = functionName,
  191. Code = new FunctionCode
  192. {
  193. ZipFile = stream
  194. },
  195. Handler = "helloworld.handler",
  196. //Mode = Mode.Event,
  197. Runtime = Runtime.Nodejs,
  198. Role = iamCreateResponse.Role.Arn
  199. };
  200. var uploadResponse = UtilityMethods.WaitUntilSuccess(() => Client.CreateFunctionAsync(uploadRequest).Result);
  201. createdFunctionNames.Add(functionName);
  202. Assert.IsTrue(uploadResponse.CodeSize > 0);
  203. Assert.IsNotNull(uploadResponse.FunctionArn);
  204. functionArn = uploadResponse.FunctionArn;
  205. }
  206. private static MemoryStream GetScriptStream()
  207. {
  208. return new MemoryStream(Convert.FromBase64String(HELLO_SCRIPT_BYTES_BASE64));
  209. }
  210. private static string HELLO_SCRIPT_BYTES_BASE64 = "UEsDBBQAAAAIANZsA0emOtZ2nwAAANoAAAANAAAAaGVsbG93b3JsZC5qc1XMQQuCQBCG4bvgfxj2opKs96STBEHdJDovOqkwzoS7mhL999Qw6DYfzPMWwlYINUkVBhcxZcMV4IDsgij1PRwf0jmra8MlYQcHuPdcuEY4XJ9iKIQdji6Cl+/Bsn45NRjqcSYKdt+kPuO0VGFTuhTGkHuiGNQJiQRu0lG5/yPzreK1srF8sg7bKAVIEsivWXbMc3g2roYWrTUV+t77A1BLAQIUABQAAAAIANZsA0emOtZ2nwAAANoAAAANAAAAAAAAAAAAAAAAAAAAAABoZWxsb3dvcmxkLmpzUEsFBgAAAAABAAEAOwAAAMoAAAAAAA==";
  211. // The above base64 string was generated by calling the below function in a 4.5 application with name="helloworld" and script=HELLO_SCRIPT
  212. // private static string HELLO_SCRIPT =
  213. //@"console.log('Loading event');
  214. //exports.handler = function(event, context) {
  215. // console.log(""value = "" + event.Key);
  216. // context.done(null, ""Hello World:"" + event.Key + "", "" + context.System); // SUCCESS with message
  217. //}";
  218. //private static string CreateScriptBytesBase64(string name, string script)
  219. //{
  220. // using (var stream = new MemoryStream())
  221. // {
  222. // using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, true))
  223. // {
  224. // var entry = archive.CreateEntry(name + ".js");
  225. // using (var entryStream = entry.Open())
  226. // using (var writer = new StreamWriter(entryStream))
  227. // {
  228. // writer.Write(script);
  229. // }
  230. // }
  231. // var bytes = stream.ToArray();
  232. // var base64 = Convert.ToBase64String(bytes);
  233. // return base64;
  234. // }
  235. //}
  236. //#endif
  237. }
  238. }