Refactor and enhance tests for call graph extractors and connection management
- Updated JavaScriptCallGraphExtractorTests to improve naming conventions and test cases for Azure Functions, CLI commands, and socket handling. - Modified NodeCallGraphExtractorTests to correctly assert exceptions for null inputs. - Enhanced WitnessModalComponent tests in Angular to use Jasmine spies and improved assertions for path visualization and signature verification. - Added ConnectionState property for tracking connection establishment time in Router.Common. - Implemented validation for HelloPayload in ConnectionManager to ensure required fields are present. - Introduced RabbitMqContainerFixture method for restarting RabbitMQ container during tests. - Added integration tests for RabbitMq to verify connection recovery after broker restarts. - Created new BinaryCallGraphExtractorTests, GoCallGraphExtractorTests, and PythonCallGraphExtractorTests for comprehensive coverage of binary, Go, and Python call graph extraction functionalities. - Developed ConnectionManagerTests to validate connection handling, including rejection of invalid hello messages and proper cleanup on client disconnects.
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// GoCallGraphExtractorTests.cs
|
||||
// Sprint: SPRINT_3610_0002_0001_go_callgraph
|
||||
// Description: Unit tests for Go call graph extraction.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using StellaOps.Scanner.CallGraph.Go;
|
||||
using StellaOps.Scanner.Reachability;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Scanner.CallGraph.Tests;
|
||||
|
||||
public class GoCallGraphExtractorTests
|
||||
{
|
||||
[Fact]
|
||||
public void BuildFunctionId_CreatesCorrectFormat()
|
||||
{
|
||||
// Arrange & Act
|
||||
var id = GoSymbolIdBuilder.BuildFunctionId("github.com/example/pkg", "HandleRequest");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("go:github.com/example/pkg.HandleRequest", id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildMethodId_CreatesCorrectFormat()
|
||||
{
|
||||
// Arrange & Act
|
||||
var id = GoSymbolIdBuilder.BuildMethodId("github.com/example/pkg", "Server", "Start");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("go:github.com/example/pkg.Server.Start", id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildExternalId_CreatesCorrectFormat()
|
||||
{
|
||||
// Arrange & Act
|
||||
var id = GoSymbolIdBuilder.BuildExternalId("fmt", "Println");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("go:external/fmt.Println", id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_ParsesFunctionId()
|
||||
{
|
||||
// Arrange
|
||||
var id = "go:github.com/example/pkg.HandleRequest";
|
||||
|
||||
// Act
|
||||
var result = GoSymbolIdBuilder.Parse(id);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal("github.com/example/pkg", result.PackagePath);
|
||||
Assert.Equal("HandleRequest", result.Name);
|
||||
Assert.Null(result.ReceiverType);
|
||||
Assert.False(result.IsMethod);
|
||||
Assert.False(result.IsExternal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Parse_ParsesExternalId()
|
||||
{
|
||||
// Arrange
|
||||
var id = "go:external/os/exec.Command";
|
||||
|
||||
// Act
|
||||
var result = GoSymbolIdBuilder.Parse(id);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal("os/exec", result.PackagePath);
|
||||
Assert.Equal("Command", result.Name);
|
||||
Assert.True(result.IsExternal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsStdLib_ReturnsTrueForStandardLibrary()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.True(GoSymbolIdBuilder.IsStdLib("go:external/fmt.Println"));
|
||||
Assert.True(GoSymbolIdBuilder.IsStdLib("go:external/os/exec.Command"));
|
||||
Assert.False(GoSymbolIdBuilder.IsStdLib("go:external/github.com/gin-gonic/gin.New"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GoSsaResultParser_ParsesValidJson()
|
||||
{
|
||||
// Arrange
|
||||
var json = """
|
||||
{
|
||||
"module": "github.com/example/app",
|
||||
"nodes": [
|
||||
{
|
||||
"id": "go:github.com/example/app.main",
|
||||
"package": "github.com/example/app",
|
||||
"name": "main"
|
||||
}
|
||||
],
|
||||
"edges": [],
|
||||
"entrypoints": [
|
||||
{
|
||||
"id": "go:github.com/example/app.main",
|
||||
"type": "cli_command"
|
||||
}
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
// Act
|
||||
var result = GoSsaResultParser.Parse(json);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("github.com/example/app", result.Module);
|
||||
Assert.Single(result.Nodes);
|
||||
Assert.Empty(result.Edges);
|
||||
Assert.Single(result.Entrypoints);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GoSsaResultParser_ThrowsOnEmptyInput()
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
Assert.Throws<ArgumentException>(() => GoSsaResultParser.Parse(""));
|
||||
Assert.Throws<ArgumentException>(() => GoSsaResultParser.Parse(" "));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GoEntrypointClassifier_ClassifiesHttpHandler()
|
||||
{
|
||||
// Arrange
|
||||
var classifier = new GoEntrypointClassifier();
|
||||
var node = new CallGraphNode(
|
||||
NodeId: "go:example/api.HandleUsers",
|
||||
Symbol: "HandleUsers",
|
||||
File: "api.go",
|
||||
Line: 10,
|
||||
Package: "example/api",
|
||||
Visibility: Visibility.Public,
|
||||
IsEntrypoint: false,
|
||||
EntrypointType: null,
|
||||
IsSink: false,
|
||||
SinkCategory: null);
|
||||
|
||||
var func = new GoFunctionInfo
|
||||
{
|
||||
NodeId = "go:example/api.GetUsers",
|
||||
Name = "GetUsers",
|
||||
Package = "example/api",
|
||||
Receiver = "",
|
||||
IsExported = true,
|
||||
HasGinContext = true,
|
||||
Annotations = ["gin.GET", "route:/users"]
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = classifier.Classify(func);
|
||||
|
||||
// Assert
|
||||
Assert.True(result.HasValue);
|
||||
Assert.Equal(EntrypointType.HttpHandler, result.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GoSinkMatcher_MatchesExecCommand()
|
||||
{
|
||||
// Arrange
|
||||
var matcher = new GoSinkMatcher();
|
||||
|
||||
// Act
|
||||
var result = matcher.Match("os/exec", "Command");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(SinkCategory.CmdExec, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GoSinkMatcher_MatchesSqlQuery()
|
||||
{
|
||||
// Arrange
|
||||
var matcher = new GoSinkMatcher();
|
||||
|
||||
// Act
|
||||
var result = matcher.Match("database/sql", "Query");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(SinkCategory.SqlRaw, result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user