grok-cli-acp 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +42 -0
- package/.github/workflows/ci.yml +30 -0
- package/.github/workflows/rust.yml +22 -0
- package/.grok/.env.example +85 -0
- package/.grok/COMPLETE_FIX_SUMMARY.md +466 -0
- package/.grok/ENV_CONFIG_GUIDE.md +173 -0
- package/.grok/QUICK_REFERENCE.md +180 -0
- package/.grok/README.md +104 -0
- package/.grok/TESTING_GUIDE.md +393 -0
- package/CHANGELOG.md +465 -0
- package/CODE_REVIEW_SUMMARY.md +414 -0
- package/COMPLETE_FIX_SUMMARY.md +415 -0
- package/CONFIGURATION.md +489 -0
- package/CONTEXT_FILES_GUIDE.md +419 -0
- package/CONTRIBUTING.md +55 -0
- package/CURSOR_POSITION_FIX.md +206 -0
- package/Cargo.toml +88 -0
- package/ERROR_HANDLING_REPORT.md +361 -0
- package/FINAL_FIX_SUMMARY.md +462 -0
- package/FIXES.md +37 -0
- package/FIXES_SUMMARY.md +87 -0
- package/GROK_API_MIGRATION_SUMMARY.md +111 -0
- package/LICENSE +22 -0
- package/MIGRATION_TO_GROK_API.md +223 -0
- package/README.md +504 -0
- package/REVIEW_COMPLETE.md +416 -0
- package/REVIEW_QUICK_REFERENCE.md +173 -0
- package/SECURITY.md +463 -0
- package/SECURITY_AUDIT.md +661 -0
- package/SETUP.md +287 -0
- package/TESTING_TOOLS.md +88 -0
- package/TESTING_TOOL_EXECUTION.md +239 -0
- package/TOOL_EXECUTION_FIX.md +491 -0
- package/VERIFICATION_CHECKLIST.md +419 -0
- package/docs/API.md +74 -0
- package/docs/CHAT_LOGGING.md +39 -0
- package/docs/CURSOR_FIX_DEMO.md +306 -0
- package/docs/ERROR_HANDLING_GUIDE.md +547 -0
- package/docs/FILE_OPERATIONS.md +449 -0
- package/docs/INTERACTIVE.md +401 -0
- package/docs/PROJECT_CREATION_GUIDE.md +570 -0
- package/docs/QUICKSTART.md +378 -0
- package/docs/QUICK_REFERENCE.md +691 -0
- package/docs/RELEASE_NOTES_0.1.2.md +240 -0
- package/docs/TOOLS.md +459 -0
- package/docs/TOOLS_QUICK_REFERENCE.md +210 -0
- package/docs/ZED_INTEGRATION.md +371 -0
- package/docs/extensions.md +464 -0
- package/docs/settings.md +293 -0
- package/examples/extensions/logging-hook/README.md +91 -0
- package/examples/extensions/logging-hook/extension.json +22 -0
- package/package.json +30 -0
- package/scripts/test_acp.py +252 -0
- package/scripts/test_acp.sh +143 -0
- package/scripts/test_acp_simple.sh +72 -0
- package/src/acp/mod.rs +741 -0
- package/src/acp/protocol.rs +323 -0
- package/src/acp/security.rs +298 -0
- package/src/acp/tools.rs +697 -0
- package/src/bin/banner_demo.rs +216 -0
- package/src/bin/docgen.rs +18 -0
- package/src/bin/installer.rs +217 -0
- package/src/cli/app.rs +310 -0
- package/src/cli/commands/acp.rs +721 -0
- package/src/cli/commands/chat.rs +485 -0
- package/src/cli/commands/code.rs +513 -0
- package/src/cli/commands/config.rs +394 -0
- package/src/cli/commands/health.rs +442 -0
- package/src/cli/commands/history.rs +421 -0
- package/src/cli/commands/mod.rs +14 -0
- package/src/cli/commands/settings.rs +1384 -0
- package/src/cli/mod.rs +166 -0
- package/src/config/mod.rs +2212 -0
- package/src/display/ascii_art.rs +139 -0
- package/src/display/banner.rs +289 -0
- package/src/display/components/input.rs +323 -0
- package/src/display/components/mod.rs +2 -0
- package/src/display/components/settings_list.rs +306 -0
- package/src/display/interactive.rs +1255 -0
- package/src/display/mod.rs +62 -0
- package/src/display/terminal.rs +42 -0
- package/src/display/tips.rs +316 -0
- package/src/grok_client_ext.rs +177 -0
- package/src/hooks/loader.rs +407 -0
- package/src/hooks/mod.rs +158 -0
- package/src/lib.rs +174 -0
- package/src/main.rs +65 -0
- package/src/mcp/client.rs +195 -0
- package/src/mcp/config.rs +20 -0
- package/src/mcp/mod.rs +6 -0
- package/src/mcp/protocol.rs +67 -0
- package/src/utils/auth.rs +41 -0
- package/src/utils/chat_logger.rs +568 -0
- package/src/utils/context.rs +390 -0
- package/src/utils/mod.rs +16 -0
- package/src/utils/network.rs +320 -0
- package/src/utils/rate_limiter.rs +166 -0
- package/src/utils/session.rs +73 -0
- package/src/utils/shell_permissions.rs +389 -0
- package/src/utils/telemetry.rs +41 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
//! Health check command handler for grok-cli
|
|
2
|
+
//!
|
|
3
|
+
//! Handles health checking operations including API connectivity tests,
|
|
4
|
+
//! configuration validation, and system diagnostics.
|
|
5
|
+
|
|
6
|
+
use anyhow::{Result, anyhow};
|
|
7
|
+
use colored::*;
|
|
8
|
+
use std::time::{Duration, Instant};
|
|
9
|
+
|
|
10
|
+
use crate::GrokClient;
|
|
11
|
+
use crate::cli::{create_spinner, print_error, print_info, print_success, print_warning};
|
|
12
|
+
use crate::config::Config;
|
|
13
|
+
use crate::utils::network::{detect_starlink_connection, test_connectivity};
|
|
14
|
+
|
|
15
|
+
/// Handle health check commands
|
|
16
|
+
pub async fn handle_health_check(
|
|
17
|
+
check_api: bool,
|
|
18
|
+
check_config: bool,
|
|
19
|
+
api_key: Option<&str>,
|
|
20
|
+
config: &Config,
|
|
21
|
+
model: &str,
|
|
22
|
+
timeout_secs: u64,
|
|
23
|
+
) -> Result<()> {
|
|
24
|
+
println!("{}", "🏥 Grok CLI Health Check".cyan().bold());
|
|
25
|
+
println!();
|
|
26
|
+
|
|
27
|
+
let mut checks_passed = 0;
|
|
28
|
+
let mut total_checks = 0;
|
|
29
|
+
let mut warnings = Vec::new();
|
|
30
|
+
|
|
31
|
+
// Always run basic system checks
|
|
32
|
+
println!("{}", "System Checks:".green().bold());
|
|
33
|
+
|
|
34
|
+
// Check configuration file
|
|
35
|
+
total_checks += 1;
|
|
36
|
+
let config_file_status = check_config_file().await;
|
|
37
|
+
match config_file_status {
|
|
38
|
+
Ok(()) => {
|
|
39
|
+
print_success("Configuration file found and readable");
|
|
40
|
+
checks_passed += 1;
|
|
41
|
+
}
|
|
42
|
+
Err(e) => {
|
|
43
|
+
print_error(&format!("Configuration file issue: {}", e));
|
|
44
|
+
warnings.push("Configuration file may need to be initialized".to_string());
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Check environment variables
|
|
49
|
+
total_checks += 1;
|
|
50
|
+
let env_status = check_environment();
|
|
51
|
+
match env_status {
|
|
52
|
+
Ok(env_info) => {
|
|
53
|
+
print_success(&format!("Environment: {}", env_info));
|
|
54
|
+
checks_passed += 1;
|
|
55
|
+
}
|
|
56
|
+
Err(e) => {
|
|
57
|
+
print_warning(&format!("Environment check: {}", e));
|
|
58
|
+
checks_passed += 1; // Not critical
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Check network connectivity
|
|
63
|
+
total_checks += 1;
|
|
64
|
+
println!();
|
|
65
|
+
println!("{}", "Network Checks:".green().bold());
|
|
66
|
+
|
|
67
|
+
let spinner = create_spinner("Testing basic connectivity...");
|
|
68
|
+
let connectivity_result = test_connectivity(Duration::from_secs(5)).await;
|
|
69
|
+
spinner.finish_and_clear();
|
|
70
|
+
|
|
71
|
+
match connectivity_result {
|
|
72
|
+
Ok(latency) => {
|
|
73
|
+
print_success(&format!("Network connectivity OK (latency: {:?})", latency));
|
|
74
|
+
checks_passed += 1;
|
|
75
|
+
|
|
76
|
+
if latency > Duration::from_millis(1000) {
|
|
77
|
+
warnings.push(
|
|
78
|
+
"High network latency detected - consider Starlink optimizations".to_string(),
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
Err(e) => {
|
|
83
|
+
print_error(&format!("Network connectivity failed: {}", e));
|
|
84
|
+
warnings.push("Network issues may affect API calls".to_string());
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Check for Starlink connection
|
|
89
|
+
total_checks += 1;
|
|
90
|
+
let starlink_spinner = create_spinner("Detecting network type...");
|
|
91
|
+
let is_starlink = detect_starlink_connection().await;
|
|
92
|
+
starlink_spinner.finish_and_clear();
|
|
93
|
+
|
|
94
|
+
if is_starlink {
|
|
95
|
+
print_info("Detected possible Starlink satellite connection");
|
|
96
|
+
if config.network.starlink_optimizations {
|
|
97
|
+
print_success("Starlink optimizations are enabled");
|
|
98
|
+
} else {
|
|
99
|
+
print_warning("Consider enabling Starlink optimizations");
|
|
100
|
+
warnings.push("Enable Starlink optimizations with: grok config set network.starlink_optimizations true".to_string());
|
|
101
|
+
}
|
|
102
|
+
checks_passed += 1;
|
|
103
|
+
} else {
|
|
104
|
+
print_info("Standard internet connection detected");
|
|
105
|
+
checks_passed += 1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Configuration validation if requested
|
|
109
|
+
if check_config {
|
|
110
|
+
println!();
|
|
111
|
+
println!("{}", "Configuration Validation:".green().bold());
|
|
112
|
+
|
|
113
|
+
total_checks += 1;
|
|
114
|
+
match config.validate() {
|
|
115
|
+
Ok(()) => {
|
|
116
|
+
print_success("Configuration is valid");
|
|
117
|
+
checks_passed += 1;
|
|
118
|
+
}
|
|
119
|
+
Err(e) => {
|
|
120
|
+
print_error(&format!("Configuration validation failed: {}", e));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Check specific configuration values
|
|
125
|
+
total_checks += 1;
|
|
126
|
+
if config.api_key.is_some() {
|
|
127
|
+
print_success("API key is configured");
|
|
128
|
+
checks_passed += 1;
|
|
129
|
+
} else {
|
|
130
|
+
print_warning("No API key configured");
|
|
131
|
+
warnings.push("Set API key with: grok config set api_key YOUR_API_KEY".to_string());
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
total_checks += 1;
|
|
135
|
+
if config.acp.enabled {
|
|
136
|
+
print_info("ACP (Zed integration) is enabled");
|
|
137
|
+
checks_passed += 1;
|
|
138
|
+
} else {
|
|
139
|
+
print_info("ACP is disabled");
|
|
140
|
+
checks_passed += 1;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// API connectivity test if requested
|
|
145
|
+
if check_api {
|
|
146
|
+
println!();
|
|
147
|
+
println!("{}", "API Connectivity:".green().bold());
|
|
148
|
+
|
|
149
|
+
if let Some(key) = api_key {
|
|
150
|
+
total_checks += 2;
|
|
151
|
+
|
|
152
|
+
// Test API key validity
|
|
153
|
+
let api_spinner = create_spinner("Testing Grok API connection...");
|
|
154
|
+
let client_result = GrokClient::with_settings(key, timeout_secs, 3)
|
|
155
|
+
.map(|client| client.with_rate_limits(config.rate_limits));
|
|
156
|
+
|
|
157
|
+
match client_result {
|
|
158
|
+
Ok(client) => {
|
|
159
|
+
let test_result = client.test_connection().await;
|
|
160
|
+
api_spinner.finish_and_clear();
|
|
161
|
+
|
|
162
|
+
match test_result {
|
|
163
|
+
Ok(()) => {
|
|
164
|
+
print_success("Grok API connection successful");
|
|
165
|
+
checks_passed += 2;
|
|
166
|
+
}
|
|
167
|
+
Err(e) => {
|
|
168
|
+
print_error(&format!("Grok API connection failed: {}", e));
|
|
169
|
+
|
|
170
|
+
// Provide specific error guidance
|
|
171
|
+
let error_msg = e.to_string().to_lowercase();
|
|
172
|
+
if error_msg.contains("authentication") || error_msg.contains("401") {
|
|
173
|
+
warnings.push(
|
|
174
|
+
"Check your API key - it may be invalid or expired".to_string(),
|
|
175
|
+
);
|
|
176
|
+
} else if error_msg.contains("timeout") || error_msg.contains("network")
|
|
177
|
+
{
|
|
178
|
+
warnings.push(
|
|
179
|
+
"Network connectivity issues - check your internet connection"
|
|
180
|
+
.to_string(),
|
|
181
|
+
);
|
|
182
|
+
} else if error_msg.contains("rate limit") || error_msg.contains("429")
|
|
183
|
+
{
|
|
184
|
+
warnings
|
|
185
|
+
.push("API rate limit exceeded - try again later".to_string());
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
Err(e) => {
|
|
191
|
+
api_spinner.finish_and_clear();
|
|
192
|
+
print_error(&format!("Failed to create API client: {}", e));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Test model availability
|
|
197
|
+
match GrokClient::with_settings(key, timeout_secs, 3)
|
|
198
|
+
.map(|client| client.with_rate_limits(config.rate_limits))
|
|
199
|
+
{
|
|
200
|
+
Ok(client) => {
|
|
201
|
+
let models_spinner = create_spinner("Checking model availability...");
|
|
202
|
+
let models_result = client.list_models().await;
|
|
203
|
+
models_spinner.finish_and_clear();
|
|
204
|
+
|
|
205
|
+
match models_result {
|
|
206
|
+
Ok(models) => {
|
|
207
|
+
if models.contains(&model.to_string()) {
|
|
208
|
+
print_success(&format!("Model '{}' is available", model));
|
|
209
|
+
} else {
|
|
210
|
+
print_warning(&format!("Model '{}' may not be available", model));
|
|
211
|
+
print_info(&format!("Available models: {}", models.join(", ")));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
Err(e) => {
|
|
215
|
+
print_warning(&format!("Could not check model availability: {}", e));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
Err(_) => {
|
|
220
|
+
// Already handled above
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
} else {
|
|
224
|
+
print_warning("No API key provided - skipping API tests");
|
|
225
|
+
warnings.push("Provide API key to test API connectivity".to_string());
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Performance diagnostics
|
|
230
|
+
println!();
|
|
231
|
+
println!("{}", "Performance Diagnostics:".green().bold());
|
|
232
|
+
|
|
233
|
+
total_checks += 1;
|
|
234
|
+
let perf_result = run_performance_diagnostics(config).await;
|
|
235
|
+
match perf_result {
|
|
236
|
+
Ok(diagnostics) => {
|
|
237
|
+
print_success("Performance diagnostics completed");
|
|
238
|
+
display_performance_results(&diagnostics);
|
|
239
|
+
checks_passed += 1;
|
|
240
|
+
}
|
|
241
|
+
Err(e) => {
|
|
242
|
+
print_warning(&format!("Performance diagnostics failed: {}", e));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Summary
|
|
247
|
+
println!();
|
|
248
|
+
println!("{}", "Health Check Summary:".cyan().bold());
|
|
249
|
+
println!("{}", "─".repeat(50));
|
|
250
|
+
|
|
251
|
+
let success_rate = if total_checks > 0 {
|
|
252
|
+
(checks_passed as f64 / total_checks as f64) * 100.0
|
|
253
|
+
} else {
|
|
254
|
+
100.0
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
let status_color = if success_rate >= 90.0 {
|
|
258
|
+
"green"
|
|
259
|
+
} else if success_rate >= 70.0 {
|
|
260
|
+
"yellow"
|
|
261
|
+
} else {
|
|
262
|
+
"red"
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
match status_color {
|
|
266
|
+
"green" => println!(
|
|
267
|
+
"Status: {} ({:.0}%)",
|
|
268
|
+
"✓ HEALTHY".green().bold(),
|
|
269
|
+
success_rate
|
|
270
|
+
),
|
|
271
|
+
"yellow" => println!(
|
|
272
|
+
"Status: {} ({:.0}%)",
|
|
273
|
+
"⚠ WARNING".yellow().bold(),
|
|
274
|
+
success_rate
|
|
275
|
+
),
|
|
276
|
+
"red" => println!(
|
|
277
|
+
"Status: {} ({:.0}%)",
|
|
278
|
+
"✗ UNHEALTHY".red().bold(),
|
|
279
|
+
success_rate
|
|
280
|
+
),
|
|
281
|
+
_ => unreachable!(),
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
println!("Checks passed: {}/{}", checks_passed, total_checks);
|
|
285
|
+
|
|
286
|
+
if !warnings.is_empty() {
|
|
287
|
+
println!();
|
|
288
|
+
println!("{}", "Recommendations:".yellow().bold());
|
|
289
|
+
for (i, warning) in warnings.iter().enumerate() {
|
|
290
|
+
println!(" {}. {}", i + 1, warning);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
println!();
|
|
295
|
+
if success_rate >= 90.0 {
|
|
296
|
+
print_success("System is healthy and ready to use!");
|
|
297
|
+
} else if success_rate >= 70.0 {
|
|
298
|
+
print_warning("System has minor issues but should work");
|
|
299
|
+
} else {
|
|
300
|
+
print_error("System has significant issues that need attention");
|
|
301
|
+
return Err(anyhow!(
|
|
302
|
+
"Health check failed with {:.0}% success rate",
|
|
303
|
+
success_rate
|
|
304
|
+
));
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
Ok(())
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/// Check if configuration file exists and is readable
|
|
311
|
+
async fn check_config_file() -> Result<()> {
|
|
312
|
+
let config_path = Config::default_config_path()?;
|
|
313
|
+
|
|
314
|
+
if !config_path.exists() {
|
|
315
|
+
return Err(anyhow!("Configuration file not found at {:?}", config_path));
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Try to load the config to ensure it's valid
|
|
319
|
+
Config::load(None).await?;
|
|
320
|
+
|
|
321
|
+
Ok(())
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/// Check environment variables and system information
|
|
325
|
+
fn check_environment() -> Result<String> {
|
|
326
|
+
let mut env_info = Vec::new();
|
|
327
|
+
|
|
328
|
+
// Check OS
|
|
329
|
+
env_info.push(format!("OS: {}", std::env::consts::OS));
|
|
330
|
+
|
|
331
|
+
// Check if running in terminal
|
|
332
|
+
if std::io::IsTerminal::is_terminal(&std::io::stdout()) {
|
|
333
|
+
env_info.push("Terminal: Yes".to_string());
|
|
334
|
+
} else {
|
|
335
|
+
env_info.push("Terminal: No (piped/redirected)".to_string());
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Check for NO_COLOR environment variable
|
|
339
|
+
if std::env::var("NO_COLOR").is_ok() {
|
|
340
|
+
env_info.push("Colors: Disabled (NO_COLOR set)".to_string());
|
|
341
|
+
} else {
|
|
342
|
+
env_info.push("Colors: Enabled".to_string());
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Check for relevant environment variables
|
|
346
|
+
let mut env_vars = Vec::new();
|
|
347
|
+
if std::env::var("GROK_API_KEY").is_ok() {
|
|
348
|
+
env_vars.push("GROK_API_KEY");
|
|
349
|
+
}
|
|
350
|
+
if std::env::var("X_API_KEY").is_ok() {
|
|
351
|
+
env_vars.push("X_API_KEY");
|
|
352
|
+
}
|
|
353
|
+
if std::env::var("GROK_MODEL").is_ok() {
|
|
354
|
+
env_vars.push("GROK_MODEL");
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if !env_vars.is_empty() {
|
|
358
|
+
env_info.push(format!("Env vars: {}", env_vars.join(", ")));
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
Ok(env_info.join(", "))
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/// Performance diagnostics data
|
|
365
|
+
struct PerformanceDiagnostics {
|
|
366
|
+
memory_usage: u64,
|
|
367
|
+
startup_time: Duration,
|
|
368
|
+
config_load_time: Duration,
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/// Run performance diagnostics
|
|
372
|
+
async fn run_performance_diagnostics(_config: &Config) -> Result<PerformanceDiagnostics> {
|
|
373
|
+
let start_time = Instant::now();
|
|
374
|
+
|
|
375
|
+
// Measure config reload time
|
|
376
|
+
let config_start = Instant::now();
|
|
377
|
+
Config::load(None).await?;
|
|
378
|
+
let config_load_time = config_start.elapsed();
|
|
379
|
+
|
|
380
|
+
// Estimate memory usage (simplified)
|
|
381
|
+
let memory_usage = estimate_memory_usage();
|
|
382
|
+
|
|
383
|
+
let startup_time = start_time.elapsed();
|
|
384
|
+
|
|
385
|
+
Ok(PerformanceDiagnostics {
|
|
386
|
+
memory_usage,
|
|
387
|
+
startup_time,
|
|
388
|
+
config_load_time,
|
|
389
|
+
})
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/// Display performance diagnostic results
|
|
393
|
+
fn display_performance_results(diagnostics: &PerformanceDiagnostics) {
|
|
394
|
+
println!(" Memory usage: ~{} KB", diagnostics.memory_usage / 1024);
|
|
395
|
+
println!(" Config load time: {:?}", diagnostics.config_load_time);
|
|
396
|
+
println!(" Startup time: {:?}", diagnostics.startup_time);
|
|
397
|
+
|
|
398
|
+
// Performance warnings
|
|
399
|
+
if diagnostics.config_load_time > Duration::from_millis(100) {
|
|
400
|
+
print_warning("Configuration loading is slow");
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if diagnostics.memory_usage > 50 * 1024 * 1024 {
|
|
404
|
+
// 50MB
|
|
405
|
+
print_warning("High memory usage detected");
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/// Estimate current memory usage (simplified approach)
|
|
410
|
+
fn estimate_memory_usage() -> u64 {
|
|
411
|
+
// This is a simplified estimation
|
|
412
|
+
// In a real implementation, you might use system-specific APIs
|
|
413
|
+
// to get actual memory usage
|
|
414
|
+
10 * 1024 * 1024 // Estimate 10MB base usage
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
#[cfg(test)]
|
|
418
|
+
mod tests {
|
|
419
|
+
use super::*;
|
|
420
|
+
|
|
421
|
+
#[test]
|
|
422
|
+
fn test_check_environment() {
|
|
423
|
+
let result = check_environment();
|
|
424
|
+
assert!(result.is_ok());
|
|
425
|
+
let env_info = result.unwrap();
|
|
426
|
+
assert!(env_info.contains("OS:"));
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
#[test]
|
|
430
|
+
fn test_estimate_memory_usage() {
|
|
431
|
+
let memory = estimate_memory_usage();
|
|
432
|
+
assert!(memory > 0);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
#[tokio::test]
|
|
436
|
+
async fn test_performance_diagnostics() {
|
|
437
|
+
let config = Config::default();
|
|
438
|
+
let result = run_performance_diagnostics(&config).await;
|
|
439
|
+
// This test might fail if config loading fails, but that's expected
|
|
440
|
+
// in a test environment without proper setup
|
|
441
|
+
}
|
|
442
|
+
}
|