feat: add new mermaid diagram and update bibliography with additional references
All checks were successful
Build LaTeX Document / build_latex (push) Successful in 4m4s
All checks were successful
Build LaTeX Document / build_latex (push) Successful in 4m4s
This commit is contained in:
185
Tesi.tex
185
Tesi.tex
@@ -63,7 +63,7 @@
|
||||
\usepackage[italian, textsize=tiny]{todonotes}
|
||||
\setlength{\marginparwidth}{2cm}
|
||||
|
||||
\usepackage{refcheck}
|
||||
%\usepackage{refcheck}
|
||||
|
||||
\usepackage{tikz}
|
||||
\usetikzlibrary{arrows}
|
||||
@@ -612,6 +612,7 @@ Per i nostri test abbiamo utilizzato una combinazione di tecnologie open source
|
||||
\item \textbf{Python}: Come linguaggio principale per l'automazione
|
||||
\item \textbf{Selenium}: Per simulare browser reali che guardano lo stream
|
||||
\item \textbf{WebRTC Internals Exporter}: Una estensione del browser creata per raccogliere metriche dettagliate sulle connessioni WebRTC
|
||||
\item \textbf{WebPack}: Un sistema di compilazione e gestione delle dipendenze per il frontend web
|
||||
\item \textbf{Hetzner Cloud e script CLI}: Per distribuire i test su macchine virtuali in diverse regioni geografiche
|
||||
\end{itemize}
|
||||
|
||||
@@ -870,6 +871,18 @@ Questo progetto fa uso di una \footnote{Disponibile qui: \url{https://gitea.kobi
|
||||
\item Supporto alla configurazione tramite variabili d'ambiente per semplificare l'integrazione con il nostro sistema di test.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Webpack}
|
||||
|
||||
Webpack è un bundler di moduli per applicazioni JavaScript. Prende moduli con varie dipendenze e genera dei file statici che rappresentano quei moduli. È ampiamente utilizzato per applicazioni web moderne, in particolare quelle basate su framework come React, Angular e Vue.js.
|
||||
|
||||
Quando Webpack elabora un'applicazione, costruisce internamente un grafo delle dipendenze a partire da uno o più entry points. Successivamente, combina tutti i moduli necessari al progetto in uno o più bundle, che sono asset statici utilizzati per servire i contenuti dell'applicazione.
|
||||
|
||||
Di default, Webpack `comprende' solo file JavaScript e JSON.
|
||||
|
||||
Per gestire altri tipi di file, utilizza i \textit{Loaders}, che permettono di elaborare e convertire vari formati (come CSS, immagini o TypeScript) in altro moduli validi. Questi moduli possono essere quindi usati dall'applicazione ed aggiunti al grafo delle dipendenze.
|
||||
|
||||
Altro componente essenziale sono i \textit{Plugin}. Mentre i \textit{Loaders} trasformano i file in moduli validi, i \textit{Plugin} servono per eseguire operazioni più avanzate, come ottimizzazione, gestione degli asset, variabili d’ambiente e molto altro.\cite{webpackConceptsWebpack}
|
||||
|
||||
\subsection{Hetzner Cloud e script CLI}
|
||||
|
||||
Hetzner Cloud è un servizio di cloud computing offerto da Hetzner Online GmbH, un provider di servizi di hosting e data center con sede in Germania. Hetzner Cloud offre una vasta gamma di servizi di cloud computing, tra cui server virtuali, storage, reti e servizi di sicurezza.
|
||||
@@ -885,36 +898,176 @@ Rispetto a quelli originali, li abbiamo modificati per far utilizzo delle varibi
|
||||
|
||||
Finora abbiamo descritto le tecnologie utilizzate alla base per creare il nostro sistema di test, senza però piegare effettivamente come queste vengono integrate e utilizzate insieme per creare un sistema di test automatizzato.
|
||||
|
||||
Introduciamo quindi l'ultimo pezzo necessario per far funzionare il tutto, ovvero il \textbf{\textit{collector}}, un'applicazione Python che si occupa di fare \footnote{Il data scraping è una tecnica in cui un programma informatico estrae dati da un output leggibile dall'uomo generato da un altro programma.} \textbf{scraping} delle metriche di PeerTube, di raccogliere le metriche WebRTC tramite l'estensione Chromium, e di inviare il tutto a Telegraf per l'elaborazione e l'invio al database.
|
||||
Introduciamo quindi l'ultimo pezzo necessario per far funzionare il tutto, ovvero il \textbf{\textit{collector}}, un'applicazione Python che si occupa di fare \footnote{Il data scraping è una tecnica in cui un programma informatico estrae dati da un output leggibile dall'uomo generato da un altro programma.} scraping delle metriche di PeerTube, di raccogliere le metriche WebRTC tramite l'estensione Chromium, e di inviare il tutto a Telegraf per l'elaborazione e l'invio al database.
|
||||
|
||||
\begin{figure}[H]
|
||||
\vfill
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=\textwidth]{images/mermaid-diagram-2025-03-20-215704.png}
|
||||
\includegraphics[width=\textwidth]{images/mermaid-diagram-2025-03-22-144148.png}
|
||||
\caption{Architettura del collector.}
|
||||
\label{fig:architettura-collector}
|
||||
\end{figure}
|
||||
\vfill\break
|
||||
|
||||
Nella figura \ref{fig:architettura-collector} viene mostrato il funzionamento e il flusso dei dati all'interno del \textit{collector} e come esso si interfacci con le altre tecnologie utilizzate.
|
||||
|
||||
|
||||
|
||||
Ecco quindi un diagramma finale dell'architettura del nostro sistema:
|
||||
Nello specifico il \textit{collector} è composto da 3 parti principali:
|
||||
|
||||
\begin{itemize}
|
||||
\item Un server centrale che esegue un'istanza di PeerTube e che raccoglie le metriche fornite da OpenTelemetry.
|
||||
\item Multiple macchine virtuali distribuite geograficamente che simulano gli spettatori.
|
||||
\item Una applicazione Python in esecuzione sulle singole macchine, che coordina Selenium e Telegraf per raccogliere le metriche WebRTC e di sistema.
|
||||
\item Un database centralizzato per la raccolta e l'analisi dei dati.
|
||||
\item Un Python script principale che coordina il tutto
|
||||
\item Selenium
|
||||
\item WebRTC Internals Exporter
|
||||
\end{itemize}
|
||||
|
||||
Selenium e WebRTC Internals Exporter li abbiamo già descritti in precedenza, mentre il Python script è il cuore del sistema, che si occupa di coordinare le altre componenti, di avviare e fermare i test, di raccogliere i dati, aggregarli e di inviarli a Telegraf per l'invio al database.
|
||||
|
||||
\subsection{Difficoltà incontrate e soluzioni}
|
||||
|
||||
Durante lo sviluppo del sistema di test abbiamo affrontato diverse sfide:
|
||||
Durante la creazione del sistema, abbiamo incontrato diverse difficoltà, per lo più sistemistiche, che hanno richiesto soluzioni creative per superarle. Alcune delle principali sfide sono state:
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{Accesso alle metriche WebRTC}: Risolto sviluppando un'estensione Chrome personalizzata
|
||||
\item \textbf{Limitazioni delle API di Peertube}: Superato utilizzando tecniche di scraping con Selenium e Python
|
||||
\item \textbf{Gestione delle variabili d'ambiente nell'estensione Chrome}: Risolto attraverso webpack e sostituzione dinamica
|
||||
\item \textbf{Raccolta dei dati dei test su macchine virtuali distribuite}: Risolto utilizzando Telegraf e MongoDB
|
||||
\item \textbf{Accesso agli indirizzi IP forniti da WebRTC}: WebRTC dalle ultime versioni come misura di sicurezza e privacy, non permette più l'accesso e la visualizzazione degli indirizzi IP locali delle macchine coinvolte nella connessione grazie a tecniche di offuscazione, rendendo difficile la raccolta di queste informazioni. Per ovviare a questo problema ci siamo avvalsi di 2 soluzioni: la prima consiste nell'utilizzare una versione vecchia di Chromium, nello specifico una versone anteriore o uguale alla 129.0, in quanto in queste versioni l'offuscazione è presente ma è possibile disabilitarla tramite un flag da interfaccia grafica; la seconda soluzione invece consiste proprio nel disabilitarequesta funzionalità ma da riga di comando tramite un altro flag, all'avvio del browser.
|
||||
\item \textbf{Limitazioni delle API di Peertube}: PeerTube fornisce delle API per la gestione della piattaforma, moderazione dei video, e altro ancora, ma non fornisce API per la raccolta delle metriche dei video. Alcune metriche generiche sono esposte via OpenTelemetry ma non sono specifiche per un singolo utente o video. Per ovviare a questo problema, abbiamo utilizzato il data scraping per estrarre le metriche direttamente dalla pagina web.
|
||||
\item \textbf{Gestione delle variabili d'ambiente nell'estensione Chrome}: WebRTC Internals Exporter è un'estensione per Chromium che consente di esportare le metriche WebRTC da un browser in un formato leggibile e analizzabile. Tuttavia, l'estensione non supporta la sostituzione delle variabili d'ambiente nel codice JavaScript, in quanto viene caricata ed eseguita runtime in un ambiente isolato, rendendo difficile la configurazione dinamica dell'estensione. L'utilizzo di WebPack ci consente di configurare l'estensione in fase di complilazione, sostituendo le variabili d'ambiente con i valori corretti prima di caricarla nel browser.
|
||||
\item \textbf{Raccolta dei dati dei test su macchine virtuali distribuite}: Data la distribuzione geografica delle nostre macchine virtuali di test, abbiamo dovuto affrontare la sfida di raccogliere ed aggregare i dati in modo efficiente e coordinato. Abbiamo risolto questo problema utilizzando Telegraf come agente di raccolta dati su ogni VM, configurandolo per inviare le metriche ad un'istanza centrale di MongoDB. MongoDB è stato scelto per la sua flessibilità nello schema e per la capacità di gestire grandi volumi di dati time-series provenienti da fonti eterogenee.Le API di Hetzner Cloud ci hanno permesso di automatizzare il deployment e la configurazione di tutte queste componenti su macchine distribuite in diverse regioni geografiche, mantenendo una configurazione coerente su tutta l'infrastruttura di test.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Python script}
|
||||
|
||||
Il funzionamento dello script è relativamente semplice; vengono eseguiti dei passaggi in successione per arrivare in una situazione in cui i dati sono costantemente raccolti e inviati al database creando quindi un ciclo infinito che si ripete ogni 2 secondi circa, fin quando il test non viene fermato.
|
||||
|
||||
\
|
||||
|
||||
Importante particolarità dello script è la possibilità di creare e caricare plugin personalizzati che permettono di estrarre metriche di vario tipo da potenzialmente qualsiasi pagina web e non solo da PeerTube. Questo potenzialmente permette di estendere il sistema di test a qualsiasi altra piattaforma di video streaming, o di qualsiasi altro tipo, semplicemente creando un plugin personalizzato.
|
||||
Questa funzionalità è stata implementata utilizzando le \textit{Abstract Base Classes} di Python, che permettono di definire delle classi base che devono essere implementate dalle classi derivate, e che permettono di definire delle interfacce comuni.
|
||||
|
||||
\begin{lstlisting}[caption={Abstract Base Classes}, captionpos=b, basicstyle=\scriptsize]
|
||||
# Abstract Base Classes for Plugins
|
||||
class StatsSetupPlugin(abc.ABC):
|
||||
@abc.abstractmethod
|
||||
def setup_stats(
|
||||
self,
|
||||
driver: webdriver.Remote | webdriver.Chrome,
|
||||
url: str,
|
||||
retries: int = 5
|
||||
) -> webdriver.Remote | webdriver.Chrome:
|
||||
pass
|
||||
|
||||
class StatsDownloadPlugin(abc.ABC):
|
||||
@abc.abstractmethod
|
||||
def download_stats(
|
||||
self,
|
||||
driver: webdriver.Remote | webdriver.Chrome,
|
||||
peersDict: dict,
|
||||
socket_url: str,
|
||||
socket_port: int
|
||||
):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def saveStats(stats: list, socket_url: str, socket_port: int):
|
||||
try:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
logger.debug(f'Saving stats: {json.dumps(stats, indent=4)}')
|
||||
sock.sendto(json.dumps(stats).encode(), (socket_url, socket_port))
|
||||
sock.close()
|
||||
logger.debug('Sent stats to socket.')
|
||||
except socket.error as e:
|
||||
logger.error(f'Got socket error: {e}')
|
||||
\end{lstlisting}
|
||||
|
||||
|
||||
|
||||
Per tutto questo, alla creazione, abbiamo fatto uso di alcune librerie Python tra cui: \textit{selenium} e \textit{beautifulsoup4}.
|
||||
\\ \textit{BeautifulSoup} è una libreria Python che permette di estrarre dati da file HTML e XML. È in grado di navigare nella struttura del documento, estrarre i dati, modificarli e salvare le modifiche. È spesso utilizzata per fare \textit{web scraping}. Assieme, quste due librerie, ci permettono di interagire con il browser e di estrarre i dati necessari dalla pagina web di PeerTube.\cite{10617017}
|
||||
|
||||
I passaggi presenti in figura \ref{fig:architettura-collector} possono essere riassunti come:
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{Inizializzazione}: Viene impostata da riga di comando o tramite variabili d'ambiente la configurazione del test.
|
||||
\begin{description}
|
||||
\item Queste possono includere: I plugin personalizzati BeautifulSoup, l'URL del video da analizzare, l'URL del server Telegraf, l'URL dell'hub di Selenium Grid, il percorso dell'estensione di WebRTC Internals Exporter, e altro ancora.
|
||||
\end{description}
|
||||
\item \textbf{Avvio del browser}: Viene avviato il browser ed aperta la pagina del video specificato tramite Selenium, con l'estensione di WebRTC Internals Exporter installata ed abilitata. Viene anche avviato in ascolto un server HTTP in background per ricevere le metriche WebRTC tramite un endpoint locale POST dedicato.
|
||||
\item \textbf{Avvio del test}: Viene caricata la pagina del video e tramite Selenium viene controllato che il video sia in riproduzione tramite il controllo dell'esistenza del bottone play.
|
||||
\item \textbf{Raccolta delle metriche WebRTC}: L'estensione per WebRTC inizia a raccogliere le metriche e ogni 2 secondi circa le invia allo script principale. Viene quindi di fatto instaurato un ciclo che viene usato dallo script come sorgente di clock per la raccolta delle altre metriche.
|
||||
\item \textbf{Raccolta delle metriche video di PeerTube}: Utilizzando BeautifulSoup, vengono trasformate e raccolte le metriche del player video di PeerTube, come la qualità del video, il buffering, quantità di dati trasferiti, la latenza, e altro ancora.
|
||||
\item \textbf{Invio delle metriche a Telegraf}: Le metriche raccolte infine vengono inviate a Telegraf tramite una socket di sistema, per l'elaborazione e l'invio al database finale.
|
||||
\end{itemize}
|
||||
|
||||
Va evidenziata la scelta di utilizzare un solo script Python per coordinare il tutto sia l'inizializzazione che raccolta delle metriche dalle pagine web e dalla estensione esterna, in quanto questo ha semplificato la gestione e soprattutto la creazione del sistema, e permette come bonus di avere un unico punto di controllo per l'intero processo.
|
||||
|
||||
\newpage
|
||||
|
||||
\begin{lstlisting}[caption={Codice del plugin per la raccolta delle metriche di PeerTube}, captionpos=b, basicstyle=\scriptsize]
|
||||
# Default Plugin Implementation
|
||||
class DefaultStatsSetupPlugin(StatsSetupPlugin):
|
||||
def setup_stats(
|
||||
self, driver: webdriver.Remote,
|
||||
url: str,
|
||||
retries: int = 5
|
||||
) -> webdriver.Remote:
|
||||
logger.log(logging.INFO, 'Setting up stats.')
|
||||
actions = ActionChains(driver)
|
||||
wait = WebDriverWait(driver, 30, poll_frequency=0.2)
|
||||
|
||||
sleep(2)
|
||||
|
||||
for attempt in range(retries):
|
||||
driver.get(url)
|
||||
try:
|
||||
wait.until(
|
||||
ec.presence_of_element_located(
|
||||
(By.CLASS_NAME, 'vjs-big-play-button')
|
||||
)
|
||||
)
|
||||
break
|
||||
except Exception:
|
||||
logger.error(
|
||||
f'Timeout. Attempt {attempt + 1} of {retries}'
|
||||
)
|
||||
if attempt == retries - 1:
|
||||
logger.error('Timeout limit reached. Exiting.')
|
||||
driver.quit()
|
||||
raise SystemExit(1)
|
||||
|
||||
actions.click(
|
||||
driver.find_element(By.CLASS_NAME ,'video-js')
|
||||
).perform()
|
||||
wait.until(
|
||||
ec.visibility_of_element_located((By.CLASS_NAME, 'vjs-control-bar'))
|
||||
)
|
||||
actions.context_click(
|
||||
driver.find_element(By.CLASS_NAME ,'video-js')
|
||||
.perform()
|
||||
statsForNerds = driver.find_elements(
|
||||
By.CLASS_NAME ,'vjs-menu-item'
|
||||
|
||||
actions.click(statsForNerds[-1]).perform()
|
||||
wait.until(
|
||||
ec.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, 'div.vjs-stats-content[style="display: block;"]')
|
||||
)
|
||||
)
|
||||
actions.move_to_element(
|
||||
driver.find_element(By.CLASS_NAME ,'vjs-control-bar')
|
||||
).perform()
|
||||
|
||||
logger.log(logging.INFO, 'Stats setup complete.')
|
||||
|
||||
return driver
|
||||
\end{lstlisting}
|
||||
|
||||
\newpage
|
||||
|
||||
Il diagramma finale dell'architettura del nostro sistema è il seguente:
|
||||
|
||||
\begin{itemize}
|
||||
\item Un server centrale che esegue un'istanza di PeerTube e che raccoglie le metriche fornite da OpenTelemetry.
|
||||
\item Molteplici macchine virtuali distribuite geograficamente sul globo che simulano gli spettatori.
|
||||
\item Una applicazione Python in esecuzione su ogni singola macchina, che coordina Selenium e Telegraf per raccogliere le statistiche del video in riproduzione e le metriche WebRTC.
|
||||
\item Un database centralizzato per la raccolta dei dati.
|
||||
\end{itemize}
|
||||
|
||||
\section{Casi d'uso e scenari di test riprodotti}
|
||||
|
Reference in New Issue
Block a user