2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.ci.tests.run;
23 import org.apache.log4j.PropertyConfigurator;
24 import org.junit.runner.JUnitCore;
25 import org.junit.runner.Result;
26 import org.junit.runner.notification.Failure;
27 import org.openecomp.sdc.ci.tests.api.AttSdcTest;
28 import org.openecomp.sdc.ci.tests.config.Config;
29 import org.openecomp.sdc.ci.tests.utils.Utils;
30 import org.openecomp.sdc.ci.tests.utils.general.FileUtils;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
35 import java.io.FileNotFoundException;
36 import java.io.IOException;
37 import java.lang.annotation.Annotation;
38 import java.lang.reflect.Method;
39 import java.net.URISyntaxException;
41 import java.text.SimpleDateFormat;
42 import java.util.ArrayList;
43 import java.util.Calendar;
44 import java.util.Enumeration;
45 import java.util.List;
46 import java.util.concurrent.atomic.AtomicBoolean;
47 import java.util.jar.JarEntry;
48 import java.util.jar.JarFile;
50 public class StartTest2backup {
52 private List<Class<? extends AttSdcTest>> testClasses = new ArrayList<Class<? extends AttSdcTest>>();
53 public static long timeOfTest = 0;
55 public static boolean debug = false;
57 public static AtomicBoolean loggerInitialized = new AtomicBoolean(false);
59 protected static Logger logger = null;
61 public static void main(String[] args) {
63 String debugEnabled = System.getProperty("debug");
64 if (debugEnabled != null && debugEnabled.equalsIgnoreCase("true")) {
67 System.out.println("Debug mode is " + (debug ? "enabled" : "disabled"));
73 config = Utils.getConfig();
74 } catch (FileNotFoundException e) {
79 logger.error("Failed to configuration file of ci tests.");
83 List<String> packagesToRun = config.getPackages();
84 if (packagesToRun == null || true == packagesToRun.isEmpty()) {
85 logger.error("No package was configured to be executed.");
88 StartTest2backup tests = new StartTest2backup();
90 boolean stopOnClassFailure = false;
91 String stopOnClassFailureStr = System.getProperty("stopOnClassFailure");
92 if (stopOnClassFailureStr != null && stopOnClassFailureStr.equalsIgnoreCase("true")) {
93 stopOnClassFailure = true;
95 Boolean stopOnClassFailureObj = config.isStopOnClassFailure();
96 if (stopOnClassFailureObj != null) {
97 stopOnClassFailure = stopOnClassFailureObj.booleanValue();
101 tests.start(packagesToRun, stopOnClassFailure);
104 public StartTest2backup() {
105 logger = LoggerFactory.getLogger(StartTest2backup.class.getName());
108 public static void enableLogger() {
110 if (false == loggerInitialized.get()) {
112 loggerInitialized.set(true);
114 String log4jPropsFile = System.getProperty("log4j.configuration");
115 if (System.getProperty("os.name").contains("Windows")) {
116 String logProps = "src/main/resources/ci/conf/log4j.properties";
117 if (log4jPropsFile == null) {
118 System.setProperty("targetlog", "target/");
119 log4jPropsFile = logProps;
123 PropertyConfigurator.configureAndWatch(log4jPropsFile);
128 public void start(List<String> packages, boolean exitOnFailure) {
130 boolean success = true;
131 StringBuilder results = new StringBuilder();
134 if (packages == null) {
138 for (String packageName : packages) {
139 // List<Class> classesForPackage =
140 // getClassesForPackage("org.openecomp.sdc.ci.tests.execute");
141 List<Class> classesForPackage = getClassesForPackage(packageName);
142 if (classesForPackage != null && false == classesForPackage.isEmpty()) {
143 for (Class testUnit : classesForPackage) {
144 testClasses.add(testUnit);
149 System.out.println(testClasses);
151 // tsetClasses.add(LogValidatorTest.class);
152 // tsetClasses.add(AttNorthboundTest.class);
155 "<Html><head><style>th{background-color: gray;color: white;height: 30px;}td {color: black;height: 30px;}.fail {background-color: #FF5555;width: 100px;text-align: center;}.success {background-color: #00FF00;width: 100px;text-align: center;}.name {width: 200px;background-color: #F0F0F0;}.message {width: 300px;background-color: #F0F0F0;}</style></head><body>");
157 Calendar calendar = Calendar.getInstance();
158 timeOfTest = calendar.getTimeInMillis();
159 SimpleDateFormat date_format = new SimpleDateFormat("MMM dd yyyy HH:mm:ss");
160 results.append("<br/><h2> This report generated on " + date_format.format(calendar.getTime()) + "</h2><br/>");
162 results.append("<table>");
163 addTableHead(results);
165 int size = testClasses.size();
168 int totalRunTests = 0;
169 int totalFailureTests = 0;
170 int totalIgnoreTests = 0;
171 int numOfFailureClasses = 0;
172 for (Class<? extends AttSdcTest> testClass : testClasses) {
176 StringBuilder builder = new StringBuilder();
177 String str = "***************************************************************************";
178 builder.append(str + "\n");
179 String current = "class " + index + "/" + size + " failure(" + numOfFailureClasses + ") + RUNS("
180 + totalRunTests + ")" + " FAILURES(" + totalFailureTests + ") IGNORED(" + totalIgnoreTests + ")";
181 int interval = ((str.length() - current.length() - 2) / 2);
182 String substring = str.substring(0, interval);
183 builder.append(substring + " " + current + " " + substring + "\n");
184 builder.append(str + "\n");
186 System.out.println(builder.toString());
188 logger.debug(builder.toString());
189 logger.debug("Going to run test class {}", testClass.getName());
191 result = JUnitCore.runClasses(testClass);
192 if (result.wasSuccessful() == false) {
193 numOfFailureClasses++;
195 logger.debug("Test class {} finished {}",testClass.getName(),(result.wasSuccessful() ? "OK." : " WITH ERROR."));
196 List<Failure> failures = result.getFailures();
197 if (failures != null) {
198 for (Failure failure : failures) {
199 logger.error("Test class {} failure test {}-{}",testClass.getName(),failure.getTestHeader(),failure.getTrace());
202 int runsPerClass = result.getRunCount();
203 int failuresPerClass = result.getFailureCount();
204 int ignoredPerClass = result.getIgnoreCount();
206 totalRunTests += runsPerClass;
207 totalFailureTests += failuresPerClass;
208 totalIgnoreTests += ignoredPerClass;
210 logger.debug("class {} Failed tests {} %",testClass.getName(),(failuresPerClass * 1.0) / runsPerClass * 100);
211 logger.debug("class {} Ignored tests {} %",testClass.getName(),(ignoredPerClass * 1.0) / runsPerClass * 100);
213 // List<Failure> failures = result.getFailures();
214 // if (failures != null) {
215 // for (Failure failure : failures) {
216 // System.err.println("9999999999" + failure.getTestHeader());
220 addUnitTestResult(results, testClass, result);
221 success &= result.wasSuccessful();
223 if (numOfFailureClasses > 0) {
224 // if (exitOnFailure) {
231 results.append("</table>");
232 results.append("<br/><h2> Tests Summary: </h2><br/>");
233 results.append("Total Runs : " + totalRunTests + "<br/>");
234 results.append("Total Failure : " + totalFailureTests + "<br/>");
235 results.append("Total: " + totalFailureTests + "/" + totalRunTests + "<br/>");
236 results.append("</html>");
238 FileUtils.writeToFile(Config.instance().getOutputFolder() + File.separator + Config.instance().getReportName(),
242 System.out.println("FAILURE");
243 logger.error("Failure tests : {} %",((totalFailureTests + totalIgnoreTests) * 1.0) / (totalRunTests + totalIgnoreTests));
244 logger.error("Ignored tests : {} %",(totalIgnoreTests * 1.0) / (totalRunTests + totalIgnoreTests));
248 System.out.println("SUCCESS");
251 private List<Class> getClassesForPackage(String pkgname) {
253 List<Class> classes = new ArrayList<Class>();
255 // Get a File object for the package
256 File directory = null;
258 String relPath = pkgname.replace('.', '/');
260 // System.out.println("ClassDiscovery: Package: " + pkgname +
261 // " becomes Path:" + relPath);
263 URL resource = ClassLoader.getSystemClassLoader().getResource(relPath);
265 // System.out.println("ClassDiscovery: Resource = " + resource);
266 if (resource == null) {
267 throw new RuntimeException("No resource for " + relPath);
269 fullPath = resource.getFile();
270 // System.out.println("ClassDiscovery: FullPath = " + resource);
273 System.out.println("fullPath is " + fullPath);
277 directory = new File(resource.toURI());
278 } catch (URISyntaxException e) {
279 throw new RuntimeException(
280 pkgname + " (" + resource
281 + ") does not appear to be a valid URL / URI. Strange, since we got it from the system...",
283 } catch (IllegalArgumentException e) {
286 // System.out.println("ClassDiscovery: Directory = " + directory);
288 if (directory != null && directory.exists()) {
290 // Get the list of the files contained in the package
291 String[] files = directory.list();
292 for (int i = 0; i < files.length; i++) {
294 // we are only interested in .class files
295 if (files[i].endsWith(".class") && false == files[i].contains("$")) {
297 // removes the .class extension
298 String className = pkgname + '.' + files[i].substring(0, files[i].length() - 6);
300 // System.out.println("ClassDiscovery: className = " +
304 System.out.println("ClassDiscovery: className = " + className);
308 Class clas = Class.forName(className);
309 boolean isAddToRun = false;
310 Method[] methods = clas.getMethods();
311 for (Method method : methods) {
312 Annotation[] anns = method.getAnnotations();
313 for (Annotation an : anns) {
314 if (an.annotationType().getSimpleName().equalsIgnoreCase("Test")) {
322 } catch (ClassNotFoundException e) {
323 throw new RuntimeException("ClassNotFoundException loading " + className);
329 String jarPath = fullPath.replaceFirst("[.]jar[!].*", ".jar").replaceFirst("file:", "");
332 System.out.println("jarPath is " + jarPath);
335 JarFile jarFile = new JarFile(jarPath);
336 Enumeration<JarEntry> entries = jarFile.entries();
337 while (entries.hasMoreElements()) {
338 JarEntry entry = entries.nextElement();
339 String entryName = entry.getName();
340 if (entryName.startsWith(relPath) && entryName.length() > (relPath.length() + "/".length())) {
342 // System.out.println("ClassDiscovery: JarEntry: " +
344 String className = entryName.replace('/', '.').replace('\\', '.').replace(".class", "");
346 // System.out.println("ClassDiscovery: className = " +
349 if (false == className.contains("$")) {
352 System.out.println("ClassDiscovery: className = " + className);
356 Class clas = Class.forName(className);
357 boolean isAddToRun = false;
358 Method[] methods = clas.getMethods();
359 for (Method method : methods) {
360 Annotation[] anns = method.getAnnotations();
361 for (Annotation an : anns) {
362 if (an.annotationType().getSimpleName().equalsIgnoreCase("Test")) {
370 } catch (ClassNotFoundException e) {
371 throw new RuntimeException("ClassNotFoundException loading " + className);
378 } catch (IOException e) {
379 throw new RuntimeException(pkgname + " (" + directory + ") does not appear to be a valid package", e);
385 private void addTableHead(StringBuilder results) {
386 results.append("<tr>");
387 results.append("<th>").append("Unit Test").append("</th>");
388 results.append("<th>").append("Result").append("</th>");
389 results.append("</tr>");
392 private void addUnitTestResult(StringBuilder results, Class<? extends AttSdcTest> testClass,
393 Result unitTestResult) {
395 boolean isSuccess = unitTestResult.wasSuccessful();
397 String result = (isSuccess) ? "success" : "fail";
398 String fileName = FileUtils.getFileName(testClass.getName());
399 results.append("<tr>");
400 // results.append("<td>").append(FileUtils.getFileName(testClass.getName())).append("</td>");
401 results.append("<td class=\"name\">")
402 .append("<a href=\"" + fileName + timeOfTest + ".html\">" + fileName + "</a>").append("</td>");
403 results.append("<td class=\"" + result + "\">").append(result).append("</td>");
404 results.append("</tr>");