forked from cleveragents/cleveragents-core
Feat: Added an --all flag to the context delete command
This commit is contained in:
+71
-9
@@ -981,23 +981,85 @@ def clear_context(name: str, context_dir: Optional[Path]) -> None:
|
||||
|
||||
|
||||
@context.command("delete")
|
||||
@click.argument("name")
|
||||
@click.argument("name", required=False)
|
||||
@click.option(
|
||||
"--context-dir",
|
||||
type=click.Path(file_okay=False, dir_okay=True, path_type=Path),
|
||||
help="Directory where contexts are stored.",
|
||||
)
|
||||
@click.confirmation_option(prompt="Are you sure you want to delete this context?")
|
||||
def delete_context(name: str, context_dir: Optional[Path]) -> None:
|
||||
"""Delete a context and all its data."""
|
||||
@click.option(
|
||||
"--all",
|
||||
is_flag=True,
|
||||
help="Delete all contexts.",
|
||||
)
|
||||
@click.option(
|
||||
"--yes",
|
||||
"-y",
|
||||
is_flag=True,
|
||||
help="Skip confirmation prompt.",
|
||||
)
|
||||
def delete_context(name: Optional[str], context_dir: Optional[Path], all: bool, yes: bool) -> None:
|
||||
"""Delete a context and all its data, or delete all contexts with --all."""
|
||||
try:
|
||||
ctx_manager = ContextManager(name, context_dir)
|
||||
if not ctx_manager.exists():
|
||||
click.echo(f"Context '{name}' does not exist.", err=True)
|
||||
# Validate arguments
|
||||
if all and name:
|
||||
click.echo("Error: Cannot specify NAME when using --all flag.", err=True)
|
||||
sys.exit(1)
|
||||
|
||||
ctx_manager.delete()
|
||||
click.echo(f"Context '{name}' has been deleted.")
|
||||
if not all and not name:
|
||||
click.echo("Error: Must specify NAME or use --all flag.", err=True)
|
||||
sys.exit(1)
|
||||
|
||||
if all:
|
||||
# Delete all contexts
|
||||
contexts = ContextManager.list_contexts(context_dir)
|
||||
|
||||
if not contexts:
|
||||
click.echo("No contexts found.")
|
||||
return
|
||||
|
||||
# Show what will be deleted
|
||||
click.echo(f"Found {len(contexts)} context(s) to delete:")
|
||||
for ctx in contexts:
|
||||
click.echo(f" - {ctx}")
|
||||
|
||||
# Confirmation prompt (unless --yes is provided)
|
||||
if not yes:
|
||||
if not click.confirm("Are you sure you want to delete ALL contexts?"):
|
||||
click.echo("Operation cancelled.")
|
||||
return
|
||||
|
||||
# Delete all contexts
|
||||
deleted_count = 0
|
||||
failed_count = 0
|
||||
for ctx_name in contexts:
|
||||
try:
|
||||
ctx_manager = ContextManager(ctx_name, context_dir)
|
||||
ctx_manager.delete()
|
||||
deleted_count += 1
|
||||
except Exception as e: # pylint: disable=broad-exception-caught
|
||||
click.echo(f"Failed to delete context '{ctx_name}': {e}", err=True)
|
||||
failed_count += 1
|
||||
|
||||
click.echo(f"Deleted {deleted_count} context(s).")
|
||||
if failed_count > 0:
|
||||
click.echo(f"Failed to delete {failed_count} context(s).", err=True)
|
||||
else:
|
||||
# Delete single context
|
||||
assert name is not None # mypy type narrowing: guaranteed by validation above
|
||||
ctx_manager = ContextManager(name, context_dir)
|
||||
if not ctx_manager.exists():
|
||||
click.echo(f"Context '{name}' does not exist.", err=True)
|
||||
sys.exit(1)
|
||||
|
||||
# Confirmation prompt (unless --yes is provided)
|
||||
if not yes:
|
||||
if not click.confirm(f"Are you sure you want to delete context '{name}'?"):
|
||||
click.echo("Operation cancelled.")
|
||||
return
|
||||
|
||||
ctx_manager.delete()
|
||||
click.echo(f"Context '{name}' has been deleted.")
|
||||
except Exception as e: # pylint: disable=broad-exception-caught
|
||||
click.echo(f"Error: {e}", err=True)
|
||||
sys.exit(1)
|
||||
|
||||
@@ -227,8 +227,20 @@ class ContextManager:
|
||||
|
||||
contexts = []
|
||||
for path in base_dir.iterdir():
|
||||
if path.is_dir() and (path / "messages.json").exists():
|
||||
contexts.append(path.name)
|
||||
try:
|
||||
if path.is_dir():
|
||||
# Try to check if messages.json exists, but if we can't access it
|
||||
# (due to permissions), assume it's a context directory anyway
|
||||
try:
|
||||
if (path / "messages.json").exists():
|
||||
contexts.append(path.name)
|
||||
except (PermissionError, OSError):
|
||||
# Can't access the directory contents, but it might be a context
|
||||
# Include it anyway and let deletion handle the error
|
||||
contexts.append(path.name)
|
||||
except (PermissionError, OSError):
|
||||
# Can't even check if it's a directory, skip it
|
||||
continue
|
||||
|
||||
return sorted(contexts)
|
||||
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
Feature: Context Delete with --all and --yes Flags
|
||||
As a user of CleverAgents
|
||||
I want to delete contexts individually or in bulk with confirmation control
|
||||
So that I can efficiently manage my stored conversation contexts
|
||||
|
||||
Background:
|
||||
Given I have a temporary test directory for contexts
|
||||
|
||||
Scenario: Delete single context with --yes bypasses confirmation
|
||||
Given I have a context "test-context-1" in the test directory
|
||||
When I run CLI command "context delete test-context-1 --yes" with test context dir
|
||||
Then the command should succeed
|
||||
And the context "test-context-1" should not exist
|
||||
|
||||
Scenario: Delete single context without --yes prompts for confirmation
|
||||
Given I have a context "test-context-2" in the test directory
|
||||
When I run CLI command "context delete test-context-2" with test context dir and answer "y"
|
||||
Then the command should succeed
|
||||
And the context "test-context-2" should not exist
|
||||
|
||||
Scenario: Delete single context - cancel confirmation
|
||||
Given I have a context "test-context-3" in the test directory
|
||||
When I run CLI command "context delete test-context-3" with test context dir and answer "n"
|
||||
Then the command should be cancelled
|
||||
And the context "test-context-3" should still exist
|
||||
|
||||
Scenario: Delete all contexts with --all --yes bypasses confirmation
|
||||
Given I have contexts "ctx-a", "ctx-b", "ctx-c" in the test directory
|
||||
When I run CLI command "context delete --all --yes" with test context dir
|
||||
Then the command should succeed
|
||||
And all contexts should be deleted
|
||||
And the output should show "Deleted 3 context(s)"
|
||||
|
||||
Scenario: Delete all contexts with --all prompts for confirmation
|
||||
Given I have contexts "ctx-d", "ctx-e" in the test directory
|
||||
When I run CLI command "context delete --all" with test context dir and answer "y"
|
||||
Then the command should succeed
|
||||
And all contexts should be deleted
|
||||
And the output should list all contexts before deletion
|
||||
|
||||
Scenario: Delete all contexts - cancel confirmation
|
||||
Given I have contexts "ctx-f", "ctx-g" in the test directory
|
||||
When I run CLI command "context delete --all" with test context dir and answer "n"
|
||||
Then the command should be cancelled
|
||||
And the contexts "ctx-f", "ctx-g" should still exist
|
||||
|
||||
Scenario: Error when both NAME and --all provided
|
||||
When I run CLI command "context delete test-context --all" with test context dir
|
||||
Then the command should fail with error "Cannot specify NAME when using --all flag"
|
||||
|
||||
Scenario: Error when neither NAME nor --all provided
|
||||
When I run CLI command "context delete" with test context dir
|
||||
Then the command should fail with error "Must specify NAME or use --all flag"
|
||||
|
||||
Scenario: Delete all when no contexts exist
|
||||
Given the test context directory is empty
|
||||
When I run CLI command "context delete --all --yes" with test context dir
|
||||
Then the command should succeed
|
||||
And the output should show "No contexts found"
|
||||
|
||||
Scenario: Delete single non-existent context
|
||||
When I run CLI command "context delete non-existent --yes" with test context dir
|
||||
Then the command should fail
|
||||
And the output should show "does not exist"
|
||||
|
||||
Scenario: Delete all contexts with partial failures
|
||||
Given I have contexts "ctx-h", "ctx-i" in the test directory
|
||||
And context "ctx-i" directory is made read-only
|
||||
When I run CLI command "context delete --all --yes" with test context dir
|
||||
Then the command should succeed
|
||||
And the output should show deleted count
|
||||
And the output should show failed count
|
||||
|
||||
Scenario: Delete all shows context list before confirmation
|
||||
Given I have contexts "alpha", "beta", "gamma" in the test directory
|
||||
When I run CLI command "context delete --all" with test context dir and capture output
|
||||
Then the output should contain "Found 3 context(s) to delete"
|
||||
And the output should contain "alpha"
|
||||
And the output should contain "beta"
|
||||
And the output should contain "gamma"
|
||||
|
||||
Scenario: Using -y as shorthand for --yes
|
||||
Given I have a context "test-short-yes" in the test directory
|
||||
When I run CLI command "context delete test-short-yes -y" with test context dir
|
||||
Then the command should succeed
|
||||
And the context "test-short-yes" should not exist
|
||||
@@ -0,0 +1,247 @@
|
||||
"""Step definitions for Context Delete with --all and --yes flags."""
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
from behave import given, then, when
|
||||
from behave.runner import Context
|
||||
|
||||
|
||||
@given('I have a context "{name}" in the test directory')
|
||||
def step_have_context_in_test_dir(context: Context, name: str) -> None:
|
||||
"""Create a single context in the test directory."""
|
||||
if not hasattr(context, "context_dir"):
|
||||
context.temp_dir = tempfile.mkdtemp(prefix="cleveragents_test_")
|
||||
context.context_dir = Path(context.temp_dir) / "contexts"
|
||||
context.context_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create a simple context structure
|
||||
ctx_dir = context.context_dir / name
|
||||
ctx_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create the standard context files
|
||||
(ctx_dir / "messages.json").write_text("[]")
|
||||
(ctx_dir / "metadata.json").write_text("{}")
|
||||
(ctx_dir / "state.json").write_text("{}")
|
||||
(ctx_dir / "global_context.json").write_text("{}")
|
||||
|
||||
|
||||
@given('I have contexts "{names}" in the test directory')
|
||||
def step_have_multiple_contexts_in_test_dir(context: Context, names: str) -> None:
|
||||
"""Create multiple contexts in the test directory."""
|
||||
if not hasattr(context, "context_dir"):
|
||||
context.temp_dir = tempfile.mkdtemp(prefix="cleveragents_test_")
|
||||
context.context_dir = Path(context.temp_dir) / "contexts"
|
||||
context.context_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Parse the comma-separated names
|
||||
context_names = [name.strip().strip('"') for name in names.split(",")]
|
||||
|
||||
# Create each context
|
||||
for name in context_names:
|
||||
ctx_dir = context.context_dir / name
|
||||
ctx_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create the standard context files
|
||||
(ctx_dir / "messages.json").write_text("[]")
|
||||
(ctx_dir / "metadata.json").write_text("{}")
|
||||
(ctx_dir / "state.json").write_text("{}")
|
||||
(ctx_dir / "global_context.json").write_text("{}")
|
||||
|
||||
|
||||
@given("the test context directory is empty")
|
||||
def step_empty_test_context_dir(context: Context) -> None:
|
||||
"""Ensure the test context directory is empty."""
|
||||
if not hasattr(context, "context_dir"):
|
||||
context.temp_dir = tempfile.mkdtemp(prefix="cleveragents_test_")
|
||||
context.context_dir = Path(context.temp_dir) / "contexts"
|
||||
context.context_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Directory already empty since we just created it
|
||||
|
||||
|
||||
@given('context "{name}" directory is made read-only')
|
||||
def step_make_context_readonly(context: Context, name: str) -> None:
|
||||
"""Make a context directory read-only to simulate failure."""
|
||||
ctx_dir = context.context_dir / name
|
||||
if ctx_dir.exists():
|
||||
# Make directory read-only
|
||||
os.chmod(ctx_dir, 0o444)
|
||||
# Track this for cleanup
|
||||
if not hasattr(context, "readonly_dirs"):
|
||||
context.readonly_dirs = []
|
||||
context.readonly_dirs.append(ctx_dir)
|
||||
|
||||
|
||||
@when('I run CLI command "{command}" with test context dir')
|
||||
def step_run_cli_with_test_context_dir(context: Context, command: str) -> None:
|
||||
"""Run a CLI command with the test context directory."""
|
||||
# Parse command and add --context-dir
|
||||
cmd_parts = ["python", "-m", "cleveragents"] + command.split()
|
||||
cmd_parts.extend(["--context-dir", str(context.context_dir)])
|
||||
|
||||
# Run the command
|
||||
result = subprocess.run(cmd_parts, capture_output=True, text=True, cwd="/app")
|
||||
|
||||
context.cli_result = result
|
||||
context.cli_stdout = result.stdout
|
||||
context.cli_stderr = result.stderr
|
||||
context.cli_returncode = result.returncode
|
||||
|
||||
|
||||
@when('I run CLI command "{command}" with test context dir and answer "{answer}"')
|
||||
def step_run_cli_with_answer(context: Context, command: str, answer: str) -> None:
|
||||
"""Run a CLI command with the test context directory and provide input."""
|
||||
# Parse command and add --context-dir
|
||||
cmd_parts = ["python", "-m", "cleveragents"] + command.split()
|
||||
cmd_parts.extend(["--context-dir", str(context.context_dir)])
|
||||
|
||||
# Run the command with input
|
||||
result = subprocess.run(cmd_parts, input=answer + "\n", capture_output=True, text=True, cwd="/app")
|
||||
|
||||
context.cli_result = result
|
||||
context.cli_stdout = result.stdout
|
||||
context.cli_stderr = result.stderr
|
||||
context.cli_returncode = result.returncode
|
||||
|
||||
|
||||
@when('I run CLI command "{command}" with test context dir and capture output')
|
||||
def step_run_cli_and_capture_output(context: Context, command: str) -> None:
|
||||
"""Run a CLI command with the test context directory and capture all output."""
|
||||
# Parse command and add --context-dir
|
||||
cmd_parts = ["python", "-m", "cleveragents"] + command.split()
|
||||
cmd_parts.extend(["--context-dir", str(context.context_dir)])
|
||||
|
||||
# Run the command (it will wait for input but we won't provide it to capture the output)
|
||||
# We'll use a short timeout to avoid hanging
|
||||
try:
|
||||
result = subprocess.run(cmd_parts, input="n\n", capture_output=True, text=True, timeout=5, cwd="/app")
|
||||
context.cli_result = result
|
||||
context.cli_stdout = result.stdout
|
||||
context.cli_stderr = result.stderr
|
||||
context.cli_returncode = result.returncode
|
||||
except subprocess.TimeoutExpired as e:
|
||||
context.cli_stdout = e.stdout.decode() if e.stdout else ""
|
||||
context.cli_stderr = e.stderr.decode() if e.stderr else ""
|
||||
context.cli_returncode = -1
|
||||
|
||||
|
||||
# Note: "the command should succeed" and "the command should fail" are already defined in cli_steps.py
|
||||
|
||||
|
||||
@then("the command should be cancelled")
|
||||
def step_command_should_be_cancelled(context: Context) -> None:
|
||||
"""Verify the command was cancelled."""
|
||||
assert "cancelled" in context.cli_stdout.lower() or "cancelled" in context.cli_stderr.lower(), (
|
||||
f"Command was not cancelled\n" f"stdout: {context.cli_stdout}\n" f"stderr: {context.cli_stderr}"
|
||||
)
|
||||
|
||||
|
||||
@then('the command should fail with error "{error_text}"')
|
||||
def step_command_should_fail_with_error(context: Context, error_text: str) -> None:
|
||||
"""Verify the command failed with specific error message."""
|
||||
assert context.cli_returncode != 0, (
|
||||
f"Command succeeded unexpectedly\n" f"stdout: {context.cli_stdout}\n" f"stderr: {context.cli_stderr}"
|
||||
)
|
||||
|
||||
combined_output = context.cli_stdout + context.cli_stderr
|
||||
assert error_text in combined_output, (
|
||||
f"Expected error message not found: {error_text}\n"
|
||||
f"stdout: {context.cli_stdout}\n"
|
||||
f"stderr: {context.cli_stderr}"
|
||||
)
|
||||
|
||||
|
||||
@then('the context "{name}" should not exist')
|
||||
def step_context_should_not_exist(context: Context, name: str) -> None:
|
||||
"""Verify a context does not exist."""
|
||||
ctx_dir = context.context_dir / name
|
||||
assert not ctx_dir.exists(), f"Context '{name}' still exists at {ctx_dir}"
|
||||
|
||||
|
||||
@then('the context "{name}" should still exist')
|
||||
def step_context_should_still_exist(context: Context, name: str) -> None:
|
||||
"""Verify a context still exists."""
|
||||
ctx_dir = context.context_dir / name
|
||||
assert ctx_dir.exists(), f"Context '{name}' does not exist at {ctx_dir}"
|
||||
|
||||
|
||||
@then("all contexts should be deleted")
|
||||
def step_all_contexts_deleted(context: Context) -> None:
|
||||
"""Verify all contexts were deleted."""
|
||||
# List all subdirectories in the context directory
|
||||
if context.context_dir.exists():
|
||||
contexts = [d for d in context.context_dir.iterdir() if d.is_dir()]
|
||||
assert len(contexts) == 0, f"Found {len(contexts)} contexts still present: {[c.name for c in contexts]}"
|
||||
|
||||
|
||||
@then('the contexts "{names}" should still exist')
|
||||
def step_contexts_should_still_exist(context: Context, names: str) -> None:
|
||||
"""Verify specific contexts still exist."""
|
||||
context_names = [name.strip().strip('"') for name in names.split(",")]
|
||||
|
||||
for name in context_names:
|
||||
ctx_dir = context.context_dir / name
|
||||
assert ctx_dir.exists(), f"Context '{name}' does not exist at {ctx_dir}"
|
||||
|
||||
|
||||
@then('the output should show "{text}"')
|
||||
def step_output_should_show(context: Context, text: str) -> None:
|
||||
"""Verify the output contains specific text."""
|
||||
combined_output = context.cli_stdout + context.cli_stderr
|
||||
assert text in combined_output, (
|
||||
f"Expected text not found in output: {text}\n" f"stdout: {context.cli_stdout}\n" f"stderr: {context.cli_stderr}"
|
||||
)
|
||||
|
||||
|
||||
@then("the output should show deleted count")
|
||||
def step_output_shows_deleted_count(context: Context) -> None:
|
||||
"""Verify the output shows deleted count."""
|
||||
combined_output = context.cli_stdout + context.cli_stderr
|
||||
assert "Deleted" in combined_output and "context" in combined_output, (
|
||||
f"Deleted count not found in output\n" f"stdout: {context.cli_stdout}\n" f"stderr: {context.cli_stderr}"
|
||||
)
|
||||
|
||||
|
||||
@then("the output should show failed count")
|
||||
def step_output_shows_failed_count(context: Context) -> None:
|
||||
"""Verify the output shows failed count."""
|
||||
combined_output = context.cli_stdout + context.cli_stderr
|
||||
assert "Failed" in combined_output, (
|
||||
f"Failed count not found in output\n" f"stdout: {context.cli_stdout}\n" f"stderr: {context.cli_stderr}"
|
||||
)
|
||||
|
||||
|
||||
# Note: "the output should contain" is already defined in cli_steps.py as "the output should contain '{expected_text}'"
|
||||
|
||||
|
||||
@then("the output should list all contexts before deletion")
|
||||
def step_output_lists_contexts_before_deletion(context: Context) -> None:
|
||||
"""Verify the output lists contexts before deletion."""
|
||||
combined_output = context.cli_stdout + context.cli_stderr
|
||||
assert "Found" in combined_output and "to delete" in combined_output, (
|
||||
f"Context list not found in output\n" f"stdout: {context.cli_stdout}\n" f"stderr: {context.cli_stderr}"
|
||||
)
|
||||
|
||||
|
||||
def after_scenario(context, scenario):
|
||||
"""Clean up after each scenario."""
|
||||
# Restore permissions on read-only directories
|
||||
if hasattr(context, "readonly_dirs"):
|
||||
for dir_path in context.readonly_dirs:
|
||||
try:
|
||||
os.chmod(dir_path, 0o755)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Clean up temp directory
|
||||
if hasattr(context, "temp_dir"):
|
||||
import shutil
|
||||
|
||||
try:
|
||||
shutil.rmtree(context.temp_dir)
|
||||
except Exception:
|
||||
pass
|
||||
@@ -0,0 +1,318 @@
|
||||
*** Settings ***
|
||||
Documentation Integration tests for context delete with --all and --yes flags
|
||||
Library Process
|
||||
Library OperatingSystem
|
||||
Library String
|
||||
Library DateTime
|
||||
Suite Setup Setup Test Environment
|
||||
Suite Teardown Cleanup Test Environment
|
||||
|
||||
*** Variables ***
|
||||
${SIMPLE_CONFIG} tests/fixtures/simple_echo_config.yaml
|
||||
${CONTEXT_DIR} ${TEMPDIR}/test_contexts_delete_all_yes
|
||||
${UNIQUE_ID} ${EMPTY}
|
||||
${TEMP} ${EMPTY}
|
||||
|
||||
*** Test Cases ***
|
||||
Test Delete Single Context With Yes Flag
|
||||
[Documentation] Test context delete with --yes bypasses confirmation
|
||||
${context_name} = Set Variable delete_yes_${UNIQUE_ID}
|
||||
|
||||
# Create context
|
||||
Run Process python -m cleveragents run
|
||||
... -c ${SIMPLE_CONFIG}
|
||||
... --context ${context_name}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... --unsafe
|
||||
... -p "test message"
|
||||
|
||||
Directory Should Exist ${CONTEXT_DIR}/${context_name}
|
||||
|
||||
# Delete it with --yes flag
|
||||
${result} = Run Process python -m cleveragents context delete
|
||||
... ${context_name}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... --yes
|
||||
|
||||
Should Be Equal As Integers ${result.rc} 0
|
||||
Directory Should Not Exist ${CONTEXT_DIR}/${context_name}
|
||||
Should Contain ${result.stdout} deleted
|
||||
|
||||
Test Delete Single Context With Short Yes Flag
|
||||
[Documentation] Test context delete with -y shorthand flag
|
||||
${context_name} = Set Variable delete_short_${UNIQUE_ID}
|
||||
|
||||
# Create context
|
||||
Run Process python -m cleveragents run
|
||||
... -c ${SIMPLE_CONFIG}
|
||||
... --context ${context_name}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... --unsafe
|
||||
... -p "test message"
|
||||
|
||||
Directory Should Exist ${CONTEXT_DIR}/${context_name}
|
||||
|
||||
# Delete it with -y flag
|
||||
${result} = Run Process python -m cleveragents context delete
|
||||
... ${context_name}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... -y
|
||||
|
||||
Should Be Equal As Integers ${result.rc} 0
|
||||
Directory Should Not Exist ${CONTEXT_DIR}/${context_name}
|
||||
|
||||
Test Delete Single Context With Confirmation Accept
|
||||
[Documentation] Test context delete with confirmation accepted
|
||||
${context_name} = Set Variable delete_confirm_${UNIQUE_ID}
|
||||
|
||||
# Create context
|
||||
Run Process python -m cleveragents run
|
||||
... -c ${SIMPLE_CONFIG}
|
||||
... --context ${context_name}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... --unsafe
|
||||
... -p "test message"
|
||||
|
||||
Directory Should Exist ${CONTEXT_DIR}/${context_name}
|
||||
|
||||
# Delete with confirmation (answer 'y')
|
||||
${result} = Run Process python -m cleveragents context delete
|
||||
... ${context_name}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... stdin=y\n
|
||||
|
||||
Should Be Equal As Integers ${result.rc} 0
|
||||
Directory Should Not Exist ${CONTEXT_DIR}/${context_name}
|
||||
|
||||
Test Delete Single Context With Confirmation Reject
|
||||
[Documentation] Test context delete with confirmation rejected
|
||||
${context_name} = Set Variable delete_reject_${UNIQUE_ID}
|
||||
|
||||
# Create context
|
||||
Run Process python -m cleveragents run
|
||||
... -c ${SIMPLE_CONFIG}
|
||||
... --context ${context_name}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... --unsafe
|
||||
... -p "test message"
|
||||
|
||||
Directory Should Exist ${CONTEXT_DIR}/${context_name}
|
||||
|
||||
# Delete with confirmation rejected (answer 'n')
|
||||
${result} = Run Process python -m cleveragents context delete
|
||||
... ${context_name}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... stdin=n\n
|
||||
|
||||
Should Be Equal As Integers ${result.rc} 0
|
||||
Directory Should Exist ${CONTEXT_DIR}/${context_name}
|
||||
Should Contain ${result.stdout} cancelled
|
||||
|
||||
Test Delete All Contexts With All And Yes Flags
|
||||
[Documentation] Test delete all contexts with --all --yes
|
||||
[Setup] Empty Directory ${CONTEXT_DIR}
|
||||
${ctx1} = Set Variable all_ctx1_${UNIQUE_ID}
|
||||
${ctx2} = Set Variable all_ctx2_${UNIQUE_ID}
|
||||
${ctx3} = Set Variable all_ctx3_${UNIQUE_ID}
|
||||
|
||||
# Create multiple contexts
|
||||
Run Process python -m cleveragents run
|
||||
... -c ${SIMPLE_CONFIG}
|
||||
... --context ${ctx1}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... --unsafe
|
||||
... -p "test"
|
||||
|
||||
Run Process python -m cleveragents run
|
||||
... -c ${SIMPLE_CONFIG}
|
||||
... --context ${ctx2}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... --unsafe
|
||||
... -p "test"
|
||||
|
||||
Run Process python -m cleveragents run
|
||||
... -c ${SIMPLE_CONFIG}
|
||||
... --context ${ctx3}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... --unsafe
|
||||
... -p "test"
|
||||
|
||||
Directory Should Exist ${CONTEXT_DIR}/${ctx1}
|
||||
Directory Should Exist ${CONTEXT_DIR}/${ctx2}
|
||||
Directory Should Exist ${CONTEXT_DIR}/${ctx3}
|
||||
|
||||
# Delete all with --all --yes
|
||||
${result} = Run Process python -m cleveragents context delete
|
||||
... --all
|
||||
... --yes
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
|
||||
Should Be Equal As Integers ${result.rc} 0
|
||||
Directory Should Not Exist ${CONTEXT_DIR}/${ctx1}
|
||||
Directory Should Not Exist ${CONTEXT_DIR}/${ctx2}
|
||||
Directory Should Not Exist ${CONTEXT_DIR}/${ctx3}
|
||||
Should Contain ${result.stdout} Deleted 3 context
|
||||
|
||||
Test Delete All With Confirmation Accept
|
||||
[Documentation] Test delete all with confirmation accepted
|
||||
[Setup] Empty Directory ${CONTEXT_DIR}
|
||||
${ctx1} = Set Variable all_confirm1_${UNIQUE_ID}
|
||||
${ctx2} = Set Variable all_confirm2_${UNIQUE_ID}
|
||||
|
||||
# Create contexts
|
||||
Run Process python -m cleveragents run
|
||||
... -c ${SIMPLE_CONFIG}
|
||||
... --context ${ctx1}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... --unsafe
|
||||
... -p "test"
|
||||
|
||||
Run Process python -m cleveragents run
|
||||
... -c ${SIMPLE_CONFIG}
|
||||
... --context ${ctx2}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... --unsafe
|
||||
... -p "test"
|
||||
|
||||
# Delete all with confirmation
|
||||
${result} = Run Process python -m cleveragents context delete
|
||||
... --all
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... stdin=y\n
|
||||
|
||||
Should Be Equal As Integers ${result.rc} 0
|
||||
Directory Should Not Exist ${CONTEXT_DIR}/${ctx1}
|
||||
Directory Should Not Exist ${CONTEXT_DIR}/${ctx2}
|
||||
Should Contain ${result.stdout} Found
|
||||
Should Contain ${result.stdout} to delete
|
||||
|
||||
Test Delete All With Confirmation Reject
|
||||
[Documentation] Test delete all with confirmation rejected
|
||||
[Setup] Empty Directory ${CONTEXT_DIR}
|
||||
${ctx1} = Set Variable all_reject1_${UNIQUE_ID}
|
||||
${ctx2} = Set Variable all_reject2_${UNIQUE_ID}
|
||||
|
||||
# Create contexts
|
||||
Run Process python -m cleveragents run
|
||||
... -c ${SIMPLE_CONFIG}
|
||||
... --context ${ctx1}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... --unsafe
|
||||
... -p "test"
|
||||
|
||||
Run Process python -m cleveragents run
|
||||
... -c ${SIMPLE_CONFIG}
|
||||
... --context ${ctx2}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... --unsafe
|
||||
... -p "test"
|
||||
|
||||
# Delete all with confirmation rejected
|
||||
${result} = Run Process python -m cleveragents context delete
|
||||
... --all
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... stdin=n\n
|
||||
|
||||
Should Be Equal As Integers ${result.rc} 0
|
||||
Directory Should Exist ${CONTEXT_DIR}/${ctx1}
|
||||
Directory Should Exist ${CONTEXT_DIR}/${ctx2}
|
||||
Should Contain ${result.stdout} cancelled
|
||||
|
||||
Test Error When Both Name And All Provided
|
||||
[Documentation] Test error when both NAME and --all are provided
|
||||
${result} = Run Process python -m cleveragents context delete
|
||||
... test_context
|
||||
... --all
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
|
||||
Should Not Be Equal As Integers ${result.rc} 0
|
||||
Should Contain Any ${result.stderr} ${result.stdout} Cannot specify NAME when using --all
|
||||
|
||||
Test Error When Neither Name Nor All Provided
|
||||
[Documentation] Test error when neither NAME nor --all is provided
|
||||
${result} = Run Process python -m cleveragents context delete
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
|
||||
Should Not Be Equal As Integers ${result.rc} 0
|
||||
Should Contain Any ${result.stderr} ${result.stdout} Must specify NAME or use --all
|
||||
|
||||
Test Delete All When No Contexts Exist
|
||||
[Documentation] Test delete all when directory is empty
|
||||
# Ensure directory is empty
|
||||
Empty Directory ${CONTEXT_DIR}
|
||||
|
||||
${result} = Run Process python -m cleveragents context delete
|
||||
... --all
|
||||
... --yes
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
|
||||
Should Be Equal As Integers ${result.rc} 0
|
||||
Should Contain ${result.stdout} No contexts found
|
||||
|
||||
Test Delete Non Existent Context
|
||||
[Documentation] Test deleting a context that doesn't exist
|
||||
${result} = Run Process python -m cleveragents context delete
|
||||
... non_existent_context_${UNIQUE_ID}
|
||||
... --yes
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
|
||||
Should Not Be Equal As Integers ${result.rc} 0
|
||||
Should Contain Any ${result.stderr} ${result.stdout} does not exist
|
||||
|
||||
Test Delete All Shows Context List Before Deletion
|
||||
[Documentation] Test that --all shows context list before confirmation
|
||||
[Setup] Empty Directory ${CONTEXT_DIR}
|
||||
${ctx1} = Set Variable list_ctx1_${UNIQUE_ID}
|
||||
${ctx2} = Set Variable list_ctx2_${UNIQUE_ID}
|
||||
${ctx3} = Set Variable list_ctx3_${UNIQUE_ID}
|
||||
|
||||
# Create contexts
|
||||
Run Process python -m cleveragents run
|
||||
... -c ${SIMPLE_CONFIG}
|
||||
... --context ${ctx1}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... --unsafe
|
||||
... -p "test"
|
||||
|
||||
Run Process python -m cleveragents run
|
||||
... -c ${SIMPLE_CONFIG}
|
||||
... --context ${ctx2}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... --unsafe
|
||||
... -p "test"
|
||||
|
||||
Run Process python -m cleveragents run
|
||||
... -c ${SIMPLE_CONFIG}
|
||||
... --context ${ctx3}
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... --unsafe
|
||||
... -p "test"
|
||||
|
||||
# Delete all with confirmation to see list
|
||||
${result} = Run Process python -m cleveragents context delete
|
||||
... --all
|
||||
... --context-dir ${CONTEXT_DIR}
|
||||
... stdin=n\n
|
||||
|
||||
Should Contain ${result.stdout} Found 3 context
|
||||
Should Contain ${result.stdout} ${ctx1}
|
||||
Should Contain ${result.stdout} ${ctx2}
|
||||
Should Contain ${result.stdout} ${ctx3}
|
||||
|
||||
*** Keywords ***
|
||||
Setup Test Environment
|
||||
${timestamp} = Get Current Date result_format=%Y%m%d_%H%M%S
|
||||
${random} = Evaluate random.randint(1000, 9999) modules=random
|
||||
Set Suite Variable ${UNIQUE_ID} ${timestamp}_${random}
|
||||
Set Suite Variable ${TEMP} ${TEMPDIR}/ca_delete_test_${UNIQUE_ID}
|
||||
Set Suite Variable ${CONTEXT_DIR} ${TEMP}/contexts
|
||||
Create Directory ${TEMP}
|
||||
Create Directory ${CONTEXT_DIR}
|
||||
|
||||
Cleanup Test Environment
|
||||
Run Keyword And Ignore Error Remove Directory ${TEMP} recursive=True
|
||||
|
||||
Should Contain Any
|
||||
[Arguments] ${text1} ${text2} ${expected}
|
||||
${combined} = Set Variable ${text1}${text2}
|
||||
Should Contain ${combined} ${expected}
|
||||
Reference in New Issue
Block a user