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

9

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

Quindi ho dei test di integrazione dove sto chiamando l'API GitHub, con autenticazione.
(e quando la funzionalità di clonazione / estrazione è terminata, probabilmente ci saranno test che cloneranno i repository da GitHub, e avranno bisogno per autenticarsi)

Ho creato un utente e un'organizzazione specialmente per l'uso 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.

Che cosa sto facendo ora

Nei test, sto ricevendo tutti i nomi utente, password e nomi di 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 quelle variabili d'ambiente.
Quello reale ( environment-variables.bat ) viene chiamato nel mio script di build e prima dell'esecuzione dei test, ma ignorato nel controllo del codice sorgente, quindi non è effettivamente nel mio repository.

Che è nel controllo del codice sorgente è environment-variables.bat.sample , che imposta le stesse variabili d'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 sul mio computer, rinominare questo file in environment-variables.bat , sostituire la password falsa con quella reale e tutti i test di integrazione funzioneranno.

Funziona anche con l'integrazione continua - sto usando AppVeyor, e lì posso impostare questi variabili d'ambiente nell'interfaccia utente web .

Ciò che non mi piace su di esso

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

In teoria, un contributore al mio progetto sarebbe in grado di eseguire i test di integrazione proprio ora:

  • creando il proprio utente di test e l'organizzazione di test su GitHub
  • creazione di alcuni repository di test
  • crea la sua versione di environment-variables.bat con 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 supporto per più hosters aggiungendo alcune classi che implementano le interfacce giuste.

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

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

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

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

    
posta Christian Specht 26.02.2017 - 14:18
fonte

1 risposta

2

Penso che il tuo setup attuale sia perfetto, ma vorrei fare qualche aggiustamento.

To be able to execute all integration tests, a potential contributor would create his own users, organizations and test repositories at GitHub, Bitbucket, GitLab, .... and who knows how much more, and add all of them to his environment-variables.bat version.

Sì, è vero, ma i contributori non devono necessariamente eseguire tutti i test di integrazione prima di creare un PR sul progetto. Una volta creata una PR, l'elemento della configurazione eseguirà la suite completa di test.

È comune avere una suite di test che non è in qualche modo possibile eseguire facilmente. Per molte organizzazioni mantengono suite di test che impiegano giorni per essere eseguiti, pertanto gli sviluppatori devono eseguire test selettivi facili da eseguire e spingere il codice in avanti per test più rigorosi. Sto suggerendo lo stesso approccio.

Per i contributori regolari / fidati, puoi renderli contributori effettivi sul tuo progetto che dovrebbero consentire loro di eseguire CI sul loro ramo prima di fare un PR.

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

Gli aggiustamenti che ti suggerisco sono:

In primo luogo, effettua la maggior parte dei test delle unità di copertura del test. Questi dovrebbero coprire tutti i rami della tua base di codice.

In secondo luogo, scrivere test di integrazione in cui l'endpoint è deriso. Puoi persino prendere in giro 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 ti permetteranno di

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

Terzo, disabilita tutti i test che richiedono conoscenze speciali da eseguire in una build normale. Nella maggior parte degli strumenti di gestione delle build esiste un modo per separare i test di integrazione, tag test e gestirli in modo selettivo. I contributori dovrebbero essere in grado di creare e testare il software senza qualsiasi configurazione precedente. L'intera suite di test dovrebbe essere eseguita dopo ogni build in CI.

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

    
risposta data 14.06.2017 - 02:25
fonte

Leggi altre domande sui tag