Skip to main content
Glama

Azure MCP Server

Official
MIT License
1,161
  • Linux
  • Apple
ResourceLogQueryCommandTests.cs10.4 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System.CommandLine; using System.CommandLine.Parsing; using System.Text.Json.Nodes; using AzureMcp.Core.Models.Command; using AzureMcp.Core.Options; using AzureMcp.Monitor.Commands.Log; using AzureMcp.Monitor.Services; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using NSubstitute; using Xunit; namespace AzureMcp.Monitor.UnitTests.Log; [Trait("Area", "Monitor")] public sealed class ResourceLogQueryCommandTests { private readonly IServiceProvider _serviceProvider; private readonly IMonitorService _monitorService; private readonly ILogger<ResourceLogQueryCommand> _logger; private readonly ResourceLogQueryCommand _command; private readonly CommandContext _context; private readonly Parser _parser; private const string _knownSubscription = "knownSubscription"; private const string _knownResourceId = "/subscriptions/sub123/resourceGroups/rg1/providers/Microsoft.Storage/storageAccounts/storage1"; private const string _knownTable = "StorageEvents"; private const string _knownQuery = "| limit 10"; private const string _knownTenant = "knownTenant"; private const string _knownHours = "24"; private const string _knownLimit = "100"; public ResourceLogQueryCommandTests() { _monitorService = Substitute.For<IMonitorService>(); _logger = Substitute.For<ILogger<ResourceLogQueryCommand>>(); var collection = new ServiceCollection(); collection.AddSingleton(_monitorService); _serviceProvider = collection.BuildServiceProvider(); _command = new(_logger); _context = new(_serviceProvider); _parser = new(_command.GetCommand()); } [Theory] [InlineData($"--subscription {_knownSubscription} --resource-id {_knownResourceId} --table {_knownTable} --query {_knownQuery}", true)] [InlineData($"--subscription {_knownSubscription} --resource-id {_knownResourceId} --table {_knownTable} --query {_knownQuery} --hours {_knownHours} --limit {_knownLimit}", true)] [InlineData($"--subscription {_knownSubscription} --table {_knownTable} --query {_knownQuery}", false)] // missing resource-id [InlineData($"--subscription {_knownSubscription}", false)] [InlineData("", false)] public async Task ExecuteAsync_ValidatesInputCorrectly(string args, bool shouldSucceed) { // Arrange if (shouldSucceed) { var mockResults = new List<JsonNode> { JsonNode.Parse(@"{""TimeGenerated"": ""2023-01-01T12:00:00Z"", ""Message"": ""Resource log entry""}") ?? JsonNode.Parse("{}") ?? new JsonObject(), JsonNode.Parse(@"{""TimeGenerated"": ""2023-01-01T12:01:00Z"", ""Message"": ""Another resource log entry""}") ?? JsonNode.Parse("{}") ?? new JsonObject() }; _monitorService.QueryResourceLogs( _knownSubscription, _knownResourceId, _knownQuery, _knownTable, Arg.Any<int?>(), Arg.Any<int?>(), Arg.Any<string>(), Arg.Any<RetryPolicyOptions>()) .Returns(mockResults); } // Act var response = await _command.ExecuteAsync(_context, _parser.Parse(args)); // Assert Assert.Equal(shouldSucceed ? 200 : 400, response.Status); if (shouldSucceed) { Assert.NotNull(response.Results); Assert.Equal("Success", response.Message); } else { Assert.Contains("required", response.Message.ToLower()); } } [Fact] public async Task ExecuteAsync_ReturnsQueryResults() { // Arrange var mockResults = new List<JsonNode> { JsonNode.Parse($@"{{""TimeGenerated"": ""2023-01-01T12:00:00Z"", ""ResourceId"": ""{_knownResourceId}"", ""Level"": ""Info""}}") ?? new JsonObject(), JsonNode.Parse($@"{{""TimeGenerated"": ""2023-01-01T12:01:00Z"", ""ResourceId"": ""{_knownResourceId}"", ""Level"": ""Warning""}}") ?? new JsonObject(), JsonNode.Parse($@"{{""TimeGenerated"": ""2023-01-01T12:02:00Z"", ""ResourceId"": ""{_knownResourceId}"", ""Level"": ""Error""}}") ?? new JsonObject() }; _monitorService.QueryResourceLogs( _knownSubscription, _knownResourceId, _knownQuery, _knownTable, Arg.Any<int?>(), Arg.Any<int?>(), Arg.Any<string>(), Arg.Any<RetryPolicyOptions>()) .Returns(mockResults); var args = _parser.Parse([ "--subscription", _knownSubscription, "--resource-id", _knownResourceId, "--table", _knownTable, "--query", _knownQuery ]); // Act var response = await _command.ExecuteAsync(_context, args); // Assert Assert.Equal(200, response.Status); Assert.NotNull(response.Results); // Verify the mock was called await _monitorService.Received(1).QueryResourceLogs( _knownSubscription, _knownResourceId, _knownQuery, _knownTable, Arg.Any<int?>(), Arg.Any<int?>(), Arg.Any<string>(), Arg.Any<RetryPolicyOptions>()); } [Fact] public async Task ExecuteAsync_CallsServiceWithCorrectParameters() { // Arrange var mockResults = new List<JsonNode> { JsonNode.Parse(@"{""result"": ""data""}") ?? new JsonObject() }; _monitorService.QueryResourceLogs( _knownSubscription, _knownResourceId, _knownQuery, _knownTable, int.Parse(_knownHours), int.Parse(_knownLimit), _knownTenant, Arg.Any<RetryPolicyOptions>()) .Returns(mockResults); var args = _parser.Parse([ "--subscription", _knownSubscription, "--resource-id", _knownResourceId, "--table", _knownTable, "--query", _knownQuery, "--hours", _knownHours, "--limit", _knownLimit, "--tenant", _knownTenant ]); // Act var response = await _command.ExecuteAsync(_context, args); // Assert Assert.Equal(200, response.Status); await _monitorService.Received(1).QueryResourceLogs( _knownSubscription, _knownResourceId, _knownQuery, _knownTable, int.Parse(_knownHours), int.Parse(_knownLimit), _knownTenant, Arg.Any<RetryPolicyOptions>()); } [Fact] public async Task ExecuteAsync_WithDefaultParameters_UsesExpectedDefaults() { // Arrange var mockResults = new List<JsonNode> { JsonNode.Parse(@"{""result"": ""data""}") ?? new JsonObject() }; _monitorService.QueryResourceLogs( _knownSubscription, _knownResourceId, _knownQuery, _knownTable, Arg.Any<int?>(), Arg.Any<int?>(), Arg.Any<string>(), Arg.Any<RetryPolicyOptions>()) .Returns(mockResults); var args = _parser.Parse([ "--subscription", _knownSubscription, "--resource-id", _knownResourceId, "--table", _knownTable, "--query", _knownQuery ]); // Act var response = await _command.ExecuteAsync(_context, args); // Assert Assert.Equal(200, response.Status); await _monitorService.Received(1).QueryResourceLogs( _knownSubscription, _knownResourceId, _knownQuery, _knownTable, Arg.Any<int?>(), // Default hours Arg.Any<int?>(), // Default limit Arg.Any<string>(), Arg.Any<RetryPolicyOptions>()); } [Fact] public async Task ExecuteAsync_HandlesServiceErrors() { // Arrange _monitorService.QueryResourceLogs( _knownSubscription, _knownResourceId, _knownQuery, _knownTable, Arg.Any<int?>(), Arg.Any<int?>(), Arg.Any<string>(), Arg.Any<RetryPolicyOptions>()) .Returns(Task.FromException<List<JsonNode>>(new Exception("Test error"))); var args = _parser.Parse([ "--subscription", _knownSubscription, "--resource-id", _knownResourceId, "--table", _knownTable, "--query", _knownQuery ]); // Act var response = await _command.ExecuteAsync(_context, args); // Assert Assert.Equal(500, response.Status); Assert.Contains("Test error", response.Message); Assert.Contains("troubleshooting", response.Message); } [Fact] public async Task ExecuteAsync_WithComplexResourceId_HandlesCorrectly() { // Arrange var complexResourceId = "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/my-rg/providers/Microsoft.Compute/virtualMachines/my-vm"; var query = "| where Level == 'Error'"; var table = "VMEvents"; var mockResults = new List<JsonNode> { JsonNode.Parse(@"{""result"": ""vm data""}") ?? new JsonObject() }; _monitorService.QueryResourceLogs( _knownSubscription, complexResourceId, query, table, Arg.Any<int?>(), Arg.Any<int?>(), Arg.Any<string>(), Arg.Any<RetryPolicyOptions>()) .Returns(mockResults); var args = _parser.Parse([ "--subscription", _knownSubscription, "--resource-id", complexResourceId, "--table", table, "--query", query ]); // Act var response = await _command.ExecuteAsync(_context, args); // Assert Assert.Equal(200, response.Status); await _monitorService.Received(1).QueryResourceLogs( _knownSubscription, complexResourceId, query, table, Arg.Any<int?>(), Arg.Any<int?>(), Arg.Any<string>(), Arg.Any<RetryPolicyOptions>()); } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Azure/azure-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server