| package org.eclipse.jst.validation.test.internal.registry; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.logging.Level; |
| |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.jem.util.logger.proxy.Logger; |
| import org.eclipse.jst.validation.test.BVTValidationException; |
| import org.eclipse.jst.validation.test.BVTValidationPlugin; |
| import org.eclipse.jst.validation.test.ValidationTypeEnum; |
| import org.eclipse.jst.validation.test.internal.util.BVTRunner; |
| import org.eclipse.jst.validation.test.setup.IBuffer; |
| import org.eclipse.wst.validation.internal.ConfigurationManager; |
| import org.eclipse.wst.validation.internal.GlobalConfiguration; |
| import org.eclipse.wst.validation.internal.TaskListUtility; |
| import org.eclipse.wst.validation.internal.VThreadManager; |
| import org.eclipse.wst.validation.internal.ValidatorMetaData; |
| import org.eclipse.wst.validation.internal.core.IFileDelta; |
| import org.eclipse.wst.validation.internal.operations.ValidatorSubsetOperation; |
| |
| public class ValidatorTestcase implements ITestcaseMetaData { |
| private String _pluginId = null; // The plugin id that has contributed this test case. |
| private ValidatorMetaData _vmd = null; |
| private MessageMetaData[] _messages = null; |
| private String _projectName = null; // the name of the project that this test case tests |
| private String[] _resourceNames = null; // the resources listed in the MessageMetaData of this test case. |
| private String _inputFileName = null; |
| private String _name = null; // the name of the test case |
| private boolean _visible = true; // Is this test case visible on the Test Collector menu |
| |
| public ValidatorTestcase(String pluginName, String project, ValidatorMetaData vmd, String inputFileName, boolean visible) { |
| _pluginId = pluginName; |
| _projectName = project; |
| _vmd = vmd; |
| _inputFileName = inputFileName; |
| _visible = visible; |
| } |
| |
| public boolean isVisible() { |
| return _visible; |
| } |
| |
| public String getDeclaringPluginId() { |
| return _pluginId; |
| } |
| |
| public String getProjectName() { |
| return _projectName; |
| } |
| |
| public IProject getProject() { |
| return TestcaseUtility.findProject(this); |
| } |
| |
| public String getInputFileName() { |
| return _inputFileName; |
| } |
| |
| /** |
| * Return the number of messages |
| */ |
| public int getNumMessages() { |
| return getMessages(ValidationTypeEnum.RUN_VALIDATION).size(); |
| } |
| |
| /** |
| * Return the list of messages that should be reported for the given build |
| * type. (e.g. if the validator does not support incremental validation, |
| * then instead of returning the list of expected messages, return an empty |
| * list.) |
| */ |
| public List getMessages(int buildType) { |
| // The messages need to be stored in a list instead of an array because |
| // the list is sorted before searching & displaying. |
| switch(buildType) { |
| case(ValidationTypeEnum.AUTO_VALIDATION): |
| case(ValidationTypeEnum.INCREMENTAL_VALIDATION): { |
| if(!getValidatorMetaData().isIncremental()) { |
| return Collections.EMPTY_LIST; |
| } |
| // Otherwise, return the default copy below. |
| break; |
| } |
| |
| case(ValidationTypeEnum.FULL_VALIDATION): { |
| if(!getValidatorMetaData().isFullBuild()) { |
| return Collections.EMPTY_LIST; |
| } |
| // Otherwise, return the default copy below. |
| break; |
| } |
| |
| case(ValidationTypeEnum.RUN_VALIDATION): |
| default: { |
| // Return the default copy below. |
| } |
| |
| } |
| |
| List copy = new ArrayList(); |
| for(int i=0; i<_messages.length; i++) { |
| copy.add(_messages[i]); |
| } |
| |
| return copy; |
| } |
| |
| // Return the resources in this project for which there is a message in this test case. |
| // No resource instance will be in the resource more than once. |
| public IResource[] getResources(IProject project) { |
| Set temp = new HashSet(); // use a set in case there is more than one message registered against a resource (don't want duplicates in the list). |
| String[] resourceNames = getResourceNames(); |
| for(int i=0; i<resourceNames.length; i++) { |
| String resourceName = resourceNames[i]; |
| IResource resource = project.findMember(resourceName); |
| if(resource != null) { |
| // resource exists |
| temp.add(resource); |
| } |
| } |
| |
| IResource[] result = new IResource[temp.size()]; |
| temp.toArray(result); |
| return result; |
| } |
| |
| public String[] getResourceNames() { |
| if(_resourceNames == null) { |
| _resourceNames = new String[_messages.length]; |
| for(int i=0; i<_messages.length; i++) { |
| _resourceNames[i] = _messages[i].getResource(); |
| } |
| } |
| return _resourceNames; |
| } |
| |
| /** |
| * When an empty TMD is used to test an operation, and the operation needs the IResource[] |
| * affected by the TMD to know whether or not the operation passes (i.e., one of the ValidatorSubsetOperation |
| * constructors takes an IResource[], and the IResource[] must not be empty or null), then |
| * this method is used to set the "resources" affected by the test case. |
| */ |
| public void setResourceNames(String[] resourceNames) { |
| _resourceNames = resourceNames; |
| } |
| |
| public void setMessages(MessageMetaData[] messages) { |
| // If messages are null, that means that the test case expects no validation errors. |
| _messages = ((messages == null) ? new MessageMetaData[0] : messages); |
| } |
| |
| public ValidatorMetaData getValidatorMetaData() { |
| return _vmd; |
| } |
| |
| public String getValidatorClass() { |
| return getValidatorMetaData().getValidatorUniqueName(); |
| } |
| |
| public String getName() { |
| if(_name == null) { |
| _name = _vmd.getValidatorDisplayName() + "::" + getProjectName(); //$NON-NLS-1$ |
| } |
| return _name; |
| } |
| |
| public void run(IBuffer buffer, IProject project) { |
| String status = ">>>>>RUN VALIDATION TEST PASS [" + project.getName() + "]>>>>>"; //$NON-NLS-1$ //$NON-NLS-2$ |
| buffer.getProgressMonitor().subTask(status); |
| buffer.write(status); |
| buffer.addExecutionStatus(getName(), ValidationTypeEnum.RUN_VALIDATION_NAME, validate(buffer, project, ValidationTypeEnum.RUN_VALIDATION, ValidationTypeEnum.RUN_VALIDATION_NAME)); |
| status = ">>>>>END RUN VALIDATION TEST PASS [" + project.getName() + "]>>>>>"; //$NON-NLS-1$ //$NON-NLS-2$ |
| buffer.getProgressMonitor().subTask(status); |
| buffer.write(status); |
| |
| status = ">>>>>FULL BUILD TEST PASS [" + project.getName() + "]>>>>>"; //$NON-NLS-1$ //$NON-NLS-2$ |
| buffer.getProgressMonitor().subTask(status); |
| buffer.write(status); |
| buffer.addExecutionStatus(getName(), ValidationTypeEnum.FULL_VALIDATION_NAME, validate(buffer, project, ValidationTypeEnum.FULL_VALIDATION, ValidationTypeEnum.FULL_VALIDATION_NAME)); |
| status = ">>>>>END FULL BUILD TEST PASS [" + project.getName() + "]>>>>>"; //$NON-NLS-1$ //$NON-NLS-2$ |
| buffer.getProgressMonitor().subTask(status); |
| buffer.write(status); |
| |
| status = ">>>>>INCREMENTAL BUILD TEST PASS [" + project.getName() + "]>>>>>"; //$NON-NLS-1$ //$NON-NLS-2$ |
| buffer.getProgressMonitor().subTask(status); |
| buffer.write(status); |
| buffer.addExecutionStatus(getName(), ValidationTypeEnum.INCREMENTAL_VALIDATION_NAME, validate(buffer, project, ValidationTypeEnum.INCREMENTAL_VALIDATION, ValidationTypeEnum.INCREMENTAL_VALIDATION_NAME)); |
| status = ">>>>>END INCREMENTAL BUILD TEST PASS [" + project.getName() + "]>>>>>"; //$NON-NLS-1$ //$NON-NLS-2$ |
| buffer.getProgressMonitor().subTask(status); |
| buffer.write(status); |
| |
| status = ">>>>>AUTO BUILD TEST PASS [" + project.getName() + "]>>>>>"; //$NON-NLS-1$ //$NON-NLS-2$ |
| buffer.getProgressMonitor().subTask(status); |
| buffer.write(status); |
| buffer.addExecutionStatus(getName(), ValidationTypeEnum.AUTO_VALIDATION_NAME, validate(buffer, project, ValidationTypeEnum.AUTO_VALIDATION, ValidationTypeEnum.AUTO_VALIDATION_NAME)); |
| status = ">>>>>END AUTO BUILD TEST PASS [" + project.getName() + "]>>>>>"; //$NON-NLS-1$ //$NON-NLS-2$ |
| buffer.getProgressMonitor().subTask(status); |
| buffer.write(status); |
| |
| if(getValidatorMetaData().isAsync()) { |
| status = ">>>>>ASYNCHRONOUS VALIDATION TEST PASS [" + project.getName() + "]>>>>>"; //$NON-NLS-1$ //$NON-NLS-2$ |
| buffer.getProgressMonitor().subTask(status); |
| buffer.write(status); |
| buffer.addExecutionStatus(getName(), ValidationTypeEnum.ASYNC_NAME, asyncValidate(buffer, project, ValidationTypeEnum.ASYNC_NAME)); |
| status = ">>>>>END ASYNCHRONOUS VALIDATION TEST PASS [" + project.getName() + "]>>>>>"; //$NON-NLS-1$ //$NON-NLS-2$ |
| buffer.getProgressMonitor().subTask(status); |
| buffer.write(status); |
| } |
| else { |
| // By default, "pass" the asynchrous tests of any validator that cannot run asynchronous tests. |
| buffer.addExecutionStatus(getName(), ValidationTypeEnum.ASYNC_NAME, true); |
| } |
| } |
| |
| private boolean validate(IBuffer buffer, IProject project, int validationTypeEnum, String taskName) { |
| long start = System.currentTimeMillis(); |
| boolean passed = true; |
| try { |
| passed = BVTRunner.singleton().test(buffer, project, this, validationTypeEnum); |
| } |
| catch(BVTValidationException exc) { |
| Logger logger = BVTValidationPlugin.getPlugin().getMsgLogger(); |
| if(logger.isLoggingLevel(Level.SEVERE)) { |
| logger.write(Level.SEVERE, exc); |
| if(exc.getTargetException() != null) { |
| logger.write(Level.SEVERE, exc.getTargetException()); |
| } |
| } |
| } |
| finally { |
| long end = System.currentTimeMillis(); |
| buffer.addElapsedTime(taskName, (end - start)); |
| buffer.write("Total time for validator " + getValidatorMetaData().getValidatorDisplayName() + " of project " + project.getName() + " in " + taskName + " mode was " + (end - start) + " milliseconds."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ |
| } |
| return passed; |
| } |
| |
| private boolean asyncValidate(IBuffer buffer, IProject project, String subTaskName) { |
| boolean passed = true; |
| long start = System.currentTimeMillis(); |
| long end = 0; |
| try { |
| GlobalConfiguration gconf = ConfigurationManager.getManager().getGlobalConfiguration(); |
| //boolean disableValidation = gconf.numberOfEnabledValidators()==0; |
| //boolean autoValidate = gconf.isAutoValidate(); |
| //boolean buildValidate = gconf.isBuildValidate(); |
| try { |
| //gconf.setAutoValidate(false); |
| // Turn off auto-validate so that the project isn't validated automatically. |
| //gconf.setAutoValidate(false); |
| //gconf.setBuildValidate(false); |
| gconf.passivate(); |
| |
| // Two tests: |
| // 1. Run validation on copies of the original project: "projectName.fork" and "projectName.noFork" |
| // Compare the markers of the copies to the FVT TestcaseMetaData, and the validator passes if the |
| // results of each copy matches the TestcaseMetaData. |
| // 2. Run validation on copies, but this time introduce changes during the validation. |
| // Extract the names of resources from the testcase metadata, find those resources, and |
| // add/delete/rename/move/close/change them. |
| |
| boolean pass1 = validateAndCompare(buffer, project, subTaskName); |
| boolean pass2 = validateChangeAndCompare(buffer, project, IFileDelta.CHANGED, subTaskName); |
| boolean pass3 = validateChangeAndCompare(buffer, project, IFileDelta.DELETED, subTaskName); |
| passed = (pass1 && pass2 && pass3); |
| } |
| catch(CoreException exc) { |
| // Couldn't create copy.Just continue with the next test. |
| Logger logger = BVTValidationPlugin.getPlugin().getMsgLogger(); |
| if(logger.isLoggingLevel(Level.SEVERE)) { |
| logger.write(Level.SEVERE, exc); |
| } |
| } |
| catch(BVTValidationException exc) { |
| Logger logger = BVTValidationPlugin.getPlugin().getMsgLogger(); |
| if(logger.isLoggingLevel(Level.SEVERE)) { |
| logger.write(Level.SEVERE, exc); |
| if(exc.getTargetException() != null) { |
| logger.write(Level.SEVERE, exc.getTargetException()); |
| } |
| } |
| } |
| catch(Throwable exc) { |
| Logger logger = BVTValidationPlugin.getPlugin().getMsgLogger(); |
| if(logger.isLoggingLevel(Level.SEVERE)) { |
| logger.write(Level.SEVERE, exc); |
| } |
| } |
| finally { |
| //gconf.setAutoValidate(autoValidate); |
| //gconf.setBuildValidate(buildValidate); |
| gconf.passivate(); |
| } |
| } |
| catch(InvocationTargetException exc) { |
| Logger logger = BVTValidationPlugin.getPlugin().getMsgLogger(); |
| if(logger.isLoggingLevel(Level.SEVERE)) { |
| logger.write(Level.SEVERE, exc); |
| if(exc.getTargetException() != null) { |
| logger.write(Level.SEVERE, exc.getTargetException()); |
| } |
| } |
| } |
| finally { |
| end = System.currentTimeMillis(); |
| buffer.addElapsedTime(ValidationTypeEnum.ASYNC_NAME, (end - start)); |
| buffer.write("Total time for validator " + getValidatorMetaData().getValidatorDisplayName() + " of project " + project.getName() + " in asynchronous mode was " + (end - start) + " milliseconds."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ |
| |
| } |
| return passed; |
| } |
| |
| /** |
| * Run validation, using several operations (both forked and not forked), on the IProject. |
| * Return true if the result, after the last operation is complete, is the expected result. |
| */ |
| private boolean validateAndCompare(IBuffer buffer, IProject project, String subTaskName) throws CoreException, BVTValidationException { |
| // Now compare the IProject's result to the expected TestcaseMetaData result. |
| // Validate |
| ValidatorSubsetOperation noForkOp = new ValidatorSubsetOperation(project, true, false); |
| noForkOp.setValidators(getValidatorMetaData().getValidatorNames()); |
| noForkOp.run(buffer.getProgressMonitor()); |
| |
| if(buffer.getProgressMonitor().isCanceled()) { |
| return false; |
| } |
| |
| ValidatorSubsetOperation forkOp = new ValidatorSubsetOperation(project, true, true); |
| forkOp.setValidators(getValidatorMetaData().getValidatorNames()); |
| forkOp.run(buffer.getProgressMonitor()); |
| |
| if(buffer.getProgressMonitor().isCanceled()) { |
| return false; |
| } |
| |
| ValidatorSubsetOperation noForkOp2 = new ValidatorSubsetOperation(project, true, false); |
| noForkOp2.setValidators(getValidatorMetaData().getValidatorNames()); |
| noForkOp2.run(buffer.getProgressMonitor()); |
| |
| if(buffer.getProgressMonitor().isCanceled()) { |
| return false; |
| } |
| |
| ValidatorSubsetOperation forkOp2 = new ValidatorSubsetOperation(project, true, true); |
| forkOp2.setValidators(getValidatorMetaData().getValidatorNames()); |
| forkOp2.run(buffer.getProgressMonitor()); |
| |
| if(buffer.getProgressMonitor().isCanceled()) { |
| return false; |
| } |
| |
| ValidatorSubsetOperation forkOp3 = new ValidatorSubsetOperation(project, true, true); |
| forkOp3.setValidators(getValidatorMetaData().getValidatorNames()); |
| forkOp3.run(buffer.getProgressMonitor()); |
| |
| // Wait until all of the threads have complete. |
| buffer.getProgressMonitor().subTask("Waiting for all forked threads to finish..."); //$NON-NLS-1$ |
| while(!VThreadManager.getManager().isDone() && !buffer.getProgressMonitor().isCanceled()) {} |
| buffer.getProgressMonitor().subTask("All threads are complete. Beginning the comparison."); //$NON-NLS-1$ |
| |
| if(buffer.getProgressMonitor().isCanceled()) { |
| return false; |
| } |
| |
| // Compare |
| IMarker[] markers = TaskListUtility.getValidationTasks(project, getValidatorMetaData().getValidatorNames()); |
| |
| if(buffer.getProgressMonitor().isCanceled()) { |
| return false; |
| } |
| |
| return BVTRunner.singleton().verify(buffer, getName(), subTaskName, project, getMessages(ValidationTypeEnum.RUN_VALIDATION), markers); |
| } |
| |
| private boolean validateChangeAndCompare(IBuffer buffer, IProject project, int ifileDeltaType, String subTaskName) throws BVTValidationException, CoreException { |
| boolean passed = true; |
| |
| ValidatorMetaData[] vmds = new ValidatorMetaData[]{getValidatorMetaData()}; |
| |
| ValidatorSubsetOperation noForkOpOrig = new ValidatorSubsetOperation(project, true, false); |
| noForkOpOrig.setValidators(getValidatorMetaData().getValidatorNames()); |
| noForkOpOrig.run(buffer.getProgressMonitor()); |
| |
| if(buffer.getProgressMonitor().isCanceled()) { |
| return false; |
| } |
| |
| ValidatorSubsetOperation noForkOpChanged = new ValidatorSubsetOperation(project, vmds, getResources(project), ifileDeltaType, false, false); // false = do not force if there's no deltas to validate |
| noForkOpChanged.run(buffer.getProgressMonitor()); |
| |
| if(buffer.getProgressMonitor().isCanceled()) { |
| return false; |
| } |
| |
| ValidatorSubsetOperation forkOpOrig = new ValidatorSubsetOperation(project, true, true); |
| forkOpOrig.setValidators(getValidatorMetaData().getValidatorNames()); |
| forkOpOrig.run(buffer.getProgressMonitor()); |
| |
| if(buffer.getProgressMonitor().isCanceled()) { |
| return false; |
| } |
| |
| ValidatorSubsetOperation forkOpChanged = new ValidatorSubsetOperation(project, vmds, getResources(project), ifileDeltaType, false, true); // false = do not force if there's no deltas to validate |
| forkOpChanged.run(buffer.getProgressMonitor()); |
| |
| if(buffer.getProgressMonitor().isCanceled()) { |
| return false; |
| } |
| |
| ValidatorSubsetOperation noForkOp2Orig = new ValidatorSubsetOperation(project, true, false); |
| noForkOp2Orig.setValidators(getValidatorMetaData().getValidatorNames()); |
| noForkOp2Orig.run(buffer.getProgressMonitor()); |
| |
| if(buffer.getProgressMonitor().isCanceled()) { |
| return false; |
| } |
| |
| ValidatorSubsetOperation noForkOp2Changed = new ValidatorSubsetOperation(project, vmds, getResources(project), ifileDeltaType, false, false); // false = do not force if there's no deltas to validate |
| noForkOp2Changed.run(buffer.getProgressMonitor()); |
| |
| if(buffer.getProgressMonitor().isCanceled()) { |
| return false; |
| } |
| |
| ValidatorSubsetOperation forkOp2Orig = new ValidatorSubsetOperation(project, true, true); |
| forkOp2Orig.setValidators(getValidatorMetaData().getValidatorNames()); |
| forkOp2Orig.run(buffer.getProgressMonitor()); |
| |
| if(buffer.getProgressMonitor().isCanceled()) { |
| return false; |
| } |
| |
| ValidatorSubsetOperation forkOp2Changed = new ValidatorSubsetOperation(project, vmds, getResources(project), ifileDeltaType, false, true); // false = do not force if there's no deltas to validate |
| forkOp2Changed.run(buffer.getProgressMonitor()); |
| |
| if(buffer.getProgressMonitor().isCanceled()) { |
| return false; |
| } |
| |
| ValidatorSubsetOperation forkOp3Orig = new ValidatorSubsetOperation(project, true, true); |
| forkOp3Orig.setValidators(getValidatorMetaData().getValidatorNames()); |
| forkOp3Orig.run(buffer.getProgressMonitor()); |
| |
| if(buffer.getProgressMonitor().isCanceled()) { |
| return false; |
| } |
| |
| ValidatorSubsetOperation forkOp3Changed = new ValidatorSubsetOperation(project, vmds, getResources(project), ifileDeltaType, false, true); // false = do not force if there's no deltas to validate |
| forkOp3Changed.run(buffer.getProgressMonitor()); |
| |
| // Wait until all of the threads have complete. |
| buffer.getProgressMonitor().subTask("Waiting for all forked threads to finish..."); //$NON-NLS-1$ |
| while(!VThreadManager.getManager().isDone() && !buffer.getProgressMonitor().isCanceled()) {} |
| if(buffer.getProgressMonitor().isCanceled()) { |
| buffer.getProgressMonitor().subTask("Comparison cancelled. Performing cleanup."); //$NON-NLS-1$ |
| return false; |
| } |
| buffer.getProgressMonitor().subTask("All threads are complete. Beginning the comparison."); //$NON-NLS-1$ |
| |
| // Compare |
| IMarker[] markers = TaskListUtility.getValidationTasks(project, getValidatorMetaData().getValidatorNames()); |
| |
| // Now compare the IProject's result to the expected TestcaseMetaData result. |
| // Don't write _passed = _passed && get... |
| // When the _passed == false, then java didn't bother running the test. |
| passed = BVTRunner.singleton().verify(buffer, getName(), subTaskName, project, getMessages(ValidationTypeEnum.RUN_VALIDATION), markers); |
| |
| ResourcesPlugin.getWorkspace().deleteMarkers(markers); |
| |
| return passed; |
| |
| } |
| } |