-
Notifications
You must be signed in to change notification settings - Fork 56
Integration testing framework #211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
cfb8847
4d93a46
be2fb1c
0d5539a
bf4c006
ebe622d
45678e9
c2b84cb
2816e68
2214827
c90c8e4
36f5c3b
dfdd959
d4828fb
91b3c44
1eefe44
a06da9a
d36ec7a
c096048
5451ddf
c2cdd40
7d91ef9
87610a5
ddfdd0b
dd0a87d
6a4e8ef
7793790
3ebbd44
a6681bf
1a7264b
9ba4a43
fab4368
a111155
a2a1092
ae8a286
9a5a6a8
aad011a
be0032a
e3f4324
a077eed
49161c3
69d68d4
3dc3efa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +0,0 @@ | ||
| This directory contains tools to aid the developers of the Microsoft 365 Agents SDK for Python. | ||
|
|
||
| ### `benchmark` | ||
|
|
||
| This folder contains benchmarking utilities built in Python to send concurrent requests | ||
| to an agent. | ||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -1,32 +1,35 @@ | ||||
| import json | ||||
| import json, sys | ||||
| from io import StringIO | ||||
| import logging | ||||
| from datetime import datetime, timezone | ||||
| from contextlib import contextmanager | ||||
|
||||
| from contextlib import contextmanager |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| from .executor import ExecutionResult | ||
|
|
||
| def output_results(results: list[ExecutionResult]) -> None: | ||
| """Output the results of the benchmark to the console.""" | ||
|
|
||
| for result in results: | ||
| status = "Success" if result.success else "Failure" | ||
| print(f"Execution ID: {result.exe_id}, Duration: {result.duration:.4f} seconds, Status: {status}") | ||
| print(result.result) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| pip install -e ./microsoft-agents-testing/ --config-settings editable_mode=compat |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| # Microsoft 365 Agents SDK for Python - Testing Framework |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| from .sdk_config import SDKConfig | ||
|
|
||
| from .auth import ( | ||
| generate_token, | ||
| generate_token_from_config | ||
| ) | ||
|
|
||
| from .utils import ( | ||
| populate_activity, | ||
| get_host_and_port | ||
| ) | ||
|
|
||
| from .integration import ( | ||
| Sample, | ||
| Environment, | ||
| ApplicationRunner, | ||
| AgentClient, | ||
| ResponseClient, | ||
| AiohttpEnvironment, | ||
| Integration | ||
| ) | ||
|
|
||
| __all__ = [ | ||
| "SDKConfig", | ||
| "generate_token", | ||
| "generate_token_from_config", | ||
| "Sample", | ||
| "Environment", | ||
| "ApplicationRunner", | ||
| "AgentClient", | ||
| "ResponseClient", | ||
| "AiohttpEnvironment", | ||
| "Integration", | ||
| "populate_activity", | ||
| "get_host_and_port" | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| from .generate_token import generate_token, generate_token_from_config | ||
|
|
||
| __all__ = [ | ||
| "generate_token", | ||
| "generate_token_from_config" | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| import requests | ||
|
|
||
| from microsoft_agents.hosting.core import AgentAuthConfiguration | ||
| from microsoft_agents.testing.sdk_config import SDKConfig | ||
|
|
||
| def generate_token(app_id: str, app_secret: str, tenant_id: str) -> str: | ||
| """Generate a token using the provided app credentials. | ||
|
|
||
| :param app_id: Application (client) ID. | ||
| :param app_secret: Application client secret. | ||
| :param tenant_id: Directory (tenant) ID. | ||
| :return: Generated access token as a string. | ||
| """ | ||
|
|
||
| authority_endpoint = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token" | ||
|
|
||
| res = requests.post( | ||
| authority_endpoint, | ||
| headers={ | ||
| "Content-Type": "application/x-www-form-urlencoded", | ||
| }, | ||
| data={ | ||
| "grant_type": "client_credentials", | ||
| "client_id": app_id, | ||
| "client_secret": app_secret, | ||
| "scope": f"{app_id}/.default", | ||
| }, | ||
| timeout=10, | ||
| ) | ||
| return res.json().get("access_token") | ||
|
|
||
| def generate_token_from_config(sdk_config: SDKConfig) -> str: | ||
| """Generates a token using a provided config object. | ||
|
|
||
| :param config: Configuration dictionary containing connection settings. | ||
| :return: Generated access token as a string. | ||
| """ | ||
|
|
||
| settings: AgentAuthConfiguration = sdk_config.get_connection() | ||
|
|
||
| app_id = settings.CLIENT_ID | ||
| app_secret = settings.CLIENT_SECRET | ||
| tenant_id = settings.TENANT_ID | ||
|
|
||
| if not app_id or not app_secret or not tenant_id: | ||
| raise ValueError("Incorrect configuration provided for token generation.") | ||
| return generate_token(app_id, app_secret, tenant_id) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| from .core import ( | ||
| AgentClient, | ||
| ApplicationRunner, | ||
| AiohttpEnvironment, | ||
| ResponseClient, | ||
| Environment, | ||
| Integration, | ||
| Sample, | ||
| ) | ||
|
|
||
| __all__ = [ | ||
| "AgentClient", | ||
| "ApplicationRunner", | ||
| "AiohttpEnvironment", | ||
| "ResponseClient", | ||
| "Environment", | ||
| "Integration", | ||
| "Sample", | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| from .application_runner import ApplicationRunner | ||
| from .aiohttp import AiohttpEnvironment | ||
| from .client import ( | ||
| AgentClient, | ||
| ResponseClient, | ||
| ) | ||
| from .environment import Environment | ||
| from .integration import Integration | ||
| from .sample import Sample | ||
|
|
||
|
|
||
| __all__ = [ | ||
| "AgentClient", | ||
| "ApplicationRunner", | ||
| "AiohttpEnvironment", | ||
| "ResponseClient", | ||
| "Environment", | ||
| "Integration", | ||
| "Sample", | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| from .aiohttp_environment import AiohttpEnvironment | ||
| from .aiohttp_runner import AiohttpRunner | ||
|
|
||
| __all__ = ["AiohttpEnvironment", "AiohttpRunner"] |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,58 @@ | ||||||||||
| from tkinter import E | ||||||||||
|
||||||||||
| from tkinter import E |
Copilot
AI
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Import of 'run_app' is not used.
| from aiohttp.web import Request, Response, Application, run_app | |
| from aiohttp.web import Request, Response, Application |
Copilot
AI
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method requires 3 positional arguments, whereas overridden Environment.create_runner requires 1.
| def create_runner(self, host: str, port: int) -> ApplicationRunner: | |
| def create_runner(self, **kwargs) -> ApplicationRunner: | |
| host = kwargs.get("host", "127.0.0.1") | |
| port = kwargs.get("port", 8080) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused imports. The
sysandStringIOimports are not used in the code. Remove them.