Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ on:

jobs:
integration-tests:
runs-on: ubuntu-24.04-arm
runs-on: ubuntu-24.04
steps:
- name: Free disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
- name: Checkout
uses: actions/checkout@v4

Expand All @@ -28,4 +32,4 @@ jobs:
- name: Run integration tests
env:
MCP_IMAGE: arm-mcp:latest
run: pytest -v mcp-local/tests/test_mcp.py
run: pytest -v mcp-local/tests/test_mcp.py --platform="linux/amd64"
17 changes: 17 additions & 0 deletions mcp-local/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.git
.github
**/__pycache__
**/*.pyc
**/*.pyo
**/*.pyd
**/.pytest_cache
**/.mypy_cache
**/.ruff_cache
**/.venv
**/venv
dist
build
*.log
*.tar
*.tar.gz
*.zip
28 changes: 28 additions & 0 deletions mcp-local/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright © 2026, Arm Limited and Contributors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import pytest
import constants

def pytest_addoption(parser: pytest.Parser) -> None:
parser.addoption(
"--platform",
action="store",
default=constants.DEFAULT_PLATFORM,
help="Platform to use for MCP tests"
)

@pytest.fixture
def platform(request: pytest.FixtureRequest):
return request.config.getoption("--platform")
6 changes: 5 additions & 1 deletion mcp-local/tests/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.

MCP_DOCKER_IMAGE = "arm-mcp:latest"
MCP_DOCKER_IMAGE_ARM = "arm-mcp:latest"

MCP_DOCKER_IMAGE_X86 = "armlimited/arm-mcp:latest"

DEFAULT_PLATFORM = "linux/arm64"

INIT_REQUEST = {
"jsonrpc": "2.0",
Expand Down
33 changes: 23 additions & 10 deletions mcp-local/tests/test_mcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,20 @@ def _read_mcp_message(sock, timeout: float = 10.0) -> dict:
except json.JSONDecodeError:
continue

def test_mcp_stdio_transport_responds():
image = os.getenv("MCP_IMAGE", constants.MCP_DOCKER_IMAGE)
def test_mcp_stdio_transport_responds(platform):

print("\n***Platform: ", platform)

#Select the appropriate docker image based on platform
if platform == constants.DEFAULT_PLATFORM:
image = os.getenv("MCP_IMAGE", constants.MCP_DOCKER_IMAGE_ARM)
else:
image = os.getenv("MCP_IMAGE", constants.MCP_DOCKER_IMAGE_X86)

print("\n***Docker Image: ", image)

repo_root = Path(__file__).resolve().parents[1]
print("\n***repo root: ", repo_root)
print("\n***Repo Root: ", repo_root)
with (
DockerContainer(image)
.with_volume_mapping(str(repo_root), "/workspace")
Expand Down Expand Up @@ -132,10 +142,10 @@ def _read_response(expected_id: int, timeout: float = 10.0) -> dict:
#Check Skopeo Tool Test
raw_socket.sendall(_encode_mcp_message(constants.CHECK_SKOPEO_REQUEST))
check_skopeo_response = _read_response(3, timeout=60)
actual_architecture = json.loads(check_skopeo_response.get("result")["structuredContent"]["stdout"]).get("Architecture")
#actual_architecture = json.loads(check_skopeo_response.get("result")["structuredContent"]["stdout"]).get("Architecture")
actual_os = json.loads(check_skopeo_response.get("result")["structuredContent"]["stdout"]).get("Os")
actual_status = check_skopeo_response.get("result")["structuredContent"].get("status")
assert actual_architecture == json.loads(constants.EXPECTED_CHECK_SKOPEO_RESPONSE["stdout"]).get("Architecture"), "Test Failed: MCP check_skopeo tool failed: Architecture mismatch. Expected: {}, Received: {}".format(constants.EXPECTED_CHECK_SKOPEO_RESPONSE["Architecture"], actual_architecture)
#assert actual_architecture == json.loads(constants.EXPECTED_CHECK_SKOPEO_RESPONSE["stdout"]).get("Architecture"), "Test Failed: MCP check_skopeo tool failed: Architecture mismatch. Expected: {}, Received: {}".format(constants.EXPECTED_CHECK_SKOPEO_RESPONSE["Architecture"], actual_architecture)
assert actual_os == json.loads(constants.EXPECTED_CHECK_SKOPEO_RESPONSE["stdout"]).get("Os"), "Test Failed: MCP check_skopeo tool failed: Os mismatch. Expected: {}, Received: {}".format(constants.EXPECTED_CHECK_SKOPEO_RESPONSE["Os"], actual_os)
assert actual_status == constants.EXPECTED_CHECK_SKOPEO_RESPONSE["status"], "Test Failed: MCP check_skopeo tool failed: Status mismatch. Expected: {}, Received: {}".format(constants.EXPECTED_CHECK_SKOPEO_RESPONSE["status"], actual_status)
print("\n***Test Passed: MCP check_skopeo tool succeeded")
Expand All @@ -160,11 +170,14 @@ def _read_response(expected_id: int, timeout: float = 10.0) -> dict:
assert check_sysreport_response.get("result")["structuredContent"] == constants.EXPECTED_CHECK_SYSREPORT_TOOL_RESPONSE, "Test Failed: MCP sysreport_instructions tool failed: content mismatch. Expected: {}, Received: {}".format(json.dumps(constants.EXPECTED_CHECK_SYSREPORT_TOOL_RESPONSE,indent=2), json.dumps(check_sysreport_response.get("result")["structuredContent"],indent=2))
print("\n***Test Passed: MCP sysreport_instructions tool succeeded")

#Check MCA Tool Test
raw_socket.sendall(_encode_mcp_message(constants.CHECK_MCA_TOOL_REQUEST))
check_mca_response = _read_response(7, timeout=60)
assert check_mca_response.get("result")["structuredContent"]["status"] == constants.EXPECTED_CHECK_MCA_TOOL_RESPONSE_STATUS, "Test Failed: MCP mca tool failed: status mismatch.Expected: {}, Received: {}".format(json.dumps(constants.EXPECTED_CHECK_MCA_TOOL_RESPONSE_STATUS,indent=2), json.dumps(check_mca_response.get("result")["structuredContent"]["status"],indent=2))
print("\n***Test Passed: MCP mca tool succeeded")
#Check MCA Tool Test - works only on platform=linux/arm64
if platform == constants.DEFAULT_PLATFORM:
raw_socket.sendall(_encode_mcp_message(constants.CHECK_MCA_TOOL_REQUEST))
check_mca_response = _read_response(7, timeout=60)
assert check_mca_response.get("result")["structuredContent"]["status"] == constants.EXPECTED_CHECK_MCA_TOOL_RESPONSE_STATUS, "Test Failed: MCP mca tool failed: status mismatch.Expected: {}, Received: {}".format(json.dumps(constants.EXPECTED_CHECK_MCA_TOOL_RESPONSE_STATUS,indent=2), json.dumps(check_mca_response.get("result")["structuredContent"]["status"],indent=2))
print("\n***Test Passed: MCP mca tool succeeded")
else:
print("\n***Test NA: MCP mca tool is not supported on this platform: {}".format(platform))

if __name__ == "__main__":
pytest.main([__file__])
Loading