feat: implementar Fases 3, 4 y 5 del roadmap (Planificacion Avanzada, Historial de Corridas y Copia Local Duplicada)
This commit is contained in:
@@ -4,7 +4,7 @@ import platform
|
||||
import ctypes
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from datetime import datetime, timezone
|
||||
from datetime import datetime, timezone, timedelta
|
||||
|
||||
from app.core.database import init_db, AsyncSessionLocal
|
||||
from app.models.models import Client, BackupJob, BackupFile
|
||||
@@ -12,6 +12,7 @@ from app.api.jobs import purge_orphans
|
||||
from app.schemas.schemas import PurgeOrphansRequest
|
||||
from app.core.config import settings
|
||||
from agent.scanner import DirectoryScanner
|
||||
from agent.service import is_job_due
|
||||
|
||||
def set_windows_attributes(filepath: Path, hidden: bool = False, system: bool = False, readonly: bool = False):
|
||||
if platform.system() != "Windows":
|
||||
@@ -222,3 +223,82 @@ async def test_replica_mode_purge_orphans():
|
||||
assert db_files[0].is_active == True
|
||||
assert db_files[2].is_active == True
|
||||
assert (Path(settings.STORAGE_ROOT) / db_files[0].relative_path).exists()
|
||||
|
||||
def test_is_job_due_advanced():
|
||||
# 1. Traditional intervals
|
||||
# Last run was 50 mins ago (3000s)
|
||||
last_run_iso = (datetime.now(timezone.utc) - timedelta(minutes=50)).isoformat()
|
||||
assert is_job_due("hourly", last_run_iso) == False
|
||||
|
||||
# Last run was 70 mins ago (4200s)
|
||||
last_run_iso = (datetime.now(timezone.utc) - timedelta(minutes=70)).isoformat()
|
||||
assert is_job_due("hourly", last_run_iso) == True
|
||||
|
||||
# 2. Calendar schedule match
|
||||
# Let's test a simple day:
|
||||
# If the scheduled time occurred in the window, it is due.
|
||||
five_mins_ago = datetime.now(timezone.utc) - timedelta(minutes=5)
|
||||
day_name = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"][five_mins_ago.weekday()]
|
||||
time_str = five_mins_ago.strftime("%H:%M")
|
||||
|
||||
sched_str = f"{day_name} {time_str}"
|
||||
last_run = (five_mins_ago - timedelta(hours=1)).strftime("%Y-%m-%d %H:%M:%S")
|
||||
assert is_job_due(sched_str, last_run) == True
|
||||
|
||||
# 3. Cron schedule match
|
||||
# Cron format: minute hour day month weekday (0-6 starting Sunday)
|
||||
cron_weekday = (five_mins_ago.weekday() + 1) % 7
|
||||
cron_str = f"{five_mins_ago.minute} {five_mins_ago.hour} * * {cron_weekday}"
|
||||
assert is_job_due(cron_str, last_run) == True
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_job_runs_api_telemetry():
|
||||
"""
|
||||
Tests the creation, execution tracking, and completion endpoints of job runs.
|
||||
"""
|
||||
async with AsyncSessionLocal() as db:
|
||||
# 1. Setup client and job
|
||||
client = Client(
|
||||
client_code="CLIENT-R-01",
|
||||
name="Runs Test Machine",
|
||||
status="ONLINE",
|
||||
storage_used_bytes=0,
|
||||
storage_quota_bytes=100000
|
||||
)
|
||||
db.add(client)
|
||||
await db.flush()
|
||||
|
||||
job = BackupJob(
|
||||
job_code="JOB-R-01",
|
||||
client_id=client.id,
|
||||
name="Runs Test Job",
|
||||
source_path="C:\\RunsSource"
|
||||
)
|
||||
db.add(job)
|
||||
await db.commit()
|
||||
|
||||
# 2. Simulate runs endpoints inside backend
|
||||
from app.api.jobs import start_job_run, complete_job_run
|
||||
from app.schemas.schemas import JobRunStartRequest, JobRunCompleteRequest
|
||||
|
||||
start_req = JobRunStartRequest(client_id=client.id)
|
||||
run_res = await start_job_run(job_id=job.id, payload=start_req, db=db, current_client=client)
|
||||
assert run_res.status == "RUNNING"
|
||||
assert run_res.job_id == job.id
|
||||
|
||||
# Complete the run
|
||||
complete_req = JobRunCompleteRequest(
|
||||
status="SUCCESS",
|
||||
files_scanned=10,
|
||||
files_copied=3,
|
||||
files_skipped=7,
|
||||
errors_count=0,
|
||||
bytes_transferred=50000
|
||||
)
|
||||
completed_res = await complete_job_run(job_id=job.id, run_id=run_res.id, payload=complete_req, db=db, current_client=client)
|
||||
assert completed_res.status == "SUCCESS"
|
||||
assert completed_res.files_scanned == 10
|
||||
assert completed_res.files_copied == 3
|
||||
assert completed_res.files_skipped == 7
|
||||
assert completed_res.errors_count == 0
|
||||
assert completed_res.bytes_transferred == 50000
|
||||
|
||||
Reference in New Issue
Block a user