blob: 12c0763e289b1a6350497ddda220743dc50a7a3f [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 org.apache.openejb.config.rules.KeysAnnotationVisitor.ClassInfo;
import org.apache.openejb.config.rules.KeysAnnotationVisitor.MethodInfo;
import org.apache.openejb.loader.IO;
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;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import static org.apache.openejb.util.URLs.toFile;
/**
* 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() {
final ResourceBundle bundle = ResourceBundle.getBundle("org.apache.openejb.config.rules.Messages");
allKeys = bundle.keySet();
allKeys = stripPrefixes(allKeys);
}
@Test
public void audit() {
final URL resource = ValidationKeysAuditorTest.class.getResource("/org/apache/openejb/config/rules/Keys.class");
final File file = toFile(resource);
final KeysAnnotationVisitor visitor = new KeysAnnotationVisitor();
dir(file.getParentFile(), visitor);
try {
generateReport(file, visitor);
final 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(final String confluenceOutput) {
final String username = System.getProperty("confluenceUsername");
final String password = System.getProperty("confluencePassword");
if (validate(username) && validate(password)) {
try {
final String endpoint = "https://cwiki.apache.org/confluence/rpc/xmlrpc";
final Confluence confluence = new Confluence(endpoint);
confluence.login(username, password);
final 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(final 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(final File file, final KeysAnnotationVisitor visitor) throws IOException {
final StringBuilder output = new StringBuilder();
final String newLine = System.getProperty("line.separator");
final 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(final HashSet<ClassInfo> classInfos, final StringBuilder output, final String newLine) {
final 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 (final ClassInfo classInfo : classInfos) {
final HashSet<MethodInfo> methuds = classInfo.methuds;
for (final MethodInfo methodInfo : methuds) {
final HashSet<String> keys = methodInfo.keys;
for (final String key : keys) {
if (!info.containsKey(key)) {
final TreeSet<String> set = new TreeSet<String>();
set.add(createConfluenceLink(classInfo.clazz + "." + methodInfo.methud + "()"));
info.put(key, set);
} else {
final TreeSet<String> set = info.get(key);
set.add(createConfluenceLink(classInfo.clazz + "." + methodInfo.methud + "()"));
}
}
}
}
final Set<Entry<String, TreeSet<String>>> entrySet = info.entrySet();
for (final Entry<String, TreeSet<String>> entry : entrySet) {
final String key = entry.getKey();
output.append("| ").append(key).append(" | ");
int count = 0;
final TreeSet<String> values = entry.getValue();
for (final String value : values) {
if (count > 0) {
output.append(" \\\\ ");
}
output.append(value);
++count;
}
output.append(newLine);
}
output.append("{table-plus}").append(newLine);
}
private String createConfluenceLink(final String string) {
String link = "[" + string + " | ";
final String temp = string.substring(0, string.lastIndexOf("."));
final 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(final Set<String> untestedKeys, final StringBuilder output, final String newLine) {
output.append("{table-plus:autoNumber=true}").append(newLine);
output.append("|| h2.List of untested keys \\\\ ||").append(newLine);
for (final String key : untestedKeys) {
output.append(" | ").append(key).append(" | ").append(newLine);
}
output.append("{table-plus}").append(newLine);
}
private void prepareConfluenceSummary(final Set<String> untestedKeys, final StringBuilder output, final String newLine) {
final int total = allKeys.size();
final int untested = untestedKeys.size();
final int tested = total - untested;
final 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 ").append(total).append(" keys, ").append(tested).append(" have been tested. Test coverage for keys is ").append(coverage).append(" %.{info}")
.append(newLine);
}
private void generateReport(final File file, final KeysAnnotationVisitor visitor) throws IOException {
final StringBuilder output = new StringBuilder();
final String newLine = System.getProperty("line.separator");
final Set<String> testedKeys = getTestedKeys(KeysAnnotationVisitor.classInfos);
Set<String> untestedKeys = getUntestedKeys(testedKeys);
untestedKeys = new TreeSet<String>(untestedKeys);// sort the keys
prepareSummary(untestedKeys, output, newLine);
prepareUntestedKeyList(untestedKeys, output, newLine);
prepareTestedKeysDetailedReport(KeysAnnotationVisitor.classInfos, output, newLine);
writeToFile(file, output, "ValidationKeyAuditReport.txt");
}
private void prepareTestedKeysDetailedReport(final HashSet<ClassInfo> classInfos, final StringBuilder output, final 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);
final TreeMap<String, TreeSet<String>> info = new TreeMap<String, TreeSet<String>>();
for (final ClassInfo classInfo : classInfos) {
final HashSet<MethodInfo> methuds = classInfo.methuds;
for (final MethodInfo methodInfo : methuds) {
final HashSet<String> keys = methodInfo.keys;
for (final String key : keys) {
if (!info.containsKey(key)) {
final TreeSet<String> set = new TreeSet<String>();
set.add(classInfo.clazz + "." + methodInfo.methud + "()");
info.put(key, set);
} else {
final TreeSet<String> set = info.get(key);
set.add(classInfo.clazz + "." + methodInfo.methud + "()");
}
}
}
}
final Set<Entry<String, TreeSet<String>>> entrySet = info.entrySet();
for (final Entry<String, TreeSet<String>> entry : entrySet) {
final String key = entry.getKey();
output.append(key).append(" --> ");
int count = 0;
final TreeSet<String> values = entry.getValue();
for (final 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
final 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(final File file, final StringBuilder output, final String fileName) throws IOException {
final File surefireReports = new File(dir(file), "surefire-reports");
if (!surefireReports.exists()) {
surefireReports.mkdir();
}
final File auditResults = new File(surefireReports, fileName);
BufferedWriter bw = null;
try {
final FileWriter writer = new FileWriter(auditResults);
bw = new BufferedWriter(writer);
bw.append(output.toString());
} finally {
if (bw != null) {
try {
bw.flush();
} catch (Throwable e) {
//Ignore
}
}
if (bw != null) {
try {
bw.close();
} catch (Throwable e) {
//Ignore
}
}
}
}
private void prepareUntestedKeyList(final Set<String> untestedKeys, final StringBuilder output, final 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 (final String key : untestedKeys) {
output.append(key).append(newLine);
}
}
private Set<String> getUntestedKeys(final Set<String> testedKeys) {
final Set<String> untestedKeys = new HashSet<String>();
for (final String key : allKeys) {
if (!testedKeys.contains(key))
untestedKeys.add(key);
}
return untestedKeys;
}
private Set<String> getTestedKeys(final HashSet<ClassInfo> classInfos) {
final Set<String> testedKeys = new HashSet<String>();
for (final ClassInfo classInfo : classInfos) {
final HashSet<MethodInfo> methuds = classInfo.methuds;
for (final MethodInfo methodInfo : methuds) {
testedKeys.addAll(methodInfo.keys);
}
}
return testedKeys;
}
private static Set<String> stripPrefixes(final Set<String> allKeys) {
final 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(final Set<String> untestedKeys, final StringBuilder output, final String newLine) {
final int total = allKeys.size();
final int untested = untestedKeys.size();
final int tested = total - untested;
final double coverage = (((tested + 0.0) / (total + 0.0)) * 100);
output.append("================================================================================================").append(newLine);
output.append("Out of a total of ").append(total).append(" keys, ").append(tested).append(" have been tested. Test coverage for keys is ").append(coverage).append(" %.").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(final File dir, final KeysAnnotationVisitor visitor) {
final File[] files = dir.listFiles();
if (files != null) {
for (final File file : files) {
if (file.isDirectory()) {
dir(file, visitor);
} else if (file.getName().endsWith(".class")) {
file(file, visitor);
}
}
}
}
private static void file(final File file, final KeysAnnotationVisitor visitor) {
try {
final InputStream in = IO.read(file);
try {
final ClassReader classReader = new ClassReader(in);
classReader.accept(visitor, ClassWriter.COMPUTE_MAXS);
} finally {
IO.close(in);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}