[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
RE: [cdt-patch] Automated JUnit test
|
I believe the purpose behind this patch was not as a test itself, but as a
utility to allow for us to create a JUnit test out of a directory of C/C++
source. Much of our testing involves parsing through the source code of our
own internal products, which obviously cannot be checked into CVS. A Junit
test can be composed to use this utility to run on the source we have
checked into CVS.
The C/C++ flag has come about due to defects in how we parse C code. C++
Keywords like "this" and "template" are valid identifiers in C, and the
parser was getting awefully confused in scenarios where these identifiers
were used in declarations. Unless there is a way of determining if a
particular header file is C code rather than C++, we have no alternative but
to check the nature of the project that the header resides within. This
test utility must call IParser::setCppNature( false ) in order to ensure
that we properly parse C code within a project/directory.
Andrew's work here serves as a first pass in trying to expedite our testing
for April 30th.
John
> -----Original Message-----
> From: Peter Graves [mailto:pgraves@xxxxxxx]
> Sent: Thursday, April 17, 2003 8:03 AM
> To: cdt-patch@xxxxxxxxxxx
> Subject: Re: [cdt-patch] Automated JUnit test
>
>
> I have a couple questions/concerns about this test.
> First, why are you not including the test files (.c/.cpp) in the cvs
> tree? It seems like for test repeatability they should all
> be included
> in revision control, and available in the same place as the
> test cases.
> This is the way most of the current CDT tests work, and how the core
> JDT seems to do it. In general they will create a .resource
> directory
> that contains any source/projects that are needed for the
> tests. That
> would also make it possible for other people to easily drop in new
> problematic source files that would then just be part of the normal
> testing run, which should become an automatic thing at some point.
>
> Second, why the separate failure log file? Why not generate a
> full error
> message String, and then fail the test with that? Once again, once we
> have regular test runs, it will be much easier to deal with various
> failures if we only need to deal with a single results file.
>
> And the third and final question, why does the test have a
> global C or
> C++ flag? I am guessing for your testing you just have a
> directory of C
> files, and a directory of C++ files that you switch between,
> but if all
> the source does end up in cvs, it would be nice if you could do a run
> over both the C and the C++ parsing stuff all at the same time (one
> again, especially for the automated tests run..). I am guessing it
> would be fairly easy to distinguish c files from c++ files by
> the file
> names. Header files may cause a problem, but since we would
> control the
> files we test against, we could leave c headers as .h and
> make all the
> c++ headers .hpp/.hxx or something like that.
>
> Thanks,
> -Peter
>
> Niefer, Andrew wrote:
>
> >Attached are the patches for the automated test framework.
> Note, that
> >like
> >John's line number test, this automated test requires the PDE JUnit
> >plugin
> >and should be run as a "JUnit Plugin Test".
> >
> >The automated framework will take a directory and for each
> c/cpp/h file
> >in
> >it and in its subdirectories, the framework will add a JUnit
> test to its
> >testSuite which will parse that file.
> >
> >The JUnit test will fail if the parse fails or throws an exception.
> >
> >Filename and line number for each failing test is output to
> a specified
> >file.
> >
> >There is a properties file (AutomatedTest.properties) in which you
> >specify
> >the following options, which should be customized before running the
> >test:
> >cppNature = true, means the files will be cpp files, any other value
> >means c
> >files.
> >outputFile = Z:\CDT\report.txt, the file to output the results
> >testDir = Z:\CDT\test, the directory to look for source files in.
> >
> >-Andrew
> >
> >
> >
> >
> >-------------------------------------------------------------
> -----------
> >
> >Index: ChangeLog
> >===================================================================
> >RCS file: /home/tools/org.eclipse.cdt.ui.tests/ChangeLog,v
> >retrieving revision 1.30
> >diff -u -r1.30 ChangeLog
> >--- ChangeLog 16 Apr 2003 13:52:08 -0000 1.30
> >+++ ChangeLog 16 Apr 2003 19:38:35 -0000
> >@@ -1,3 +1,6 @@
> >+2003-04-16
> >+ Added AutomatedTest
> >+
> > 2003-04-15 John Camelon
> > Added ScannerTestCase::testBug36434().
> > Added ScannerTestCase::testMultipleLines().
> >Index:
> parser/org/eclipse/cdt/core/parser/resources/AutomatedTest.properties
> >===================================================================
> >RCS file:
> parser/org/eclipse/cdt/core/parser/resources/AutomatedTest.properties
> >diff -N
> parser/org/eclipse/cdt/core/parser/resources/AutomatedTest.properties
> >--- /dev/null 1 Jan 1970 00:00:00 -0000
> >+++
> parser/org/eclipse/cdt/core/parser/resources/AutomatedTest.pro
> perties 16 Apr 2003 19:38:36 -0000
> >@@ -0,0 +1,3 @@
> >+cppNature = true
> >+outputFile = Z:\\CDT\\report.txt
> >+testDir = Z:\\CDT\\test
> >Index: parser/org/eclipse/cdt/core/parser/tests/AutomatedTest.java
> >===================================================================
> >RCS file: parser/org/eclipse/cdt/core/parser/tests/AutomatedTest.java
> >diff -N parser/org/eclipse/cdt/core/parser/tests/AutomatedTest.java
> >--- /dev/null 1 Jan 1970 00:00:00 -0000
> >+++
> parser/org/eclipse/cdt/core/parser/tests/AutomatedTest.java
> 16 Apr 2003 19:38:36 -0000
> >@@ -0,0 +1,205 @@
> >+/***********************************************************
> ********************
> >+ * Copyright (c) 2001 IBM Corporation and others.
> >+ * All rights reserved. This program and the accompanying materials
> >+ * are made available under the terms of the Common Public
> License v0.5
> >+ * which accompanies this distribution, and is available at
> >+ * http://www.eclipse.org/legal/cpl-v05.html
> >+ *
> >+ * Contributors:
> >+ * IBM Corp. - Rational Software - initial implementation
> >+
> **************************************************************
> ****************/
> >+
> >+package org.eclipse.cdt.core.parser.tests;
> >+
> >+import java.io.File;
> >+import java.io.FileInputStream;
> >+import java.io.FileOutputStream;
> >+import java.io.FilenameFilter;
> >+import java.util.LinkedList;
> >+import java.util.Properties;
> >+
> >+import org.eclipse.core.runtime.Path;
> >+
> >+import org.eclipse.cdt.internal.core.parser.IParserCallback;
> >+import org.eclipse.cdt.internal.core.parser.NullParserCallback;
> >+import org.eclipse.cdt.internal.core.parser.Parser;
> >+
> >+import junit.framework.AssertionFailedError;
> >+import junit.framework.Test;
> >+import junit.framework.TestCase;
> >+import junit.framework.TestSuite;
> >+
> >+
> >+
> >+/**
> >+ * @author aniefer
> >+ *
> >+ * To change the template for this generated type comment go to
> >+ * Window>Preferences>Java>Code Generation>Code and Comments
> >+ */
> >+public class AutomatedTest extends TestCase {
> >+ public AutomatedTest(String name){
> >+ super(name);
> >+ }
> >+
> >+ public void doFile() throws Throwable {
> >+ assertNotNull( fileList );
> >+
> >+ File file = null;
> >+ Parser parser = null;
> >+
> >+ try{
> >+ file = (File)fileList.removeFirst();
> >+ FileInputStream stream = new
> FileInputStream( file );
> >+
> >+ parser = new Parser( stream,
> nullCallback, true);
> >+ parser.setCppNature( cppNature );
> >+
> >+ assertTrue( parser.parse() );
> >+ }
> >+ catch( Throwable e )
> >+ {
> >+ if( e instanceof AssertionFailedError )
> >+ {
> >+ String output =
> file.getCanonicalPath() + ": Parse failed on line ";
> >+ output +=
> parser.getLastLineNumber() + "\n";
> >+
> >+ if( report != null ){
> >+ report.write(
> output.getBytes() );
> >+ }
> >+
> >+ fail( output );
> >+ } else {
> >+ if( report != null ){
> >+ StackTraceElement
> frames[] = e.getStackTrace();
> >+ String output =
> file.getCanonicalPath() + ": " + e.getClass().toString();
> >+ output += " on line " +
> parser.getLastLineNumber() + "\n";
> >+ output += "\t" + "at "
> + frames[0].getClassName() + "." + frames[0].getMethodName() + "\n";
> >+ output += "\t" + "at "
> + frames[1].getClassName() + "." + frames[1].getMethodName() + "\n";
> >+ report.write(
> output.getBytes() );
> >+ }
> >+ throw e;
> >+ }
> >+ }
> >+ }
> >+
> >+ public void reportFailed(){
> >+ fail( "Unable to open " + outputFile + "for
> output of results." );
> >+ }
> >+
> >+ public void propertiesFailed(){
> >+ fail( "Unable to load properties file." );
> >+ }
> >+
> >+ public static Test suite()
> >+ {
> >+ TestSuite suite = new TestSuite();
> >+
> >+ try{
> >+ loadProperties();
> >+ } catch( Exception e ){
> >+ suite.addTest( new AutomatedTest(
> "propertiesFailed") );
> >+ }
> >+
> >+ if( outputFile != null && !outputFile.equals("") ){
> >+ try{
> >+
> >+ File output = new File( outputFile );
> >+
> >+ if( output.exists() ){
> >+ output.delete();
> >+ }
> >+
> >+ output.createNewFile();
> >+
> >+ report = new FileOutputStream( output );
> >+
> >+ } catch( Exception e ) {
> >+ suite.addTest( new
> AutomatedTest( "reportFailed" ) );
> >+ }
> >+ }
> >+
> >+ File file = new File( testDir );
> >+ if( file.exists() )
> >+ fillSuite( suite, file );
> >+
> >+ index = 0;
> >+
> >+ return suite;
> >+ }
> >+ private static void fillSuite( TestSuite suite, File path ){
> >+ File files[] = null;
> >+ if( path.isFile() ){
> >+ files = new File[ 1 ];
> >+ files[0] = path;
> >+ }
> >+ else
> >+ files = path.listFiles();
> >+
> >+ File file = null;
> >+ int i = 0;
> >+ try{
> >+ file = files[ i++ ];
> >+ while( file != null )
> >+ {
> >+ if( file.isDirectory() )
> >+ fillSuite( suite, file );
> >+ else if( file.isFile() &&
> nameFilter.accept( file.getParentFile(), file.getName() ) ){
> >+ fileList.add( file );
> >+ suite.addTest( new
> AutomatedTest( "doFile" ) );
> >+ }
> >+
> >+ file = files[ i++ ];
> >+ }
> >+ } catch( ArrayIndexOutOfBoundsException e ){
> >+ //done
> >+ }
> >+ }
> >+
> >+ protected void tearDown () throws Exception {
> >+ if( fileList != null && fileList.size() == 0 ){
> >+ report.flush();
> >+ report.close();
> >+ }
> >+ }
> >+
> >+ static private void loadProperties() throws Exception{
> >+ String fileName =
> org.eclipse.core.runtime.Platform.getPlugin("org.eclipse.cdt.u
> i.tests").find(new Path("/")).getFile();
> >+ fileName +=
> "/parser/org/eclipse/cdt/core/parser/resources/AutomatedTest.p
> roperties";
> >+ FileInputStream propertiesIn = new
> FileInputStream(fileName);
> >+
> >+ properties.load( propertiesIn );
> >+
> >+ String val = null;
> >+
> >+ cppNature = ( properties.getProperty(
> "cppNature", "true" ).equals("true") );
> >+ outputFile = properties.getProperty( "outputFile", "" );
> >+ testDir = properties.getProperty( "testDir", "" );
> >+ }
> >+
> >+ private static LinkedList fileList = new LinkedList();
> >+ private static int index = 0;
> >+ private static FilenameFilter nameFilter = new Filter();
> >+ private static FileOutputStream report = null;
> >+ private static IParserCallback nullCallback = new
> NullParserCallback();
> >+ private static Properties properties = new Properties();
> >+
> >+ private static boolean cppNature = true;
> >+ private static String outputFile = null;
> >+ private static String testDir = null;
> >+
> >+ static private class Filter implements FilenameFilter
> >+ {
> >+ public boolean accept(File dir, String name) {
> >+ if( name.endsWith(".cpp") ||
> >+ name.endsWith(".c") ||
> >+ name.endsWith(".cc") ||
> >+ name.endsWith(".h") )
> >+ {
> >+ return true;
> >+ }
> >+ else
> >+ return false;
> >+ }
> >+ }
> >+}
> >
> >
> >-------------------------------------------------------------
> -----------
> >
> >Index: parser/org/eclipse/cdt/internal/core/parser/Parser.java
> >===================================================================
> >RCS file:
> /home/tools/org.eclipse.cdt.core/parser/org/eclipse/cdt/intern
> al/core/parser/Parser.java,v
> >retrieving revision 1.31
> >diff -u -r1.31 Parser.java
> >--- parser/org/eclipse/cdt/internal/core/parser/Parser.java
> 16 Apr 2003 12:30:46 -0000 1.31
> >+++ parser/org/eclipse/cdt/internal/core/parser/Parser.java
> 16 Apr 2003 19:19:59 -0000
> >@@ -106,13 +106,17 @@
> > // Mark as failure and try to
> reach a recovery point
> > failParse();
> >
> >- if (lastBacktrack != null &&
> lastBacktrack == LA(1)) {
> >- // we haven't
> progressed from the last backtrack
> >- // try and find tne
> next definition
> >- consumeToNextSemicolon();
> >- } else {
> >- // start again from here
> >- lastBacktrack = LA(1);
> >+ try {
> >+ if (lastBacktrack !=
> null && lastBacktrack == LA(1)) {
> >+ // we haven't
> progressed from the last backtrack
> >+ // try and find
> tne next definition
> >+
> consumeToNextSemicolon();
> >+ } else {
> >+ // start again from here
> >+ lastBacktrack = LA(1);
> >+ }
> >+ } catch (EndOfFile e){
> >+ break;
> > }
> > }
> > catch( Exception e )
> >@@ -2269,5 +2273,12 @@
> > public int getLineNumberForOffset(int offset)
> > {
> > return scanner.getLineNumberForOffset(offset);
> >+ }
> >+
> >+ public int getLastLineNumber(){
> >+ if( lastToken != null ){
> >+ return scanner.getLineNumberForOffset(
> lastToken.offset );
> >+ }
> >+ return -1;
> > }
> > }
> >
> >
>
>
> _______________________________________________
> cdt-patch mailing list
> cdt-patch@xxxxxxxxxxx
> http://dev.eclipse.org/mailman/listinfo/cdt-patch
>