We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/kpeacocke/souschef'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
"""Mega test file targeting highest-value coverage gaps."""
from pathlib import Path
from souschef.server import (
analyse_chef_databag_usage,
analyse_chef_environment_usage,
assess_chef_migration_complexity,
convert_chef_databag_to_vars,
generate_inventory_from_chef_environments,
)
# ==============================================================================
# COMPLEXITY ASSESSMENT - ALL SCOPES
# ==============================================================================
def test_assess_complexity_full_scope() -> None:
"""Assess complexity with full scope."""
result = assess_chef_migration_complexity(
".", migration_scope="full", target_platform="ansible_awx"
)
assert isinstance(result, str)
def test_assess_complexity_recipes_only() -> None:
"""Assess complexity recipes only."""
result = assess_chef_migration_complexity(
".", migration_scope="recipes_only", target_platform="ansible_awx"
)
assert isinstance(result, str)
def test_assess_complexity_infrastructure_only() -> None:
"""Assess complexity infrastructure only."""
result = assess_chef_migration_complexity(
".", migration_scope="infrastructure_only", target_platform="ansible_awx"
)
assert isinstance(result, str)
def test_assess_complexity_ansible_core() -> None:
"""Assess complexity for Ansible core."""
result = assess_chef_migration_complexity(".", target_platform="ansible_core")
assert isinstance(result, str)
def test_assess_complexity_ansible_tower() -> None:
"""Assess complexity for Ansible Tower."""
result = assess_chef_migration_complexity(".", target_platform="ansible_tower")
assert isinstance(result, str)
def test_assess_complexity_multi_path() -> None:
"""Assess complexity with multiple paths."""
result = assess_chef_migration_complexity(".,/tmp")
assert isinstance(result, str)
def test_assess_complexity_tower_platform() -> None:
"""Assess complexity for Ansible Tower platform."""
result = assess_chef_migration_complexity(".", target_platform="ansible_tower")
assert isinstance(result, str)
def test_assess_complexity_core_platform() -> None:
"""Assess complexity for Ansible Core platform."""
result = assess_chef_migration_complexity(".", target_platform="ansible_core")
assert isinstance(result, str)
def test_assess_complexity_infra_scope() -> None:
"""Assess complexity with infrastructure scope."""
result = assess_chef_migration_complexity(
".", migration_scope="infrastructure_only"
)
assert isinstance(result, str)
def test_assess_complexity_all_params() -> None:
"""Assess complexity with all supported parameters."""
result = assess_chef_migration_complexity(
".", migration_scope="recipes_only", target_platform="ansible_awx"
)
assert isinstance(result, str)
# ==============================================================================
# DATABAG CONVERSION - ALL SCOPES
# ==============================================================================
def test_databag_group_vars_scope() -> None:
"""Convert databag to group_vars scope."""
result = convert_chef_databag_to_vars(
'{"key": "value"}', "app", target_scope="group_vars"
)
assert isinstance(result, str)
def test_databag_host_vars_scope() -> None:
"""Convert databag to host_vars scope."""
result = convert_chef_databag_to_vars(
'{"key": "value"}', "config", target_scope="host_vars"
)
assert isinstance(result, str)
def test_databag_playbook_scope() -> None:
"""Convert databag to playbook scope."""
result = convert_chef_databag_to_vars(
'{"key": "value"}', "vars", target_scope="playbook"
)
assert isinstance(result, str)
def test_databag_nested_content() -> None:
"""Convert databag with nested content."""
content = '{"db": {"primary": {"host": "db1.prod", "port": 5432}}}'
result = convert_chef_databag_to_vars(content, "database")
assert isinstance(result, str)
def test_databag_array_content() -> None:
"""Convert databag with arrays."""
content = '{"services": ["web", "api", "worker"], "ports": [8080, 8081, 9000]}'
result = convert_chef_databag_to_vars(content, "services")
assert isinstance(result, str)
def test_databag_custom_item_name() -> None:
"""Convert databag with custom item name."""
result = convert_chef_databag_to_vars(
'{"key": "value"}', "secrets", item_name="production"
)
assert isinstance(result, str)
def test_databag_encrypted() -> None:
"""Convert encrypted databag."""
result = convert_chef_databag_to_vars(
'{"encrypted": "data"}', "secrets", is_encrypted=True
)
assert isinstance(result, str)
def test_databag_unicode_content() -> None:
"""Convert databag with Unicode."""
content = '{"message": "café ☕", "chars": "日本語"}'
result = convert_chef_databag_to_vars(content, "international")
assert isinstance(result, str)
def test_databag_special_chars() -> None:
"""Convert databag with special characters."""
content = '{"path": "/var/www/app", "pattern": "[0-9]+", "symbol": "@#$%"}'
result = convert_chef_databag_to_vars(content, "special")
assert isinstance(result, str)
def test_databag_large_content() -> None:
"""Convert large databag."""
large_dict = {f"key_{i}": f"value_{i}" for i in range(100)}
import json
result = convert_chef_databag_to_vars(json.dumps(large_dict), "large")
assert isinstance(result, str)
# ==============================================================================
# ENVIRONMENT ANALYSIS
# ==============================================================================
def test_analyse_environment_usage(tmp_path: Path) -> None:
"""Analyse environment usage."""
cookbook = tmp_path / "app"
cookbook.mkdir()
(cookbook / "metadata.rb").write_text("name 'app'\nversion '1.0'")
(cookbook / "recipes").mkdir()
(cookbook / "recipes" / "default.rb").write_text("package 'nginx'")
result = analyse_chef_environment_usage(str(cookbook))
assert isinstance(result, str)
def test_analyse_environment_with_env_path(tmp_path: Path) -> None:
"""Analyse environment with environment path."""
cookbook = tmp_path / "app"
cookbook.mkdir()
(cookbook / "metadata.rb").write_text("name 'app'")
(cookbook / "recipes").mkdir()
(cookbook / "recipes" / "default.rb").write_text("# recipe")
envdir = tmp_path / "environments"
envdir.mkdir()
(envdir / "production.rb").write_text("name 'production'")
result = analyse_chef_environment_usage(
str(cookbook), environments_path=str(envdir)
)
assert isinstance(result, str)
def test_analyse_environment_empty_cookbook(tmp_path: Path) -> None:
"""Analyse usage on empty cookbook."""
cookbook = tmp_path / "empty"
cookbook.mkdir()
result = analyse_chef_environment_usage(str(cookbook))
assert isinstance(result, str)
# ==============================================================================
# DATABAG ANALYSIS
# ==============================================================================
def test_analyse_databag_usage(tmp_path: Path) -> None:
"""Analyse databag usage."""
cookbook = tmp_path / "app"
cookbook.mkdir()
(cookbook / "metadata.rb").write_text("name 'app'")
(cookbook / "recipes").mkdir()
(cookbook / "recipes" / "default.rb").write_text("package 'nginx'")
result = analyse_chef_databag_usage(str(cookbook))
assert isinstance(result, str)
def test_analyse_databag_with_path(tmp_path: Path) -> None:
"""Analyse databag with data bags path."""
cookbook = tmp_path / "app"
cookbook.mkdir()
(cookbook / "metadata.rb").write_text("name 'app'")
(cookbook / "recipes").mkdir()
(cookbook / "recipes" / "default.rb").write_text("# recipe")
databags = tmp_path / "data_bags"
databags.mkdir()
app_bag = databags / "app"
app_bag.mkdir()
(app_bag / "config.json").write_text('{"key": "value"}')
result = analyse_chef_databag_usage(str(cookbook), databags_path=str(databags))
assert isinstance(result, str)
def test_analyse_databag_multiple_bags(tmp_path: Path) -> None:
"""Analyse with multiple databags."""
cookbook = tmp_path / "app"
cookbook.mkdir()
(cookbook / "metadata.rb").write_text("name 'app'")
(cookbook / "recipes").mkdir()
(cookbook / "recipes" / "default.rb").write_text("# recipe")
databags = tmp_path / "data_bags"
databags.mkdir()
for bag_name in ["app", "secrets", "config"]:
bag = databags / bag_name
bag.mkdir()
(bag / "default.json").write_text("{}")
result = analyse_chef_databag_usage(str(cookbook), databags_path=str(databags))
assert isinstance(result, str)
def test_analyse_databag_encrypted(tmp_path: Path) -> None:
"""Analyse with encrypted databags."""
cookbook = tmp_path / "app"
cookbook.mkdir()
(cookbook / "metadata.rb").write_text("name 'app'")
(cookbook / "recipes").mkdir()
(cookbook / "recipes" / "default.rb").write_text("# recipe")
databags = tmp_path / "data_bags"
databags.mkdir()
secrets = databags / "secrets"
secrets.mkdir()
# Encrypted databag format
(secrets / "api_key.json").write_text(
'{"encrypted": true, "cipher": "aes-256-cbc"}'
)
result = analyse_chef_databag_usage(str(cookbook), databags_path=str(databags))
assert isinstance(result, str)
# ==============================================================================
# INVENTORY GENERATION FROM ENVIRONMENTS
# ==============================================================================
def test_generate_inventory_single_env(tmp_path: Path) -> None:
"""Generate inventory from single environment."""
envdir = tmp_path / "environments"
envdir.mkdir()
(envdir / "production.rb").write_text(
"name 'production'\ndefault_attributes 'env' => 'prod'"
)
result = generate_inventory_from_chef_environments(str(envdir))
assert isinstance(result, str)
def test_generate_inventory_multiple_envs(tmp_path: Path) -> None:
"""Generate inventory from multiple environments."""
envdir = tmp_path / "environments"
envdir.mkdir()
for env_name in ["production", "staging", "development"]:
env_file = envdir / f"{env_name}.rb"
env_file.write_text(
f"name '{env_name}'\ndefault_attributes 'env' => '{env_name}'"
)
result = generate_inventory_from_chef_environments(str(envdir))
assert isinstance(result, str)
def test_generate_inventory_with_attributes(tmp_path: Path) -> None:
"""Generate inventory with complex attributes."""
envdir = tmp_path / "environments"
envdir.mkdir()
(envdir / "prod.rb").write_text(
"name 'production'\n"
"default_attributes "
"'app' => {'version' => '2.0', 'port' => 8080}, "
"'db' => {'host' => 'db.prod', 'port' => 5432}"
)
result = generate_inventory_from_chef_environments(str(envdir))
assert isinstance(result, str)
def test_generate_inventory_yaml_format(tmp_path: Path) -> None:
"""Generate inventory in YAML format."""
envdir = tmp_path / "environments"
envdir.mkdir()
(envdir / "dev.rb").write_text("name 'development'")
result = generate_inventory_from_chef_environments(
str(envdir), output_format="yaml"
)
assert isinstance(result, str)
def test_generate_inventory_ini_format(tmp_path: Path) -> None:
"""Generate inventory in INI format."""
envdir = tmp_path / "environments"
envdir.mkdir()
(envdir / "test.rb").write_text("name 'test'")
result = generate_inventory_from_chef_environments(str(envdir), output_format="ini")
assert isinstance(result, str)
def test_generate_inventory_both_formats(tmp_path: Path) -> None:
"""Generate inventory in both formats."""
envdir = tmp_path / "environments"
envdir.mkdir()
(envdir / "both.rb").write_text("name 'both'")
result = generate_inventory_from_chef_environments(
str(envdir), output_format="both"
)
assert isinstance(result, str)
def test_generate_inventory_empty_dir(tmp_path: Path) -> None:
"""Generate inventory from empty environment directory."""
envdir = tmp_path / "empty_envs"
envdir.mkdir()
result = generate_inventory_from_chef_environments(str(envdir))
assert isinstance(result, str)
def test_generate_inventory_nonexistent_dir() -> None:
"""Generate inventory from non-existent directory."""
result = generate_inventory_from_chef_environments("/nonexistent/envs")
assert isinstance(result, str)
# ==============================================================================
# ERROR HANDLING AND EDGE CASES
# ==============================================================================
def test_assess_invalid_path() -> None:
"""Assess complexity on invalid path."""
result = assess_chef_migration_complexity("/nonexistent/path")
assert isinstance(result, str)
def test_databag_invalid_json() -> None:
"""Convert invalid JSON databag."""
result = convert_chef_databag_to_vars("not valid json {", "invalid")
assert isinstance(result, str)
def test_databag_empty_content() -> None:
"""Convert empty databag."""
result = convert_chef_databag_to_vars("", "empty")
assert isinstance(result, str)
def test_databag_null_values() -> None:
"""Convert databag with null values."""
result = convert_chef_databag_to_vars('{"key": null, "other": "value"}', "nulls")
assert isinstance(result, str)
def test_databag_complex_nesting() -> None:
"""Convert databag with complex nesting."""
content = '{"a": {"b": {"c": {"d": {"e": {"f": {"g": "value"}}}}}}}'
result = convert_chef_databag_to_vars(content, "deep")
assert isinstance(result, str)
def test_analyse_invalid_cookbook() -> None:
"""Analyse databag usage on invalid cookbook."""
result = analyse_chef_databag_usage("/nonexistent/cookbook")
assert isinstance(result, str)
def test_analyse_env_invalid_cookbook() -> None:
"""Analyse environment usage on invalid cookbook."""
result = analyse_chef_environment_usage("/nonexistent/cookbook")
assert isinstance(result, str)
# ==============================================================================
# COMBINATION WORKFLOWS
# ==============================================================================
def test_assess_and_generate_inventory(tmp_path: Path) -> None:
"""Assess complexity then generate inventory."""
# Create minimal environment
envdir = tmp_path / "environments"
envdir.mkdir()
(envdir / "dev.rb").write_text("name 'development'")
assess_result = assess_chef_migration_complexity(".")
inventory_result = generate_inventory_from_chef_environments(str(envdir))
assert isinstance(assess_result, str)
assert isinstance(inventory_result, str)
def test_databag_conversion_and_analysis(tmp_path: Path) -> None:
"""Convert databag and analyse usage."""
cookbook = tmp_path / "app"
cookbook.mkdir()
(cookbook / "metadata.rb").write_text("name 'app'")
(cookbook / "recipes").mkdir()
(cookbook / "recipes" / "default.rb").write_text("# recipe")
# Convert databag
converted = convert_chef_databag_to_vars('{"key": "value"}', "test")
# Analyse usage
analysed = analyse_chef_databag_usage(str(cookbook))
assert isinstance(converted, str)
assert isinstance(analysed, str)
def test_full_migration_assessment(tmp_path: Path) -> None:
"""Full migration assessment workflow."""
cookbook = tmp_path / "app"
cookbook.mkdir()
(cookbook / "metadata.rb").write_text("name 'app'\nversion '1.0'")
(cookbook / "recipes").mkdir()
(cookbook / "recipes" / "default.rb").write_text("package 'nginx'")
envdir = tmp_path / "environments"
envdir.mkdir()
(envdir / "prod.rb").write_text("name 'production'")
# Run all assessments
complexity = assess_chef_migration_complexity(str(cookbook))
env_analysis = analyse_chef_environment_usage(str(cookbook), str(envdir))
inventory = generate_inventory_from_chef_environments(str(envdir))
assert all(isinstance(r, str) for r in [complexity, env_analysis, inventory])