Test di integrazione in progetti OSS: come gestire le terze parti con autenticazione?


10

Uno dei miei progetti di hobby (open source) è uno strumento di backup che esegue backup offline dei repository da GitHub, Bitbucket ecc.
Chiama l'API degli hoster per ottenere un elenco di repository, quindi utilizza Git / Mercurial / qualunque cosa clonare / estrarre i repository sul computer locale.

Quindi ho dei test di integrazione in cui chiamo l'API GitHub, con autenticazione.
(e al termine della funzione di clonazione / estrazione, probabilmente ci saranno test che clonano i repository da GitHub e che devono anche autenticarsi)

Ho creato un utente e un'organizzazione appositamente per l'utilizzo in questi test di integrazione.

Problema: non posso semplicemente codificare le password da qualche parte nel codice sorgente perché è open source e il codice è pubblico su GitHub.


Quello che sto facendo ora

Nei test, ottengo tutti i nomi utente, le password e i nomi dei repository dalle variabili di ambiente.
Ecco un esempio :

config.Name = TestHelper.EnvVar("GithubApiTests_Name");
config.Password = TestHelper.EnvVar("GithubApiTests_PW");

( TestHelper.EnvVarè un metodo di supporto che ottiene il valore di una variabile d'ambiente e genera un'eccezione quando non esiste)

Quindi, ho un file batch che imposta tali variabili di ambiente.
Quello vero ( environment-variables.bat) viene chiamato nel mio script di build e prima di eseguire i test, ma ignorato nel controllo del codice sorgente, quindi non è effettivamente nel mio repository.

Ciò che è nel controllo del codice sorgente è environment-variables.bat.sample, che imposta le stesse variabili di ambiente, ma con password false:

rem copy/rename this file to environment-variables.bat

echo Setting environment variables for integration tests...

set GithubApiTests_Name=scm-backup-testuser
set GithubApiTests_OrgName=scm-backup-testorg
set GithubApiTests_PW=not-the-real-password
set GithubApiTests_Repo=scm-backup

Quindi posso clonare il repository sulla mia macchina, rinominare questo file in environment-variables.bat, sostituire la password falsa con quella vera e tutti i test di integrazione funzioneranno.

Funziona anche con l'integrazione continua: sto usando AppVeyor e lì posso impostare queste variabili di ambiente nell'interfaccia utente web .


Cosa non mi piace al riguardo

Penso che non sia una buona soluzione per un progetto OSS, e soprattutto non per questo progetto:

In teoria, un collaboratore del mio progetto sarebbe in grado di eseguire i test di integrazione in questo momento:

  • creando il proprio utente di test e l'organizzazione di test su GitHub
  • creando alcuni repository di prova
  • creando la propria versione di environment-variables.batcon valori diversi

Il problema è che la mia applicazione sarà in grado di eseguire il backup di più hoster di codice sorgente.
Al momento supporta solo GitHub, ma sarà facile aggiungere il supporto per più hoster aggiungendo alcune classi che implementano le giuste interfacce.

Quindi, quando implementerò il supporto per più hoster in seguito, il numero di variabili di ambiente aumenterà.
Per essere in grado di eseguire tutti i test di integrazione, un potenziale collaboratore creerebbe i propri utenti, organizzazioni e repository di test su GitHub, Bitbucket, GitLab, .... e chissà quanti altri ancora, e li aggiungerebbe tutti alla sua environment-variables.batversione.

Esiste una soluzione migliore come farlo su un progetto in cui il codice è pubblico?

So che altri progetti fanno qualcosa di simile a quello che sto attualmente facendo.
Octokit.net , ad esempio, ha uno script per configurare le variabili di ambiente per i test di integrazione che chiamano l'API GitHub.
Ma hanno solo bisogno di un utente e una sola organizzazione, e ne avrò bisogno molto di più.

Forse non ho bisogno di una soluzione che consenta a un collaboratore di eseguire effettivamente tutti i test di integrazione.
Ad esempio, se qualcuno volesse contribuire al supporto GitHub del mio progetto, dovrebbe solo essere in grado di eseguire i test di integrazione di GitHub.
Quindi forse ho solo bisogno di un modo sano di essere in grado di dividere i miei test di integrazione in un numero infinito di "gruppi" (?) E quindi di dire "e ora eseguire tutti i test che appartengono al gruppo 'Github'".

Risposte:


2

Penso che la tua configurazione attuale vada bene, ma vorrei apportare alcune modifiche.

Per essere in grado di eseguire tutti i test di integrazione, un potenziale collaboratore creerebbe i propri utenti, organizzazioni e repository di test su GitHub, Bitbucket, GitLab, .... e chissà quanto altro, e aggiungerli tutti alle sue variabili d'ambiente Versione .bat.

Sì, è vero, ma i collaboratori non devono necessariamente eseguire tutti i test di integrazione prima di creare un PR sul progetto. Una volta creato un PR, l'IC eseguirà la suite completa di test.

È comune avere una suite di test che in qualche modo non è possibile eseguire facilmente. Per molte organizzazioni gestiscono suite di test che richiedono giorni per essere eseguite, pertanto gli sviluppatori devono eseguire selettivamente test facili da eseguire e far avanzare il codice per test più rigorosi. Sto suggerendo lo stesso approccio.

Per i contributori regolari / affidabili, è possibile renderli effettivi collaboratori nel proprio progetto, il che dovrebbe consentire loro di eseguire elementi della configurazione nella propria filiale prima di effettuare un PR.

Detto questo, non stai impedendo ai partecipanti di eseguire l'intera suite di test. Possono fornire le proprie credenziali GitHub o creare i propri account di prova e probabilmente i contributori regolari lo faranno.

Le modifiche che suggerisco sono:

Innanzitutto, esegui la maggior parte dei test dell'unità di copertura dei test. Questi dovrebbero coprire tutti i rami del tuo codebase.

In secondo luogo, scrivere i test di integrazione in cui l'endpoint è deriso. Puoi persino deridere il livello di trasporto di queste API e simulare i flussi di richiesta / risposta HTTP avviando un falso servizio GitHub Rest. Ad esempio (in pseudo codice):

// Test failed authentication to GitHub
val server = new WebServer("localhost", 9453, { request =>
    return Response(401, "unauthenticated")
})
server.start()
val backupService = new GitHubBackupService("http://localhost:9453")
backupService.backup must throw UnauthenticatedException()
server.stop()

Questi test saranno più complessi, ma te lo permetteranno

  1. Prova senza creare account e repository falsi
  2. Verifica le condizioni di errore che sarebbe difficile simulare con GitHub reale. Ad esempio 502 risposte, timeout di connessione, corpi di risposta insoliti / non analizzabili.

In terzo luogo, disabilitare tutti i test che richiedono conoscenze speciali da eseguire in una build normale. Nella maggior parte degli strumenti di gestione della build esiste un modo per separare i test di integrazione o tag test ed eseguirli selettivamente. I collaboratori dovrebbero essere in grado di costruire e testare il software senza alcuna configurazione precedente. La suite di test completa dovrebbe essere eseguita dopo ogni build in CI.

Infine, documenta i test e come eseguirli nella documentazione di test in modo che i partecipanti possano scegliere di eseguirli.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.