2. Vincent Massol
• Speaker Bio
•
CTO XWiki SAS
•
•
XWiki (community-driven open source project)
Past: Maven, Apache Cargo, Apache Cactus, Pattern Testing
•
•
•
LesCastCodeurs podcast
Creator of OSSGTP open source group in Paris
3 books: JUnit in Action, Maven: A Developer’s Notebook, BBWM
• Your Projects
• Other Credentials:
4. The XWiki project in summary
•
•
•
•
•
•
•
9 years old
28 active
committers
7 committers
do 80% of
work
700K NCLOC
11 commits/day
16 mails/day
65% TPC
5. Examples of Quality actions
•
•
•
•
•
•
•
•
Coding rules (Checkstyle, ...)
Test coverage
Track bugs
Don’t use Commons Lang 2.x
Use SLF4J and don’t draw Log4J/
JCL in dependencies
Automated build
Automated unit tests
Stable automated functional
tests
•
•
•
•
•
•
•
•
•
Ensure API stability
Code reviews
License header checks
Release with Java 6
Ensure javadoc exist
Prevent JAR hell
Release often (every 2 weeks)
Collaborative design
Test on supported
environments (DB & Browsers)
13. API Stability - Young APIs
/**!
* ...!
* @since 5.0M1!
*/!
@Unstable(<optional explanation>)!
public EntityReference createEntityReference(String name,...)!
{!
...!
}
+ max duration for keeping the annotation!
14. API Stability - Next steps
• Annotation or package for SPI?
• Better define when to use the @Unstable annotation
• Not possible to add a new method to an existing Interface
•
Java 8 and Virtual Extension/Defender methods
interface TestInterface {!
public void testMe();!
public void newMethod() default {!
System.out.println("Default from interface");!
}!
}
18. Surprising results...
• Commons Beanutils bundles some classes from Commons Collections,
•
•
•
apparently to avoid drawing a dependency to it...
Xalan bundles a lot of other projects (org/apache/xml/**, org/apache/
bcel/**, JLex/**, java_cup/**, org/apache/regexp/**). In addition, it even
has these jars in its source tree without any indication about their
versions...
stax-api, geronimo-stax-api_1.0_spec and xml-apis all draw
javax.xml.stream.* classes
xmlbeans and xml-apis draw incompatible versions of org.w3c.dom.*
classes
14 exceptions in total!
19. Maven: dependency version issue
<dependencies>!
<dependency>!
Will run logback 0.9.9
<groupId>org.slf4j</groupId>!
with slf4J-api 1.4.0
instead of 1.5.0!
<artifactId>slf4j-api</artifactId>!
<version>1.4.0</version>!
</dependency>!
<dependency>!
<groupId>ch.qos.logback</groupId>!
<artifactId>logback-classic</artifactId>!
<version>0.9.9</version>!
<!-- Depends on org.slf4j:slf4j-api:1.5.0 -->!
</dependency>!
</dependencies>
22. The Problem
More bugs reported, overall quality
goes down and harder to debug
software
23. Use Jacoco to fail the build
<plugin>!
<groupId>org.jacoco</groupId>!
<artifactId>jacoco-maven-plugin</artifactId>!
<executions>!
<execution><id>jacoco-prepare</id>!
<goals><goal>prepare-agent</goal></goals>!
</execution>!
<execution><id>jacoco-check</id>!
<goals><goal>check</goal></goals>!
</execution>!
</executions>!
<configuration>!
<check>!
<instructionRatio>${xwiki.jacoco.instructionRatio}</...>!
</check>}
24. Strategy
• When devs add code (and thus tests),
•
•
increase the TPC percentage
Put the Jacoco check in “Quality” Maven
Profile
Have a CI job to execute that profile
regularly
•
About 15% overhead compared to build
without checks
• “Cheat mode”: Add easier-to-write test
25. Quizz Time!
Step 1: Building on my local machine gives the following:
[INFO] --- jacoco-maven-plugin:0.6.2.201302030002:check (jacoco-check)
[INFO] All coverage checks have been met.
Step 2: Building on the CI machine gave:
[INFO] --- jacoco-maven-plugin:0.6.2.201302030002:check (jacoco-check) !
[WARNING] Insufficient code coverage for INSTRUCTION: 75.52% < 75.53%
Non determinism! Why?
26. Quizz Answer
... because the JVM is non deterministic!
private Map componentEntries = new ConcurrentHashMap();!
...!
for (Map.Entry entry : componentEntries.entrySet())!
{!
if (entry.getValue().instance == component) {!
key = entry.getKey();!
oldDescriptor = entry.getValue().descriptor;!
break;!
}!
}
28. The Problem
Too many false positives leading to
developers not paying attention to CI
emails anymore... leading to failing
software
29. False positives examples
• The JVM has crashed
• VNC is down (we run Selenium tests)
• Browser crash (we run Selenium tests)
• Git connection issue
• Machine slowness (if XWiki cannot start under 2 minutes then it
•
•
means the machine has some problems)
Nexus is down (we deploy our artifacts to a Nexus repository)
Connection issue (Read time out)
30. Step 1: Groovy PostBuild Plugin (1/2)
def messages = [!
[".*A fatal error has been detected by the Java Runtime Environment.*",!
"JVM Crash", "A JVM crash happened!"],!
[".*Error: cannot open display: :1.0.*",!
"VNC not running", "VNC connection issue!"],!
...!
]
def shouldSendEmail = true!
messages.each { message ->!
if (manager.logContains(message.get(0))) {!
manager.addWarningBadge(message.get(1))!
manager.createSummary("warning.gif").appendText(...)!
manager.buildUnstable()!
shouldSendEmail = false!
}!
}
31. Step 1: Groovy PostBuild Plugin (2/2)
... continued from previous slide...!
!
if (!shouldSendEmail) {!
def pa = new ParametersAction([!
new BooleanParameterValue("noEmail", true)!
])!
manager.build.addAction(pa)!
}
32. Step 2: Mail Ext Plugin
Pre-send Script
import hudson.model.*!
!
build.actions.each { action ->!
if (action instanceof ParametersAction) {!
if (action.getParameter("noEmail")) {!
cancel = true!
}!
}!
}
33. Results
+ use the Scriptler plugin to automate configuration for all jobs
35. The Problem
Bugs increasing, even simple to fix
ones, devs focusing too much on new
features (i.e. scope creep) vs fixing
what exists
Bugs created vs closed
36. Bug Fixing Day
• Every Thursday
• Goal is to close the max number of bugs
• Triaging: Can be closed with Won’t fix, Duplicate,
•
•
•
Cannot Reproduce, etc
Close low hanging fruits in priority
Started with last 365 days then with last 547 days
and currently with last 1500 days (we need to
catch up with 22 bugs!)
Today is BFD#40 (and I’m missing it!)
40. Parting words
• Slowly add new quality check over time
• Everyone must be on board
• Favor Active Quality (i.e. make the build fail) over Passive checks
• Be ready to adapt/remove checks if found not useful enough
• Quality brings some risks:
•
•
Potentially less committers for your project (especially open source)
Project seen as “less fun”
41. Be proud of your Quality!
“I have offended God and
mankind because my work didn't
reach the quality it should have.”
Leonardo da Vinci, on his death bed