Skip to content

Commit 1272379

Browse files
Fix tests
1 parent 365a767 commit 1272379

File tree

5 files changed

+279
-192
lines changed

5 files changed

+279
-192
lines changed

ddev/src/ddev/cli/size/create_dashboard.py

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"--dd-org",
1414
type=str,
1515
required=True,
16-
help="Datadog organization name taken from your config file.",
16+
help="Datadog organization name taken from your config file e.g. 'default'",
1717
)
1818
@click.pass_obj
1919
def create_dashboard(
@@ -25,6 +25,12 @@ def create_dashboard(
2525
"""
2626
try:
2727
config_file_info = get_org(app, dd_org)
28+
if 'api_key' not in config_file_info:
29+
raise RuntimeError("No API key found in config file")
30+
if 'app_key' not in config_file_info:
31+
raise RuntimeError("No APP key found in config file")
32+
if 'site' not in config_file_info:
33+
raise RuntimeError("No site found in config file")
2834
headers = {
2935
"DD-API-KEY": config_file_info["api_key"],
3036
"DD-APPLICATION-KEY": config_file_info["app_key"],
@@ -46,7 +52,6 @@ def create_dashboard(
4652
resp_json = response.json()
4753
if "Forbidden" in str(resp_json.get("errors", [])):
4854
raise PermissionError("Access denied: your APP key doesn't have permission to create dashboards.")
49-
5055
print(f"Dashboard URL: https://app.{config_file_info['site']}{resp_json['url']}")
5156
except Exception as e:
5257
app.abort(str(e))
@@ -55,8 +60,10 @@ def create_dashboard(
5560
def create_json(app: Application) -> list[dict[str, Any]]:
5661
valid_platforms = get_valid_platforms(app.repo.path)
5762
widgets: list[dict[str, Any]] = []
63+
5864
for size_type in ["compressed", "uncompressed"]:
5965
for platform in valid_platforms:
66+
# Treemap widget
6067
widgets.append(
6168
{
6269
"definition": {
@@ -91,5 +98,45 @@ def create_json(app: Application) -> list[dict[str, Any]]:
9198
}
9299
}
93100
)
101+
# Timeseries widget
102+
widgets.append(
103+
{
104+
"definition": {
105+
"title": f"Timeline of {size_type} sizes in {platform}",
106+
"type": "timeseries",
107+
"requests": [
108+
{
109+
"response_format": "timeseries",
110+
"queries": [
111+
{
112+
"name": "query1",
113+
"data_source": "metrics",
114+
"query": f"sum:datadog.agent_integrations.size_analyzer.{size_type}"
115+
f"{{platform:{platform}}}",
116+
}
117+
],
118+
"formulas": [
119+
{
120+
"formula": "query1",
121+
"number_format": {
122+
"unit": {
123+
"type": "canonical_unit",
124+
"unit_name": "byte_in_binary_bytes_family",
125+
}
126+
},
127+
}
128+
],
129+
"style": {
130+
"palette": "dog_classic",
131+
"order_by": "values",
132+
"line_type": "solid",
133+
"line_width": "normal",
134+
},
135+
"display_type": "line",
136+
}
137+
],
138+
}
139+
}
140+
)
94141

95142
return widgets

ddev/src/ddev/cli/size/utils/common_funcs.py

Lines changed: 19 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -55,33 +55,33 @@ class CommitEntryPlatformWithDelta(CommitEntryWithDelta):
5555

5656

5757
class CLIParameters(TypedDict):
58-
app: Application
59-
platform: str
60-
version: str
61-
compressed: bool
62-
format: Optional[list[str]]
63-
show_gui: bool
58+
app: Application # Main application instance for CLI operations
59+
platform: str # Target platform for analysis (e.g. linux-aarch64)
60+
version: str # Target Python version for analysis
61+
compressed: bool # Whether to analyze compressed file sizes
62+
format: Optional[list[str]] # Output format options (png, csv, markdown, json)
63+
show_gui: bool # Whether to display interactive visualization
6464

6565

6666
class CLIParametersTimeline(TypedDict):
67-
app: Application
68-
module: str
69-
threshold: Optional[int]
70-
compressed: bool
71-
format: Optional[list[str]]
72-
show_gui: bool
67+
app: Application # Main application instance for CLI operations
68+
module: str # Name of module to analyze
69+
threshold: Optional[int] # Minimum size threshold for filtering
70+
compressed: bool # Whether to analyze compressed file sizes
71+
format: Optional[list[str]] # Output format options (png, csv, markdown, json)
72+
show_gui: bool # Whether to display interactive visualization
7373

7474

7575
class InitialParametersTimelineIntegration(CLIParametersTimeline):
76-
type: Literal["integration"]
77-
first_commit: str
78-
platform: None
76+
type: Literal["integration"] # Specifies this is for integration analysis
77+
first_commit: str # Starting commit hash for timeline analysis
78+
platform: None # Platform not needed for integration analysis
7979

8080

8181
class InitialParametersTimelineDependency(CLIParametersTimeline):
82-
type: Literal["dependency"]
83-
first_commit: None
84-
platform: str
82+
type: Literal["dependency"] # Specifies this is for dependency analysis
83+
first_commit: None # No commit needed for dependency analysis
84+
platform: str # Target platform for dependency analysis
8585

8686

8787
def get_valid_platforms(repo_path: Path | str) -> set[str]:
@@ -503,7 +503,7 @@ def plot_treemap(
503503
modules: list[FileDataEntryPlatformVersion],
504504
title: str,
505505
show: bool,
506-
mode: Literal["status", "diff"] = "status",
506+
mode: Literal["status", "diff"],
507507
path: Optional[str] = None,
508508
) -> None:
509509
if not any(str(value).strip() not in ("", "0") for value in modules[0].values()):
@@ -778,23 +778,6 @@ def get_org(app: Application, org: str) -> dict[str, str]:
778778
return org_data
779779

780780

781-
# def get_org(app: Application, org: Optional[str] = "default") -> dict[str, str]:
782-
# config_path = app.config_file.path
783-
784-
# with config_path.open(mode="rb") as f:
785-
# data = tomllib.load(f)
786-
787-
# org_config = data.get("orgs", {}).get(org)
788-
# if not org_config:
789-
# raise ValueError(f"Organization '{org}' not found in config")
790-
791-
# return {
792-
# "api_key": org_config["api_key"],
793-
# "app_key": org_config["app_key"],
794-
# "site": org_config.get("site"),
795-
# }
796-
797-
798781
def is_everything_committed() -> bool:
799782
result = subprocess.run(["git", "status", "--porcelain"], capture_output=True, text=True)
800783
return result.stdout.strip() == ""
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from unittest.mock import MagicMock, patch
2+
3+
import pytest
4+
5+
6+
@pytest.fixture
7+
def app():
8+
mock_app = MagicMock()
9+
mock_app.repo.path = "/fake/repo"
10+
mock_app.abort = MagicMock()
11+
return mock_app
12+
13+
14+
@pytest.fixture()
15+
def mock_dashboard_env():
16+
with (
17+
patch("ddev.cli.size.create_dashboard.get_org") as mock_get_org,
18+
patch("ddev.cli.size.create_dashboard.get_valid_platforms") as mock_get_valid_platforms,
19+
patch("ddev.cli.size.create_dashboard.requests.post") as mock_post,
20+
):
21+
mock_get_org.return_value = {"api_key": "fake-api-key", "app_key": "fake-app-key", "site": "datadoghq.com"}
22+
mock_get_valid_platforms.return_value = ["linux"]
23+
mock_response = MagicMock()
24+
mock_response.json.return_value = {"url": "/dashboard/abc123"}
25+
mock_post.return_value = mock_response
26+
27+
yield
28+
29+
30+
def test_create_dashboard_success(ddev, app, mock_dashboard_env):
31+
result = ddev("size", "create-dashboard", "--dd-org", "default", obj=app)
32+
assert result.exit_code == 0
33+
assert "Dashboard URL: https://app.datadoghq.com/dashboard/abc123" in result.output
34+
35+
36+
def test_create_dashboard_missing_api_key(ddev, app):
37+
with patch("ddev.cli.size.create_dashboard.get_org") as mock_get_org:
38+
mock_get_org.return_value = {"app_key": "fake-app-key", "site": "datadoghq.com"}
39+
40+
result = ddev("size", "create-dashboard", "--dd-org", "default", obj=app)
41+
42+
assert result.exit_code != 0
43+
assert "No API key found in config file" in result.output
44+
45+
46+
def test_create_dashboard_missing_app_key(ddev, app):
47+
with patch("ddev.cli.size.create_dashboard.get_org") as mock_get_org:
48+
mock_get_org.return_value = {"api_key": "fake-api-key", "site": "datadoghq.com"}
49+
50+
result = ddev("size", "create-dashboard", "--dd-org", "default", obj=app)
51+
52+
assert result.exit_code != 0
53+
assert "No APP key found in config file" in result.output
54+
55+
56+
def test_create_dashboard_missing_site(ddev, app):
57+
with patch("ddev.cli.size.create_dashboard.get_org") as mock_get_org:
58+
mock_get_org.return_value = {"api_key": "fake-api-key", "app_key": "fake-app-key"}
59+
60+
result = ddev("size", "create-dashboard", "--dd-org", "default", obj=app)
61+
62+
assert result.exit_code != 0
63+
assert "No site found in config file" in result.output

0 commit comments

Comments
 (0)