Donnerstag, 14. November 2013

Codeanalyse ganz einfach

Für die Code Analyse bzw. für die Analyse der Codequalität gibt es eine Reihe von Werkzeugen wie PMD, Findbugs, Emma, Sonar und und und. Die Werkzeuge sind mehr oder weniger einfach zu bedienen und lassen sich meist gut in bestehende Entwicklungsumgebungen wie Eclipse, Ant oder Maven integrieren. Aber es geht noch einfacher. Man kann Codeanalysen auch in der Kommandozeile machen. Hier ein paar Beispiele:

Beispiel 1: Finden von Null Rückgabewerten, ein typischer Codestinker
grep -e "return null"  projectXX/net/ffreax/**/*.java | wc -l

Beispiel 2: Finde die Dateien mit den meisten Zeilen, potentielle Gottklassen bzw. überladenen Klassen
wc -l projectXX/net/ffreax/**/*.java | sort -nr | head

Ab jetzt wird PMD hinzugenommen, duz muss PMD heruntergeladen (Link) werden.

Beispiel 3: Code Duplikate finden, hier für PHP
bin/run.sh cpd --files ~/Documents/ME_Code_Review/projectXX-Web/Classes/ --minimum-tokens 120 --language php | less

Beispiel 4: Gott Klassen finden
bin/run.sh pmd -d ~/Documents/ME_Code_Review/projectXX-Android/net/  -l java   -R rulesets/java/design.xml | grep GodClass

Beispiel 5: Alle Basic Probleme
bin/run.sh pmd -d ~/Documents/ME_Code_Review/projectXX-Android/net/  -l java -r design -f text -R rulesets/java/basic.xml | less

Mittwoch, 13. November 2013

Ant und Jmeter: Automatisches anpassen des Jmeter Testplan

Jmeter lässt sich in Ant relativ einfach via Jmeter Task integrieren. Dazu benötigt mann nur ein JAR (extras/ant-jmeter-*.jar), welches mit Jmeter kommt. Jmeter selbst kann mit Variablen umgehen, die man z.B. via Kommandozeile setzen kann, hier wir das Property duration auf 12 gesetzt.
jmeter.sh -n -l r.xml -t LPT-woff-size-load.jmx -Jduration=12
Im Testplan kann man dann einfach auf diesen Wert zugreifen, hier wird zusätzlich ein Default Wert 60 gesetzt:
${__P(duration,60)}


Leider bietet der Jmeter-Ant Task nicht diese Flexibilität oder ich habe sich nicht finden können. Alternativ kann man in Ant den Jmeter Testplan direkt modifizieren. Der Testplan ist eine XML Datei  die man via Ant XML Task modifizieren kann:
<?xml version="1.0" encoding="UTF-8" ?>
<project name="jmeter">
 <description>
  This file contains private task for: Load generation with jemeter.
 </description>
  
   <property name="jmeter-home" value="${env.JMETER_HOME}" />

   <path id="ant.xml.classpath">
  <fileset dir="antlibs">
   <include name="xmltask.jar"/>
  </fileset>
 </path>

 <taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask" classpathref="ant.xml.classpath"/>
 
 <target name="load_jmeter" >
  <echot level="info">Generate synthetic load with JMeter.</echot>
  <fail message="JMeter Home not set. Use evirmoment variable JMETER_HOME or property jmeter-home in file: ${setupfile}">
   <condition>
    <not>
     <or>
      <isset property="env.JMETER_HOME" />
      <isset property="jmeter-home" />
     </or>
    </not>
   </condition>
  </fail>
  <!-- ant-jmeter.jar comes with jmeter, be sure this is the release you have -->
  <path id="ant.jmeter.classpath">
   <fileset dir="${jmeter-home}/extras">
    <include name="ant-jmeter-*.jar"/>
   </fileset>
  </path> 
  <taskdef name="jmeter" classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask" classpathref="ant.jmeter.classpath" />
  <xmltask source="src/${load.jmeter.testplan.file}" dest="results/${load.jmeter.testplan.file}">
   <replace path="//stringProp[@name='RunTime.seconds']/text()" withText="${load.duration}" />
  </xmltask>
  <copy file="src/urls.txt" todir="results" />
  
  <jmeter jmeterhome="${jmeter-home}" resultlogdir="results/jtl" testplan="results/${load.jmeter.testplan.file}">
   <property name="jmeter.save.saveservice.output_format" value="xml"/>
  </jmeter>
 </target>

</project>

Dienstag, 12. November 2013

Bessere Ant Scripte schreiben

Ant Scripte (aka Build Files) haben die Neigung komplex zu werden. Damit einher gehen geringere Lesbarkeit und Wartbarkeit der Scripte. Dieses Phänomen betrifft neben Ant auch andere Build-Werkzeuge wie Rake oder Gradel. Ein Ausweg ist das Wechsel zu Maven, das mit seinem "Convention over Configuration" Ansatz dieses Problem umgeht. Leider müssen dann oft bestehende Build-Prozesse massiv geändert werden, damit sie den Maven Konventionen entsprechen. Dieser Aufwand wird aus verschiedenen Gründen von vielen Entwicklern gescheut. Welche Gründe das sind würde diesen Artikel sprengen und ist ein neues Thema.
Ein zweiter Weg ist es die Ant Scripte besser, lesbarer zu gestalten. Dabei helfen folgende Dinge:

  1. Ersetzen von Ant Tasks durch Ant Makros
  2. Benutzung von FAIL
  3. Auslagen von Funktionen in andere Ant Scripte oder in externe Scripte (BASH) oder Programme
Das Ersetzen von Task durch Makros hat den Vorteil, dass man die zu verarbeitenden Properties als Parameter dem Makro übergeben kann. Dadurch wird sichtbar, was vorher im Verborgenen war. Zusätzlich lässt sich eine einfache Verarbeitung (Default Werte) bzw. Prüfung der Parameter durchführen.

Hier ein Beispiel für ein kleines Makro, welches ein Echo mit Timestamp zur Verfügung stellt:

 <macrodef name="echot" >
  <text name="text"/>
  <attribute name="level" default="warning"/>
  <sequential>
   <tstamp>
    <format property="current.time" pattern="yyyy-MM-dd HH:mm:ss" />
   </tstamp>
   <echo level="@{level}" message="${current.time} @{text}" />
  </sequential>
 </macrodef>

Links zum Thema: