blob: 609ceee315ed037032337c0557d40cfbc1a03b32 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.openejb.config.rules;
import static org.apache.openejb.util.URLs.toFile;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.HashSet;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Map.Entry;
import org.apache.openejb.config.rules.KeysAnnotationVisitor.ClassInfo;
import org.apache.openejb.config.rules.KeysAnnotationVisitor.MethodInfo;
import org.apache.xbean.asm.ClassReader;
import org.apache.xbean.asm.ClassWriter;
import org.codehaus.swizzle.confluence.Confluence;
import org.codehaus.swizzle.confluence.Page;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* This class is not meant to be a container for tests. Its an audit tool which generates a report of how many of the keys listed in
* org.apache.openejb.config.rules.Messages.properties have tests written for them
*/
public class ValidationKeysAuditorTest {
private static Set<String> allKeys;
@BeforeClass
public static void init() {
ResourceBundle bundle = ResourceBundle.getBundle("org.apache.openejb.config.rules.Messages");
allKeys = bundle.keySet();
allKeys = stripPrefixes(allKeys);
}
@Test
public void audit() {
URL resource = ValidationKeysAuditorTest.class.getResource("/org/apache/openejb/config/rules/Keys.class");
File file = toFile(resource);
KeysAnnotationVisitor visitor = new KeysAnnotationVisitor();
dir(file.getParentFile(), visitor);
try {
generateReport(file, visitor);
String confluenceOutput = generateConfluenceReport(file, visitor);
writeToConfluence(confluenceOutput);
} catch (IOException e) {
// ignore it
e.printStackTrace();
}
}
/**
* This method will write to confluence only if you supply the system properties confluenceUsername and confluencePassword example usage mvn test
* -Dtest=ValidationKeysAuditorTest -DconfluenceUsername=<<your username>> -DconfluencePassword=<<your password>>
*
* @param confluenceOutput
*/
private void writeToConfluence(String confluenceOutput) {
String username = System.getProperty("confluenceUsername");
String password = System.getProperty("confluencePassword");
if (validate(username) && validate(password)) {
try {
String endpoint = "https://cwiki.apache.org/confluence/rpc/xmlrpc";
Confluence confluence = new Confluence(endpoint);
confluence.login(username, password);
Page page = confluence.getPage("OPENEJB", "Validation Keys Audit Report");
page.setContent(confluenceOutput);
confluence.storePage(page);
confluence.logout();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private boolean validate(String str) {
if (str == null)
return false;
if ("true".equalsIgnoreCase(str))
return false;
if ("false".equalsIgnoreCase(str))
return false;
if (str.trim().length() == 0)
return false;
return true;
}
private String generateConfluenceReport(File file, KeysAnnotationVisitor visitor) throws IOException {
StringBuilder output = new StringBuilder();
String newLine = System.getProperty("line.separator");
Set<String> testedKeys = getTestedKeys(visitor.classInfos);
Set<String> untestedKeys = getUntestedKeys(testedKeys);
untestedKeys = new TreeSet<String>(untestedKeys);// sort the keys
prepareConfluenceSummary(untestedKeys, output, newLine);
prepareConfluenceUntestedKeyList(untestedKeys, output, newLine);
prepareConfluenceTestedKeysDetailedReport(visitor.classInfos, output, newLine);
writeToFile(file, output, "ValidationKeyAuditReportConfluence.txt");
return output.toString();
}
private void prepareConfluenceTestedKeysDetailedReport(HashSet<ClassInfo> classInfos, StringBuilder output, String newLine) {
TreeMap<String, TreeSet<String>> info = new TreeMap<String, TreeSet<String>>();
output.append("h2.List of keys which have been tested.").append(newLine);
output.append("{table-plus:autoNumber=true}").append(newLine);
output.append("|| Key | Method which tests the key ||").append(newLine);
for (ClassInfo classInfo : classInfos) {
HashSet<MethodInfo> methuds = classInfo.methuds;
for (MethodInfo methodInfo : methuds) {
HashSet<String> keys = methodInfo.keys;
for (String key : keys) {
if (!info.containsKey(key)) {
TreeSet<String> set = new TreeSet<String>();
set.add(createConfluenceLink(classInfo.clazz + "." + methodInfo.methud + "()"));
info.put(key, set);
} else {
TreeSet<String> set = info.get(key);
set.add(createConfluenceLink(classInfo.clazz + "." + methodInfo.methud + "()"));
}
}
}
}
Set<Entry<String, TreeSet<String>>> entrySet = info.entrySet();
for (Entry<String, TreeSet<String>> entry : entrySet) {
String key = entry.getKey();
output.append("| ").append(key).append(" | ");
int count = 0;
TreeSet<String> values = entry.getValue();
for (String value : values) {
if (count > 0) {
output.append(" \\\\ ");
}
output.append(value);
++count;
}
output.append(newLine);
}
output.append("{table-plus}").append(newLine);
}
private String createConfluenceLink(String string) {
String link = "[" + string + " | ";
String temp = string.substring(0, string.lastIndexOf("."));
String location = "https://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/" + temp + ".java?revision=HEAD&view=markup ]";
link = link + location;
return link;
}
private void prepareConfluenceUntestedKeyList(Set<String> untestedKeys, StringBuilder output, String newLine) {
output.append("{table-plus:autoNumber=true}").append(newLine);
output.append("|| h2.List of untested keys \\\\ ||").append(newLine);
for (String key : untestedKeys) {
output.append(" | ").append(key).append(" | ").append(newLine);
}
output.append("{table-plus}").append(newLine);
}
private void prepareConfluenceSummary(Set<String> untestedKeys, StringBuilder output, String newLine) {
int total = allKeys.size();
int untested = untestedKeys.size();
int tested = total - untested;
double coverage = (((tested + 0.0) / (total + 0.0)) * 100);
output.append("{warning:title=Warning}This page is auto-generated. Any manual changes would be over-written the next time this page is regenerated{warning}").append(
newLine);
output.append("{info:title=Audit Result}h2.Out of a total of " + total + " keys, " + tested + " have been tested. Test coverage for keys is " + coverage + " %.{info}")
.append(newLine);
}
private void generateReport(File file, KeysAnnotationVisitor visitor) throws IOException {
StringBuilder output = new StringBuilder();
String newLine = System.getProperty("line.separator");
Set<String> testedKeys = getTestedKeys(visitor.classInfos);
Set<String> untestedKeys = getUntestedKeys(testedKeys);
untestedKeys = new TreeSet<String>(untestedKeys);// sort the keys
prepareSummary(untestedKeys, output, newLine);
prepareUntestedKeyList(untestedKeys, output, newLine);
prepareTestedKeysDetailedReport(visitor.classInfos, output, newLine);
writeToFile(file, output, "ValidationKeyAuditReport.txt");
}
private void prepareTestedKeysDetailedReport(HashSet<ClassInfo> classInfos, StringBuilder output, String newLine) throws IOException {
output.append("================================================================================================").append(newLine);
output.append("List of all keys tested. Next to each is the the test method which tests the key").append(newLine);
output.append("================================================================================================").append(newLine);
TreeMap<String, TreeSet<String>> info = new TreeMap<String, TreeSet<String>>();
for (ClassInfo classInfo : classInfos) {
HashSet<MethodInfo> methuds = classInfo.methuds;
for (MethodInfo methodInfo : methuds) {
HashSet<String> keys = methodInfo.keys;
for (String key : keys) {
if (!info.containsKey(key)) {
TreeSet<String> set = new TreeSet<String>();
set.add(classInfo.clazz + "." + methodInfo.methud + "()");
info.put(key, set);
} else {
TreeSet<String> set = info.get(key);
set.add(classInfo.clazz + "." + methodInfo.methud + "()");
}
}
}
}
Set<Entry<String, TreeSet<String>>> entrySet = info.entrySet();
for (Entry<String, TreeSet<String>> entry : entrySet) {
String key = entry.getKey();
output.append(key).append(" --> ");
int count = 0;
TreeSet<String> values = entry.getValue();
for (String value : values) {
if (count > 0) {
// put as many spaces as there are characters in the key to indent and align multiple values for the same key
StringBuilder spaces = new StringBuilder();
for(int i=0;i<key.length();i++){
spaces.append(" ");
}
output.append(spaces).append(" --> ");
}
output.append(value).append(newLine);
++count;
}
}
}
private void writeToFile(File file, StringBuilder output, String fileName) throws IOException {
File surefireReports = new File(dir(file), "surefire-reports");
if (!surefireReports.exists()) {
surefireReports.mkdir();
}
File auditResults = new File(surefireReports, fileName);
BufferedWriter bw = null;
try {
FileWriter writer = new FileWriter(auditResults);
bw = new BufferedWriter(writer);
bw.append(output.toString());
} finally {
bw.flush();
bw.close();
}
}
private void prepareUntestedKeyList(Set<String> untestedKeys, StringBuilder output, String newLine) {
output.append("================================================================================================").append(newLine);
output.append("List of all keys which have not been tested yet.").append(newLine);
output.append("================================================================================================").append(newLine);
for (String key : untestedKeys) {
output.append(key).append(newLine);
}
}
private Set<String> getUntestedKeys(Set<String> testedKeys) {
Set<String> untestedKeys = new HashSet<String>();
for (String key : allKeys) {
if (!testedKeys.contains(key))
untestedKeys.add(key);
}
return untestedKeys;
}
private Set<String> getTestedKeys(HashSet<ClassInfo> classInfos) {
Set<String> testedKeys = new HashSet<String>();
for (ClassInfo classInfo : classInfos) {
HashSet<MethodInfo> methuds = classInfo.methuds;
for (MethodInfo methodInfo : methuds) {
testedKeys.addAll(methodInfo.keys);
}
}
return testedKeys;
}
private static Set<String> stripPrefixes(Set<String> allKeys) {
Set<String> keys = new HashSet<String>();
for (String key : allKeys) {
key = key.substring(key.indexOf(".") + 1);
if (!keys.contains(key))
keys.add(key);
}
return keys;
}
private void prepareSummary(Set<String> untestedKeys, StringBuilder output, String newLine) {
int total = allKeys.size();
int untested = untestedKeys.size();
int tested = total - untested;
double coverage = (((tested + 0.0) / (total + 0.0)) * 100);
output.append("================================================================================================").append(newLine);
output.append("Out of a total of " + total + " keys, " + tested + " have been tested. Test coverage for keys is " + coverage + " %.").append(newLine);
output.append("================================================================================================").append(newLine);
}
private File dir(File file) {
file = file.getParentFile();
while (file.isDirectory()) {
if (!file.getName().equals("target")) {
file = file.getParentFile();
continue;
}
return file;
}
return null;
}
private static void dir(File dir, KeysAnnotationVisitor visitor) {
for (File file : dir.listFiles()) {
if (file.isDirectory()) {
dir(file, visitor);
} else if (file.getName().endsWith(".class")) {
file(file, visitor);
}
}
}
private static void file(File file, KeysAnnotationVisitor visitor) {
try {
FileInputStream in = new FileInputStream(file);
try {
ClassReader classReader = new ClassReader(in);
classReader.accept(visitor, ClassWriter.COMPUTE_MAXS);
} finally {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}