\chapter{Datos de prueba y entornos} \label{ch:datos} \section{Host donde se ejecutan las pruebas} \label{sec:host-pruebas} Las pruebas contra el stack desplegado (smoke, integraci\'on parcial, estr\'es k6) se realizan en el siguiente equipo. \textbf{Todo informe de ejecuci\'on debe citar este entorno} (o indicar expl\'icitamente si se us\'o otro). \subsection{Hardware y sistema} \begin{table}[ht] \centering \begin{tabular}{@{}lp{8.5cm}@{}} \toprule \textbf{Campo} & \textbf{Valor} \\ \midrule Hostname & \texttt{ubuntu} \\ SO & Ubuntu 24.04.4 LTS (kernel 6.17.0-35-generic) \\ Arquitectura & x86-64 \\ Equipo & ASUSTeK X441UAK \\ CPU & Intel Core i5-7200U @ 2{,}50\,GHz (2 n\'ucleos / 4 hilos) \\ RAM & 8\,GiB DDR4-2133 (l\'imite visible Docker $\approx$ 7{,}64\,GiB) \\ Almacenamiento & HDD 500\,GB interno + disco USB 1\,TB EXT4 \\ Contexto cloud CLI & \texttt{default/inmodata-builker} \\ \bottomrule \end{tabular} \caption{Host de pruebas IPSExtractor (staging compartido).} \label{tab:host-pruebas} \end{table} \subsection{Stack IPSExtractor observado (idle)} Medici\'on \texttt{docker stats --no-stream} (13 jul 2026), contenedores IPS: \begin{table}[ht] \centering \begin{tabular}{@{}lr@{}} \toprule \textbf{Contenedor} & \textbf{RAM aprox.} \\ \midrule \texttt{ipsextractor-api} (gateway) & 42\,MiB \\ \texttt{ipsextractor-extraction} & 31\,MiB \\ \texttt{ipsextractor-worker-1/2} & 28--32\,MiB c/u \\ \texttt{ipsextractor-cleaning} & 36\,MiB \\ \texttt{ipsextractor-bot-descarga} & 17\,MiB \\ \texttt{ipsextractor-count-api} & 13\,MiB (l\'imite 4\,GiB) \\ \texttt{ipsextractor-db} & 27\,MiB \\ \texttt{ipsextractor-redis} & 8\,MiB \\ \midrule \textbf{Subtotal IPS (idle)} & $\approx$ 230--250\,MiB \\ \bottomrule \end{tabular} \caption{Huella de memoria IPSExtractor en idle.} \end{table} Health verificado: \begin{lstlisting}[language=bash,caption={Smoke del gateway en el host}] curl -s http://127.0.0.1:8189/health/live # {"status":"ok"} curl -s http://127.0.0.1:8189/health # status ok; extraction, cleaning, counting, bot_descarga ok # Nota: el health agregado puede tardar ~10-12 s en este host. \end{lstlisting} \subsection{Carga concurrente del host (no IPS)} El mismo Docker Engine ejecuta muchos servicios ajenos a IPSExtractor. En la misma medici\'on destacaban, entre otros: \begin{itemize} \item \texttt{mlflow-server} $\approx$ \textbf{1{,}86\,GiB} ($\sim$24\,\% de la RAM) \item Airflow (scheduler + webserver + postgres) $\approx$ 530\,MiB \item \texttt{n8n\_app} $\approx$ 291\,MiB \item \texttt{postgresql} (instancia compartida) $\approx$ 255\,MiB \item \texttt{minio-server} $\approx$ 136\,MiB, \texttt{uptime-kuma} $\approx$ 121\,MiB \item Adem\'as: registry, MariaDB, MongoDB, Qdrant, Portainer, Mermaid, Metabase Postgres, Redis cache, Inmodata API, etc. \end{itemize} \textbf{Consecuencia:} el host es un \emph{staging compartido}, no un laboratorio dedicado. Los SLOs de estr\'es del perfil \texttt{host-compartido-8gb} (cap.~\ref{ch:estres}) son los aplicables por defecto en este equipo. Un fallo por OOM o latencia alta \textbf{no} debe atribuirse autom\'aticamente a un bug de IPSExtractor sin revisar \texttt{docker stats} y \texttt{free -h}. \subsection{Requisitos previos a una campa\~na de estr\'es} \begin{enumerate} \item Registrar en el informe: fecha, hostname, \texttt{free -h}, salida de \texttt{docker stats --no-stream}. \item Preferible pausar/detener MLflow y Airflow (y n8n si es posible) para liberar $\geq$2\,GiB antes de k6 ligero, o $\geq$3\,GiB antes de ST-COUNT. \item Usar siempre \texttt{127.0.0.1:8189} (no \texttt{localhost} por IPv6). \end{enumerate} \section{Fixtures recomendadas} \begin{description} \item[PDFs] Peque\~nos (1--2 p\'ag.), medianos, corruptos, $>$ l\'imite, con/sin texto. \item[Excel bot] 10 / 100 / 1\,000 / 5\,000 radicados; NITs sucios; vac\'ios; columnas mal nombradas. \item[CSV cleaning] Encodings, nulls, fechas ambiguas, montos COP. \item[LLM] Respuestas fixture JSON v\'alido / inv\'alido / parcial (sin gastar cuota en CI). \item[Imaging] HTML stub en CI; portal real solo en m\'aquina con VPN. \end{description} \section{Variables de entorno relevantes} \begin{longtable}{@{}p{4.2cm}p{8cm}@{}} \caption{Variables cr\'iticas para pruebas.}\\ \toprule \textbf{Variable} & \textbf{Uso} \\ \midrule \endhead \texttt{IPS\_DOCUMENT\_ROOT} & Montaje PDFs $\rightarrow$ \texttt{/data} \\ \texttt{EXTRACTOR\_API\_KEY} / modelo & LLM extracci\'on \\ \texttt{WORKER\_REPLICAS} & Escala ARQ \\ \texttt{ASYNC\_QUEUE}, \texttt{REDIS\_URL} & Cola async \\ \texttt{BOT\_API\_TOKEN} & Bearer bot API + agent + desktop \\ \texttt{MINIO\_ENDPOINT}, \texttt{MINIO\_BUCKET} & S3 bot \\ \texttt{BOT\_IMAGING\_URL} & Portal Selenium \\ \texttt{OCR\_POOL\_SIZE}, \texttt{COUNT\_API\_MEMORY} & Tuning count-api \\ \bottomrule \end{longtable} \section{Seguridad en entornos de prueba} \begin{itemize} \item No usar API keys reales hardcodeadas en compose para CI/staging compartido. \item Token de bot distinto por entorno; rotar tras pruebas p\'ublicas. \item Datos sint\'eticos o anonimizados; nunca radicados reales en reportes p\'ublicos. \end{itemize}