1 /** 2 * Copyright 2006-2017 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package org.objenesis.tck; 17 18 import org.objenesis.Objenesis; 19 import org.objenesis.ObjenesisSerializer; 20 import org.objenesis.ObjenesisStd; 21 22 import java.io.IOException; 23 import java.io.Serializable; 24 25 /** 26 * Command line launcher for Technology Compatibility Kit (TCK). 27 * 28 * @author Joe Walnes 29 * @see TCK 30 */ 31 public class Main { 32 33 private static class MockSuperClass { 34 private final boolean superConstructorCalled; 35 36 public MockSuperClass() { 37 superConstructorCalled = true; 38 } 39 40 public boolean isSuperConstructorCalled() { 41 return superConstructorCalled; 42 } 43 } 44 45 private static class MockClass extends MockSuperClass implements Serializable { 46 private static final long serialVersionUID = 1L; 47 48 private final boolean constructorCalled; 49 50 @SuppressWarnings("unused") 51 public MockClass() { 52 constructorCalled = true; 53 } 54 55 public boolean isConstructorCalled() { 56 return constructorCalled; 57 } 58 } 59 60 /** 61 * Main class of the TCK. Can also be called as a normal method from an application server. 62 * 63 * @param args No parameters are required 64 * @throws IOException When the TCK fails to read properties' files. 65 */ 66 public static void main(String[] args) throws IOException { 67 68 TextReporter reporter = new TextReporter(System.out, System.err); 69 70 boolean result = run(reporter); 71 72 reporter.printResult(result); 73 74 if(reporter.hasErrors()) { 75 System.exit(1); 76 } 77 } 78 79 /** 80 * Run the full test suite using standard Objenesis instances 81 * 82 * @param reporter result are recorded in the reporter 83 * @return if the parent constructor test was successful 84 */ 85 public static boolean run(Reporter reporter) { 86 runStandardTest(new ObjenesisStd(), reporter); 87 runSerializerTest(new ObjenesisSerializer(), reporter); 88 89 boolean result = runParentConstructorTest(new ObjenesisSerializer()); 90 return result; 91 } 92 93 /** 94 * Run the serializing suite on the provided Objenesis instance 95 * 96 * @param reporter result are recorded in the reporter 97 * @param objenesis Objenesis instance to test 98 */ 99 public static void runSerializerTest(Objenesis objenesis, Reporter reporter) { 100 runTest(objenesis, reporter, "Objenesis serializer", 101 "candidates/serializable-candidates.properties"); 102 } 103 104 /** 105 * Run the standard suite on the provided Objenesis instance 106 * 107 * @param reporter result are recorded in the reporter 108 * @param objenesis Objenesis instance to test 109 */ 110 public static void runStandardTest(Objenesis objenesis, Reporter reporter) { 111 runTest(objenesis, reporter, "Objenesis std", "candidates/candidates.properties"); 112 } 113 114 /** 115 * A special test making sure the first none serializable class no-args constructor is called 116 * 117 * @param objenesis Objenesis instance to test 118 * @return if the test was successful 119 */ 120 public static boolean runParentConstructorTest(Objenesis objenesis) { 121 try { 122 Object result = objenesis.newInstance(MockClass.class); 123 MockClass mockObject = (MockClass) result; 124 return mockObject.isSuperConstructorCalled() && !mockObject.isConstructorCalled(); 125 } 126 catch(Exception e) { 127 System.err.println("--- Not serializable parent constructor called as expected ---"); 128 e.printStackTrace(System.err); 129 return false; 130 } 131 } 132 133 /** 134 * Run a suite of tests (candidates) on the Objenesis instance, sending the results to the 135 * reporter 136 * 137 * @param objenesis Objenesis instance to test 138 * @param reporter result are recorded in the reporter 139 * @param description description of the ran suite 140 * @param candidates property file containing a list of classes to test (key) and their 141 * description (value) 142 */ 143 public static void runTest(Objenesis objenesis, Reporter reporter, String description, 144 String candidates) { 145 TCK tck = new TCK(); 146 tck.registerObjenesisInstance(objenesis, description); 147 148 CandidateLoader candidateLoader = new CandidateLoader(tck, Main.class.getClassLoader(), 149 new CandidateLoader.LoggingErrorHandler(System.err)); 150 151 try { 152 candidateLoader.loadFromResource(Main.class, candidates); 153 } 154 catch(IOException e) { 155 throw new RuntimeException(e); 156 } 157 158 tck.runTests(reporter); 159 } 160 161 } 162