CtrlK
BlogDocsLog inGet started
Tessl Logo

golikovichev/secure-log2test

Turn a Kibana JSON log export into a runnable pytest suite using the secure-log2test CLI. Use when the user has a Kibana or Elasticsearch JSON export of API traffic and wants a regression suite from production logs, when extracting test cases from staging traffic, when scrubbing auth headers or secret-looking body fields before logs leave the laptop, when bridging Kibana-captured requests into a pytest-based suite for CI, when the user mentions Kibana logs, Elasticsearch JSON export, log-to-test conversion, log replay tests, auth header redaction, PII in logs, or regression tests from production traffic.

92

1.00x
Quality

100%

Does it follow best practices?

Impact

93%

1.00x

Average score across 2 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

test_cli_guards.pytests/

"""Tests for the CLI safeguards added in v1.2:

- --max-input-mb rejects oversized files before the parser runs.
- Skip count surfaces on the success path so users see how much got dropped.
- Exit code is non-zero when the skip ratio exceeds 50%, which usually
  means the input shape is wrong and the generated suite is useless.
"""

import json
from pathlib import Path

import pytest

from secure_log2test.cli import main as cli_main
from secure_log2test.core.parser import KibanaLogParser


def _write_kibana_export(path: Path, source_records):
    payload = {
        "hits": {
            "total": {"value": len(source_records), "relation": "eq"},
            "hits": [{"_source": rec} for rec in source_records],
        }
    }
    path.write_text(json.dumps(payload, ensure_ascii=False), encoding="utf-8")


def _good_record(method="GET", status=200):
    return {
        "method": method,
        "url": "/api/v1/items",
        "status": status,
        "duration": 5,
        "headers": {"Accept": "application/json"},
        "body": None,
    }


def _broken_record():
    # Missing required fields: method, url, status.
    return {"foo": "bar"}


def test_parser_tracks_attempted_and_skipped_counts(tmp_path):
    path = tmp_path / "mixed.json"
    _write_kibana_export(
        path,
        [_good_record(), _broken_record(), _good_record("POST", 201), _broken_record()],
    )
    parser = KibanaLogParser(path)
    entries = parser.parse()
    assert len(entries) == 2
    assert parser.attempted == 4
    assert parser.skipped == 2


def test_cli_rejects_input_above_max_input_mb(tmp_path, capsys):
    path = tmp_path / "big.json"
    # 2 MB body of arbitrary JSON-safe ASCII.
    path.write_text(
        '{"hits": {"hits": []}}\n' + ("x" * (2 * 1024 * 1024)), encoding="utf-8"
    )
    exit_code = cli_main(
        [str(path), "--max-input-mb", "1", "--output", str(tmp_path / "out.py")]
    )
    captured = capsys.readouterr()
    assert exit_code == 1
    assert "exceeds the --max-input-mb limit" in captured.err


def test_cli_zero_disables_size_check(tmp_path, capsys):
    path = tmp_path / "small_but_zero_check.json"
    _write_kibana_export(path, [_good_record()])
    out = tmp_path / "out.py"
    exit_code = cli_main([str(path), "--max-input-mb", "0", "--output", str(out)])
    assert exit_code == 0
    assert out.exists()


def test_cli_rejects_negative_max_input_mb(tmp_path):
    # 0 is the documented "disable" sentinel; a negative value is a typo
    # (e.g. -100 meant as 100) that must not silently disable the size guard.
    path = tmp_path / "ok.json"
    _write_kibana_export(path, [_good_record()])
    with pytest.raises(SystemExit) as exc:
        cli_main(
            [str(path), "--max-input-mb", "-5", "--output", str(tmp_path / "out.py")]
        )
    assert exc.value.code != 0


def test_cli_surfaces_skip_summary_in_stdout(tmp_path, capsys):
    path = tmp_path / "with_skip.json"
    _write_kibana_export(
        path,
        [
            _good_record(),
            _good_record("POST", 201),
            _good_record("PUT", 204),
            _broken_record(),
        ],
    )
    out = tmp_path / "out.py"
    exit_code = cli_main([str(path), "--output", str(out)])
    captured = capsys.readouterr()
    assert exit_code == 0
    assert "attempted 4" in captured.out
    assert "skipped 1" in captured.out
    assert "ratio 25%" in captured.out


def test_cli_exits_non_zero_when_skip_ratio_exceeds_limit(tmp_path, capsys):
    path = tmp_path / "mostly_broken.json"
    # 3 broken, 1 good = 75% skipped, well above the 50% threshold.
    _write_kibana_export(
        path,
        [_broken_record(), _broken_record(), _broken_record(), _good_record()],
    )
    out = tmp_path / "out.py"
    exit_code = cli_main([str(path), "--output", str(out)])
    captured = capsys.readouterr()
    assert exit_code == 2
    assert "Skip ratio" in captured.err

CHANGELOG.md

CONTRIBUTING.md

README.md

REFERENCE.md

RELEASING.md

requirements.txt

SECURITY.md

SKILL.md

tessl.json

tile.json