133 lines
6.3 KiB
TeX
133 lines
6.3 KiB
TeX
\subsection{Verifikation}
|
|
\label{ssub:verifikation}
|
|
|
|
Wie auch in der Softwareentwicklung müssen Konfigurationssysteme getestet
|
|
werden. Dies gestaltet sich oft als schwierig, weil nicht immer eine exakte
|
|
Kopie des aktuellen Produktionssystems zur Verfügung steht. Mit steigender
|
|
Komplexität steigt der Aufwand, Cookbooks manuell zu testen. Im Folgenden werden
|
|
verschiedene Möglichkeiten aufgeführt, wie dies automatisiert werden kann.
|
|
|
|
Die erste und einfachste Methode ist der Befehl:
|
|
|
|
\shellcmd{knife cookbook test [COOKBOOKS...]}
|
|
|
|
Das Kommandozeilenprogramm \texttt{knife} ist ein Teil von Chef. Es ist das
|
|
primäre Verwaltungsprogramm für Chef-Administratoren. Der Unterbefehl
|
|
\texttt{cookbook test} überprüft den Ruby-Quellcode und die Templates des
|
|
Cookbooks auf Syntaxfehler. Allerdings treten viele Fehler erst zur Laufzeit
|
|
auf, im Besonderen da Ruby dynamisch typisiert ist und der Compiler
|
|
beispielsweise Tippfehler in Methoden und Variablennamen nicht erkennen kann.
|
|
Ein anderes Programm ist foodcritic. Es führt eine statische Codeanalyse ähnlich
|
|
\href{http://www.jslint.com/}{JSlint} oder
|
|
\href{http://perl-critic.stacka.to/}{Perl::Critic} auf der eigenen Codebasis
|
|
durch. Dabei wird der Ruby-Quellcode gegen einen Regelsatz getestet, um so
|
|
häufige Programmierfehler zu erkennen oder um Code-Konventionen innerhalb eines
|
|
Projekts einzuhalten. Dieser Regelsatz kann durch eigene Regeln erweitern
|
|
werden.
|
|
|
|
\subsubsection{Chefspec}
|
|
\label{chefspec}
|
|
|
|
Chefspec baut auf das in Ruby verbreitete Testframework
|
|
\href{http://rspec.info/}{RSpec} auf. Chefspec erweitert dabei RSpec um die
|
|
Funktion, Cookbooks zu laden und stellt spezielle Matcher (RSpec-Terminologie
|
|
für Assertions) bereit, um diese zu testen. Wie bereits in
|
|
Abschnitt~\ref{ablauf_einer_provisionierung} erwähnt, gibt es zwei Phasen bei
|
|
der Ausführung von Chef. Bei Chefspec wird der Provisionierungsprozess nur bis
|
|
zur Convergingphase durchlaufen. Die eigenen Tests überprüfen nur die erzeugten
|
|
\texttt{Ressourcen}. Dies hat den Vorteil, das Tests sehr schnell durchlaufen
|
|
werden, da keine Änderungen an einem System vorgenommen werden müssen. Dies hat
|
|
Vorteile beim Entwickeln, weil man auf diese Weise schnell Feedback bekommt. Das
|
|
Zusammenspiel mehrerer Cookbooks lässt sich dadurch gut testen. Außerdem
|
|
ermöglicht es, verschiedene Konfigurationen/Betriebssysteme zu testen, ohne das
|
|
diese (zeit)aufwendig aufgesetzt werden müssen. Da Chefspec allerdings zu keinen
|
|
Zeitpunkt Code auf dem System ausführt, sind weitere Integrationstest
|
|
unerlässlich.
|
|
|
|
Der folgende Test wurde aus dem selbst geschriebenen NTP-Cookbook
|
|
(\ref{sub:einrichtung-der-netzwerkdienste}) entnommen.
|
|
\begin{lstlisting}[language=Ruby,caption={Chefspec-Test für das NTP-Cookbook}]
|
|
require_relative '../spec_helper'
|
|
|
|
describe 'ntp::default' do
|
|
let(:chef_run) do
|
|
ChefSpec::Runner.new do |node|
|
|
node.set["ntp"]["subnets"] = ["::1", "127.0.0.1", "172.28.128.0 mask 255.255.255.0 nomodify notrap nopeer"]
|
|
end.converge(described_recipe)
|
|
end
|
|
|
|
it "should setup ntp" do
|
|
chef_run.should install_package("ntp")
|
|
chef_run.should render_file("/etc/ntp.conf").with_content("172.28.128.0")
|
|
end
|
|
end
|
|
\end{lstlisting}
|
|
|
|
Im \texttt{chef\_run}-Block wird dem fiktiven Node Attribute zugewiesen und das zu
|
|
testende Cookbook ausgeführt. Das Ergebnis wird in diesem Beispiel in dem Objekt
|
|
\texttt{chef\_run} gespeichert. Gegen dieses Objekt wird getestet, ob bestimmte
|
|
\texttt{Ressourcen} korrekt initialisiert wurden. In diesem Fall wird überprüft, ob
|
|
das Paket \texttt{ntp} installiert werden soll und ob das Subnetz in dem Template
|
|
in der Konfigurationsdatei \texttt{/etc/ntp.conf} richtig gesetzt wird.
|
|
|
|
Die Tests werden mit dem Befehl \texttt{rspec} ausgeführt. Wenn keine weiteren Argumente
|
|
angegeben sind, führt dieses Programm alle Dateien unterhalb des Ordners \texttt{spec}
|
|
aus, dessen Dateinamen auf \texttt{\_spec.rb} enden.
|
|
|
|
Um alle drei oben genannten Testmethoden gleichzeitig ausführen zu lassen, wurde
|
|
ein Rakefile geschrieben. \href{http://rake.rubyforge.org/}{Rake} ist das in
|
|
Ruby geschriebene Äquivalent zu Make, welches ein verbreitetes Buildprogramm
|
|
auf UNIX-ähnlichen Plattformen ist. Die Tests werden durch den Befehl:
|
|
|
|
\shellcmd{rake test}
|
|
|
|
ausgeführt.
|
|
|
|
Dieser muss innerhalb Projektverzeichnisses aufgerufen werden.
|
|
|
|
\subsubsection{Minitest-Handler}
|
|
\label{minitest_handler}
|
|
|
|
\href{https://github.com/btm/minitest-handler}{Minitest-Handler} hingegen wird
|
|
nach jedem Provisionierungsdurchgang ausgeführt. Im Gegensatz zu Chefspec nutzt
|
|
es das Minitest-Framework, welches schon mit Ruby mitgeliefert wird. Um
|
|
Minitest-Handler zu nutzen, muss das Recipe aus
|
|
\texttt{Minitest-Handler-Cookbook} als erstes Recipe in der Node geladen werden.
|
|
Minitest-Handler durchsucht beim Durchlauf in jedem anderen Cookbook, in den
|
|
Unterordnern in \texttt{files/} nach dem Verzeichnis \texttt{test} und lädt alle
|
|
Tests aus diesem Verzeichnis. Über die Zeile:
|
|
|
|
\begin{lstlisting}[language=Ruby]
|
|
describe_recipe "ntp::default" do #
|
|
#...
|
|
end
|
|
\end{lstlisting}
|
|
|
|
wird angeben, zu welchem Test das Recipe gehört (In diesem Fall das
|
|
Recipe aus dem NTP-Cookbook). Wenn das entsprechende Recipe von dem Node
|
|
ausgeführt wird, wird der dazugehörige Test nach dem Provisionierungsdurchlauf
|
|
ebenfalls ausgeführt. Minitest-Handler erweitert RSpec um nützliche Methoden, um
|
|
den Status des Systems zu überprüfen. Nachfolgend ist ein Beispiel aus dem Bind-Cookbook,
|
|
welches in Abschnitt~\ref{sub:einrichtung-der-netzwerkdienste} erwähnt wurde:
|
|
|
|
\begin{lstlisting}[language=Ruby, caption={\texttt{Minitest}-Test für das Bind-Cookbook}]
|
|
describe_recipe 'bind::default' do
|
|
it "starts the named daemon" do
|
|
service("bind9").must_be_running
|
|
end
|
|
it "should resolve dns" do
|
|
assert_sh("dig localhost @localhost")
|
|
end
|
|
end
|
|
\end{lstlisting}
|
|
|
|
Die Methode \texttt{assert\_sh} überprüft den Exit-Code eines Befehls und schlägt
|
|
fehl, wenn dieser ungleich der Zahl Null ist, während die \texttt{service}-Methode den
|
|
Status eines Systemdienst überprüft. Weitere Testmethoden sind zum Beispiel
|
|
das Überprüfen von Verzeichnissen, Inhalte von Dateien oder Mountpoints. Viele
|
|
Fehler werden in der Regel schon von den Provider erkannt und festgestellt.
|
|
Minitest-Handler kann dies Erweitern um protokollspezifische Tests durchzuführen
|
|
oder das Testen von Funktionalität bestimmter Dienste.
|
|
|
|
% vim: set spell spelllang=de_de
|