You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

HelloAppHostIntegrationTests.cs 10 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // HelloAppHostIntegrationTests.cs
  3. using System.Text.Json;
  4. using Xunit.Abstractions;
  5. namespace Microsoft.AutoGen.Integration.Tests;
  6. public class HelloAppHostIntegrationTests(ITestOutputHelper testOutput)
  7. {
  8. private const string AppHostAssemblyName = "XlangTests.AppHost";
  9. private const string DotNetResourceName = "HelloAgentTestsDotNET";
  10. private const string PythonResourceName = "HelloAgentTestsPython";
  11. private const string BackendResourceName = "AgentHost";
  12. [Fact]
  13. public async Task AppHostRunsCleanly()
  14. {
  15. var appHostPath = GetAssemblyPath(AppHostAssemblyName);
  16. var appHost = await DistributedApplicationTestFactory.CreateAsync(appHostPath, testOutput);
  17. await using var app = await appHost.BuildAsync().WaitAsync(TimeSpan.FromSeconds(15));
  18. await app.StartAsync().WaitAsync(TimeSpan.FromSeconds(120));
  19. await app.WaitForResourcesAsync().WaitAsync(TimeSpan.FromSeconds(120));
  20. app.EnsureNoErrorsLogged();
  21. await app.StopAsync().WaitAsync(TimeSpan.FromSeconds(15));
  22. }
  23. [Fact]
  24. public async Task Test_Dotnet_Sends_AgentHost_Delivers_and_Python_Receives()
  25. {
  26. //Prepare
  27. var appHostPath = GetAssemblyPath(AppHostAssemblyName);
  28. var appHost = await DistributedApplicationTestFactory.CreateAsync(appHostPath, testOutput);
  29. await using var app = await appHost.BuildAsync().WaitAsync(TimeSpan.FromSeconds(15));
  30. await app.StartAsync().WaitAsync(TimeSpan.FromSeconds(120));
  31. await app.WaitForResourcesAsync(new[] { KnownResourceStates.Running }).WaitAsync(TimeSpan.FromSeconds(120));
  32. //Act
  33. var expectedMessage = "INFO:autogen_core:Received a message from host: cloudEvent {";
  34. var containsExpectedMessage = false;
  35. app.EnsureNoErrorsLogged();
  36. containsExpectedMessage = await app.WaitForExpectedMessageInResourceLogs(PythonResourceName, expectedMessage, TimeSpan.FromSeconds(120));
  37. expectedMessage = "Hello World!";
  38. containsExpectedMessage = false;
  39. containsExpectedMessage = await app.WaitForExpectedMessageInResourceLogs(PythonResourceName, expectedMessage, TimeSpan.FromSeconds(120));
  40. await app.StopAsync();
  41. //Assert
  42. Assert.True(containsExpectedMessage);
  43. }
  44. [Fact]
  45. public async Task Test_Python_Sends_AgentHost_Delivers_and_DotNet_Receives()
  46. {
  47. //Prepare
  48. var appHostPath = GetAssemblyPath(AppHostAssemblyName);
  49. var appHost = await DistributedApplicationTestFactory.CreateAsync(appHostPath, testOutput);
  50. await using var app = await appHost.BuildAsync().WaitAsync(TimeSpan.FromSeconds(15));
  51. await app.StartAsync().WaitAsync(TimeSpan.FromSeconds(120));
  52. await app.WaitForResourcesAsync(new[] { KnownResourceStates.Running }).WaitAsync(TimeSpan.FromSeconds(120));
  53. //Act
  54. var expectedMessage = "from Python!";
  55. var containsExpectedMessage = false;
  56. app.EnsureNoErrorsLogged();
  57. containsExpectedMessage = await app.WaitForExpectedMessageInResourceLogs(DotNetResourceName, expectedMessage, TimeSpan.FromSeconds(60));
  58. await app.StopAsync();
  59. //Assert
  60. Assert.True(containsExpectedMessage);
  61. }
  62. [Fact]
  63. public async Task Test_Python_Agent_Sends_And_AgentHost_Receives()
  64. {
  65. //Prepare
  66. Environment.SetEnvironmentVariable("XLANG_TEST_NO_DOTNET", "true");
  67. var appHostPath = GetAssemblyPath(AppHostAssemblyName);
  68. var appHost = await DistributedApplicationTestFactory.CreateAsync(appHostPath, testOutput);
  69. await using var app = await appHost.BuildAsync().WaitAsync(TimeSpan.FromSeconds(15));
  70. await app.StartAsync().WaitAsync(TimeSpan.FromSeconds(120));
  71. await app.WaitForResourcesAsync(new[] { KnownResourceStates.Running }).WaitAsync(TimeSpan.FromSeconds(120));
  72. //Act
  73. var expectedMessage = "\"source\": \"HelloAgents/python\"";
  74. var containsExpectedMessage = false;
  75. app.EnsureNoErrorsLogged();
  76. containsExpectedMessage = await app.WaitForExpectedMessageInResourceLogs(BackendResourceName, expectedMessage, TimeSpan.FromSeconds(120));
  77. await app.StopAsync();
  78. //Assert
  79. Assert.True(containsExpectedMessage);
  80. }
  81. [Fact]
  82. public async Task Test_Dotnet_Agent_Sends_And_AgentHost_Receives()
  83. {
  84. //Prepare
  85. Environment.SetEnvironmentVariable("XLANG_TEST_NO_PYTHON", "true");
  86. var appHostPath = GetAssemblyPath(AppHostAssemblyName);
  87. var appHost = await DistributedApplicationTestFactory.CreateAsync(appHostPath, testOutput);
  88. await using var app = await appHost.BuildAsync().WaitAsync(TimeSpan.FromSeconds(15));
  89. await app.StartAsync().WaitAsync(TimeSpan.FromSeconds(120));
  90. await app.WaitForResourcesAsync(new[] { KnownResourceStates.Running }).WaitAsync(TimeSpan.FromSeconds(120));
  91. //Act
  92. var expectedMessage = "\"source\": \"HelloAgents/dotnet\"";
  93. var containsExpectedMessage = false;
  94. app.EnsureNoErrorsLogged();
  95. containsExpectedMessage = await app.WaitForExpectedMessageInResourceLogs(BackendResourceName, expectedMessage, TimeSpan.FromSeconds(120));
  96. await app.StopAsync();
  97. //Assert
  98. Assert.True(containsExpectedMessage);
  99. }
  100. [Fact]
  101. public async Task Test_Dotnet_Agent_Sends_And_AgentHost_Delivers_Back_To_It()
  102. {
  103. //Prepare
  104. Environment.SetEnvironmentVariable("XLANG_TEST_NO_PYTHON", "true");
  105. var appHostPath = GetAssemblyPath(AppHostAssemblyName);
  106. var appHost = await DistributedApplicationTestFactory.CreateAsync(appHostPath, testOutput);
  107. await using var app = await appHost.BuildAsync().WaitAsync(TimeSpan.FromSeconds(15));
  108. await app.StartAsync().WaitAsync(TimeSpan.FromSeconds(120));
  109. await app.WaitForResourcesAsync(new[] { KnownResourceStates.Running }).WaitAsync(TimeSpan.FromSeconds(120));
  110. //Act
  111. var expectedMessage = "Hello World!";
  112. var containsExpectedMessage = false;
  113. app.EnsureNoErrorsLogged();
  114. containsExpectedMessage = await app.WaitForExpectedMessageInResourceLogs(DotNetResourceName, expectedMessage, TimeSpan.FromSeconds(120));
  115. expectedMessage = "HelloAgent said Goodbye";
  116. containsExpectedMessage = false;
  117. containsExpectedMessage = await app.WaitForExpectedMessageInResourceLogs(DotNetResourceName, expectedMessage, TimeSpan.FromSeconds(120));
  118. await app.StopAsync();
  119. //Assert
  120. Assert.True(containsExpectedMessage);
  121. }
  122. [Fact]
  123. public async Task Test_Python_Agent_Sends_And_AgentHost_Delivers_Back_To_It()
  124. {
  125. //Prepare
  126. Environment.SetEnvironmentVariable("XLANG_TEST_NO_DOTNET", "true");
  127. var appHostPath = GetAssemblyPath(AppHostAssemblyName);
  128. var appHost = await DistributedApplicationTestFactory.CreateAsync(appHostPath, testOutput);
  129. await using var app = await appHost.BuildAsync().WaitAsync(TimeSpan.FromSeconds(15));
  130. await app.StartAsync().WaitAsync(TimeSpan.FromSeconds(120));
  131. await app.WaitForResourcesAsync(new[] { KnownResourceStates.Running }).WaitAsync(TimeSpan.FromSeconds(120));
  132. //Act
  133. var expectedMessage = "INFO:autogen_core:Received a message from host: cloudEvent {";
  134. var containsExpectedMessage = false;
  135. app.EnsureNoErrorsLogged();
  136. containsExpectedMessage = await app.WaitForExpectedMessageInResourceLogs(PythonResourceName, expectedMessage, TimeSpan.FromSeconds(120));
  137. await app.StopAsync();
  138. //Assert
  139. Assert.True(containsExpectedMessage);
  140. }
  141. private static string GetAssemblyPath(string assemblyName)
  142. {
  143. var parentDir = Directory.GetParent(AppContext.BaseDirectory)?.FullName;
  144. var grandParentDir = parentDir is not null ? Directory.GetParent(parentDir)?.FullName : null;
  145. var greatGrandParentDir = grandParentDir is not null ? Directory.GetParent(grandParentDir)?.FullName : null
  146. ?? AppContext.BaseDirectory;
  147. var options = new EnumerationOptions { RecurseSubdirectories = true, MatchCasing = MatchCasing.CaseInsensitive };
  148. if (greatGrandParentDir is not null)
  149. {
  150. var foundFile = Directory.GetFiles(greatGrandParentDir, $"{assemblyName}.dll", options).FirstOrDefault();
  151. if (foundFile is not null)
  152. {
  153. return foundFile;
  154. }
  155. }
  156. throw new FileNotFoundException($"Could not find {assemblyName}.dll in {grandParentDir ?? "unknown"} directory");
  157. }
  158. }
  159. public class TestEndpoints : IXunitSerializable
  160. {
  161. // Required for deserialization
  162. public TestEndpoints() { }
  163. public TestEndpoints(string appHost, Dictionary<string, List<string>> resourceEndpoints)
  164. {
  165. AppHost = appHost;
  166. ResourceEndpoints = resourceEndpoints;
  167. }
  168. public string? AppHost { get; set; }
  169. public List<ResourceWait>? WaitForResources { get; set; }
  170. public Dictionary<string, List<string>>? ResourceEndpoints { get; set; }
  171. public void Deserialize(IXunitSerializationInfo info)
  172. {
  173. AppHost = info.GetValue<string>(nameof(AppHost));
  174. WaitForResources = JsonSerializer.Deserialize<List<ResourceWait>>(info.GetValue<string>(nameof(WaitForResources)));
  175. ResourceEndpoints = JsonSerializer.Deserialize<Dictionary<string, List<string>>>(info.GetValue<string>(nameof(ResourceEndpoints)));
  176. }
  177. public void Serialize(IXunitSerializationInfo info)
  178. {
  179. info.AddValue(nameof(AppHost), AppHost);
  180. info.AddValue(nameof(WaitForResources), JsonSerializer.Serialize(WaitForResources));
  181. info.AddValue(nameof(ResourceEndpoints), JsonSerializer.Serialize(ResourceEndpoints));
  182. }
  183. public override string? ToString() => $"{AppHost} ({ResourceEndpoints?.Count ?? 0} resources)";
  184. public class ResourceWait(string resourceName, string targetState)
  185. {
  186. public string ResourceName { get; } = resourceName;
  187. public string TargetState { get; } = targetState;
  188. public void Deconstruct(out string resourceName, out string targetState)
  189. {
  190. resourceName = ResourceName;
  191. targetState = TargetState;
  192. }
  193. }
  194. }