- Implemented a new tool `stella-callgraph-node` that extracts call graphs from JavaScript/TypeScript projects using Babel AST. - Added command-line interface with options for JSON output and help. - Included functionality to analyze project structure, detect functions, and build call graphs. - Created a package.json file for dependency management. feat: introduce stella-callgraph-python for Python call graph extraction - Developed `stella-callgraph-python` to extract call graphs from Python projects using AST analysis. - Implemented command-line interface with options for JSON output and verbose logging. - Added framework detection to identify popular web frameworks and their entry points. - Created an AST analyzer to traverse Python code and extract function definitions and calls. - Included requirements.txt for project dependencies. chore: add framework detection for Python projects - Implemented framework detection logic to identify frameworks like Flask, FastAPI, Django, and others based on project files and import patterns. - Enhanced the AST analyzer to recognize entry points based on decorators and function definitions.
148 lines
5.0 KiB
C#
148 lines
5.0 KiB
C#
using Examples.Billing.Microservice.Endpoints;
|
|
using Examples.Inventory.Microservice.Endpoints;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.AspNetCore.Mvc.Testing;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
using Microsoft.Extensions.Hosting;
|
|
using StellaOps.Microservice;
|
|
using StellaOps.Router.Common.Abstractions;
|
|
using StellaOps.Router.Common.Enums;
|
|
using StellaOps.Router.Transport.InMemory;
|
|
using Xunit;
|
|
|
|
namespace Examples.Integration.Tests;
|
|
|
|
/// <summary>
|
|
/// Test fixture that sets up the gateway and microservices for integration testing.
|
|
/// Uses in-memory transport for fast, isolated tests.
|
|
/// </summary>
|
|
public sealed class GatewayFixture : IAsyncLifetime
|
|
{
|
|
private readonly InMemoryConnectionRegistry _registry = new();
|
|
private WebApplicationFactory<Examples.Gateway.Program>? _gatewayFactory;
|
|
private IHost? _billingHost;
|
|
private IHost? _inventoryHost;
|
|
|
|
public HttpClient GatewayClient { get; private set; } = null!;
|
|
|
|
public async Task InitializeAsync()
|
|
{
|
|
// Start the gateway
|
|
_gatewayFactory = new WebApplicationFactory<Examples.Gateway.Program>()
|
|
.WithWebHostBuilder(builder =>
|
|
{
|
|
builder.UseEnvironment("Testing");
|
|
builder.ConfigureServices(services =>
|
|
{
|
|
services.RemoveAll<InMemoryConnectionRegistry>();
|
|
services.AddSingleton(_registry);
|
|
});
|
|
});
|
|
|
|
GatewayClient = _gatewayFactory.CreateClient();
|
|
|
|
// Start billing microservice
|
|
var billingBuilder = Host.CreateApplicationBuilder();
|
|
billingBuilder.Services.AddStellaMicroservice(options =>
|
|
{
|
|
options.ServiceName = "billing";
|
|
options.Version = "1.0.0";
|
|
options.Region = "test";
|
|
options.InstanceId = "billing-test";
|
|
options.Routers =
|
|
[
|
|
new RouterEndpointConfig
|
|
{
|
|
Host = "localhost",
|
|
Port = 5100,
|
|
TransportType = TransportType.InMemory
|
|
}
|
|
];
|
|
});
|
|
billingBuilder.Services.AddScoped<CreateInvoiceEndpoint>();
|
|
billingBuilder.Services.AddScoped<GetInvoiceEndpoint>();
|
|
billingBuilder.Services.AddScoped<UploadAttachmentEndpoint>();
|
|
billingBuilder.Services.AddSingleton(_registry);
|
|
billingBuilder.Services.AddInMemoryTransportClient();
|
|
|
|
_billingHost = billingBuilder.Build();
|
|
await _billingHost.StartAsync();
|
|
|
|
// Start inventory microservice
|
|
var inventoryBuilder = Host.CreateApplicationBuilder();
|
|
inventoryBuilder.Services.AddStellaMicroservice(options =>
|
|
{
|
|
options.ServiceName = "inventory";
|
|
options.Version = "1.0.0";
|
|
options.Region = "test";
|
|
options.InstanceId = "inventory-test";
|
|
options.Routers =
|
|
[
|
|
new RouterEndpointConfig
|
|
{
|
|
Host = "localhost",
|
|
Port = 5100,
|
|
TransportType = TransportType.InMemory
|
|
}
|
|
];
|
|
});
|
|
inventoryBuilder.Services.AddScoped<ListItemsEndpoint>();
|
|
inventoryBuilder.Services.AddScoped<GetItemEndpoint>();
|
|
inventoryBuilder.Services.AddSingleton(_registry);
|
|
inventoryBuilder.Services.AddInMemoryTransportClient();
|
|
|
|
_inventoryHost = inventoryBuilder.Build();
|
|
await _inventoryHost.StartAsync();
|
|
|
|
await WaitForGatewayReadyAsync(TimeSpan.FromSeconds(5));
|
|
}
|
|
|
|
public async Task DisposeAsync()
|
|
{
|
|
GatewayClient.Dispose();
|
|
|
|
if (_billingHost is not null)
|
|
{
|
|
await _billingHost.StopAsync();
|
|
_billingHost.Dispose();
|
|
}
|
|
|
|
if (_inventoryHost is not null)
|
|
{
|
|
await _inventoryHost.StopAsync();
|
|
_inventoryHost.Dispose();
|
|
}
|
|
|
|
_gatewayFactory?.Dispose();
|
|
}
|
|
|
|
private async Task WaitForGatewayReadyAsync(TimeSpan timeout)
|
|
{
|
|
if (_gatewayFactory is null)
|
|
{
|
|
throw new InvalidOperationException("Gateway factory not initialized.");
|
|
}
|
|
|
|
var routingState = _gatewayFactory.Services.GetRequiredService<IGlobalRoutingState>();
|
|
var deadline = DateTimeOffset.UtcNow.Add(timeout);
|
|
|
|
while (DateTimeOffset.UtcNow < deadline)
|
|
{
|
|
var connections = routingState.GetAllConnections();
|
|
if (connections.Count >= 2 &&
|
|
routingState.ResolveEndpoint("GET", "/items") is not null &&
|
|
routingState.ResolveEndpoint("POST", "/invoices") is not null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await Task.Delay(50);
|
|
}
|
|
|
|
var currentConnections = routingState.GetAllConnections();
|
|
throw new TimeoutException(
|
|
$"Gateway routing state not ready after {timeout}. Connections={currentConnections.Count}.");
|
|
}
|
|
}
|