/*
* Name: DependsTest
* Authors: Richard Rodger
*
* Copyright (c) 2002-2004 Richard Rodger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
// package
package org.jostraca.test;
// import
import junit.framework.TestCase;
import junit.framework.TestSuite;
import junit.textui.TestRunner;
import org.jostraca.Service;
import org.jostraca.Property;
import org.jostraca.BasicTemplatePath;
import org.jostraca.util.FileUtil;
import org.jostraca.util.WayPointRecorder;
import org.jostraca.util.BasicWayPoint;
import org.jostraca.util.ListUtil;
import org.jostraca.util.PropertySet;
import org.jostraca.util.UserMessageHandler;
import org.jostraca.util.CommandLineUserMessageHandler;
import java.io.File;
import java.util.Date;
import java.util.Vector;
/** Test of the dependency tracking logic. Templates should
* only be recompiled/generated under certain conditions, that is,
* only when necessary.
*/
public class DependsTest extends TestCase {
// test framework
public DependsTest( String pName ) {
super( pName );
}
public static TestSuite suite() {
return new TestSuite( DependsTest.class );
}
public static void main( String[] pArgs ) {
TestRunner.run( suite() );
}
private String iDependsFolder;
private String iConfigFolder;
public void setUp() throws Exception {
//iDependsFolder = "depends"+File.separator;
//iConfigFolder = "../../../../conf"+File.separator;
iDependsFolder = FileUtil.findFile( "org/jostraca/test/depends/").getAbsolutePath()+File.separator;
System.out.println( "iDependsFolder:"+iDependsFolder );
iConfigFolder = new File( FileUtil.findFile( "org/jostraca" ), "../../../conf" ).getAbsolutePath()+File.separator;
System.out.println( "iConfigFolder:"+iConfigFolder );
}
// the CodeWriter is an implementation detail and should not be tested here
// as the decision to always save the code writer is not stable
// test methods
/** always compile and execute code writer */
public void testAlways() throws Exception {
System.out.println( );
String tm = "always.jtm";
String tmG = "always.txt";
String tmW = "AlwaysWriter.java";
// lastmods
String[] before = new String[] { tmG, tm };
String[] after = new String[] { tm, tmG };
// ensure CodeWriter class exists
ensureCodeWriter( tm, tmW, "" );
appendToFile( tm, "a" ); // so that code writer is different
setLastModifiedAscending( before );
System.out.println( );
WayPointRecorder.clear();
generate( tm, "" );
//System.out.println( WayPointRecorder.makeString() );
Vector wpV = new Vector();
wpV.addElement( BasicWayPoint.SavingCodeWriter.make( iDependsFolder + "AlwaysWriter.java" ) );
wpV.addElement( BasicWayPoint.CompilingCodeWriter.make( iDependsFolder + "AlwaysWriter.java" ) );
wpV.addElement( BasicWayPoint.ExecutingCodeWriter.make( iDependsFolder + "AlwaysWriter.java" ) );
//System.out.println( wpV );
//System.out.println( WayPointRecorder.makeString() );
assertTrue( WayPointRecorder.matches( wpV ) );
checkLastModifiedAscending( after );
}
/** Code writer executed despite generated being uptodate a no meta data available.
* File states: generated older than template
* Template: executed, not compiled
*/
public void testNoMeta() throws Exception {
System.out.println( );
String tm = "nometa.jtm";
String tmG = "nometa.txt";
String tmW = "NometaWriter.java";
// lastmods
String[] before = new String[] { tm, tmW, tmG };
String[] after = new String[] { tm, tmW, tmG };
// ensure CodeWriter class exists
ensureCodeWriter( tm, tmW, "" );
setLastModifiedAscending( before );
System.out.println( );
WayPointRecorder.clear();
generate( tm, "" );
Vector wpV = new Vector();
wpV.addElement( BasicWayPoint.SavingCodeWriter.make( iDependsFolder + tmW ) );
wpV.addElement( BasicWayPoint.ExecutingCodeWriter.make( iDependsFolder + tmW ) );
System.out.println( wpV );
System.out.println( WayPointRecorder.makeString() );
assertTrue( WayPointRecorder.matches( wpV ) );
setLastModifiedAscending( after );
}
/** A compile should not be necessary if code writer has not changed.
* File states: generated older than template
* Template: executed, not compiled
*/
public void testNoCompile() throws Exception {
System.out.println( );
String tm = "nocompile.jtm";
String tmG = "nocompile.txt";
String tmO = String.valueOf((new Date()).getTime());
String tmW = "NocompileWriter.java";
String[] before = new String[] { tmG, tm, tmW };
String[] after = new String[] { tm, tmW, tmG };
// ensure CodeWriter class exists
ensureCodeWriter( tm, tmW, tmO );
setLastModifiedAscending( before );
System.out.println( );
WayPointRecorder.clear();
generate( tm, tmO );
System.out.println( WayPointRecorder.makeString() );
Vector wpV = new Vector();
wpV.addElement( BasicWayPoint.SavingCodeWriter.make( iDependsFolder + tmW ) );
wpV.addElement( BasicWayPoint.ExecutingCodeWriter.make( iDependsFolder + tmW ) );
assertTrue( WayPointRecorder.matches( wpV ) );
checkLastModifiedAscending( after );
}
/* Generated file should be regenerated if resource file is changed.
* This test requires a pregenerate to record the resource file and
* ensure that the CodeWriter exists.
* File states: resource modified, template unmodified.
* Template: not executed, not compiled
*/
public void testNoGenerate() throws Exception {
Service.activateTracking( new File("/tmp/jostraca/track") );
System.out.println( );
String tm = "nogen.jtm";
String tmG = "nogen.txt";
String tmR = "nogen-input.txt";
String tmW = "NogenWriter.java";
// lastmods
String[] before = new String[] { tmR, tm, tmG };
String[] after = new String[] { tmR, tm, tmG };
// ensure CodeWriter class exists
ensureCodeWriter( tm, tmW, tmR );
setLastModifiedAscending( before );
System.out.println( );
WayPointRecorder.clear();
generate( tm, tmR );
Vector wpV = new Vector();
wpV.addElement( BasicWayPoint.GenerationUptodate.make( iDependsFolder + tm ) );
System.out.println( wpV );
System.out.println( WayPointRecorder.makeString() );
assertTrue( WayPointRecorder.matches( wpV ) );
checkLastModifiedAscending( after );
}
/* Generated file should be regenerated if resource file is changed.
* This test requires a pregenerate to record the resource file and
* ensure that the CodeWriter exists.
* File states: resource modified, template unmodified.
* Template: executed, not compiled
*/
public void testResourceModified() throws Exception {
System.out.println( );
String tm = "resmod.jtm";
String tmG = "resmod.txt";
String tmR = "resmod-input.txt";
String tmW = "ResmodWriter.java";
// lastmods
String[] before = new String[] { tm, tmG, tmR };
String[] after = new String[] { tm, tmR, tmG };
// ensure CodeWriter class exists
ensureCodeWriter( tm, tmW, tmR );
setLastModifiedAscending( before );
System.out.println( );
WayPointRecorder.clear();
generate( tm, tmR );
System.out.println( WayPointRecorder.makeString() );
Vector wpV = new Vector();
wpV.addElement( BasicWayPoint.SavingCodeWriter.make( iDependsFolder + tmW ) );
wpV.addElement( BasicWayPoint.ExecutingCodeWriter.make( iDependsFolder + tmW ) );
assertTrue( WayPointRecorder.matches( wpV ) );
checkLastModifiedAscending( after );
}
// REVIEW: need a test case for when jostraca.GeneratedFiles is empty
public void appendToFile( String pFile, String pAppend ) throws Exception {
FileUtil.writeFile( iDependsFolder+pFile, FileUtil.readFile( iDependsFolder+pFile )+pAppend );
}
public void ensureCodeWriter( String pTemplate, String pCodeWriter, String pOptions ) throws Exception {
File cwF = new File( iDependsFolder, pCodeWriter );
if( !cwF.exists() ) {
generate( pTemplate, pOptions );
}
}
public void setLastModifiedAscending( String[] pFiles ) throws Exception {
long interval = 2000;
long t = (new Date()).getTime();
int numFiles = pFiles.length;
t -= interval;
for( int fI = numFiles - 1; fI > -1; fI-- ) {
File f = new File( iDependsFolder+"/"+pFiles[fI] );
f.setLastModified( t );
System.out.println( "["+f.lastModified()+"]"+f );
t -= interval;
}
}
public void checkLastModifiedAscending( String[] pFiles ) throws Exception {
long last = 0;
File lastf = null;
int numFiles = pFiles.length;
for( int fI = 0; fI < numFiles; fI++ ) {
File f = new File( iDependsFolder+"/"+pFiles[fI] );
System.out.println( "["+f.lastModified()+"]"+f );
long fl = f.lastModified();
if( fl < last ) {
throw new Exception( f+"["+fl+"] < "+lastf+"["+last+"]" );
}
last = fl;
lastf = f;
}
}
public void generate( String pTemplate, String pOptions ) throws Exception {
Service s = new Service();
s.setTemplatePaths( ListUtil.make( new BasicTemplatePath( iDependsFolder+pTemplate ) ) );
s.setConfigFolder( iConfigFolder );
s.addPropertySet( Service.CONF_system, s.loadBaseConfigFiles( new File( iConfigFolder, "system.conf" ) ) );
PropertySet props = new PropertySet();
props.set( Property.main_OutputFolder, iDependsFolder );
props.set( Property.main_WorkFolder, iDependsFolder );
props.set( Property.main_CodeWriterOptions, pOptions );
s.addPropertySet( Service.CONF_cmdline, props );
UserMessageHandler umh = new CommandLineUserMessageHandler();
umh.setThreshold( umh.DEBUG );
s.setUserMessageHandler( umh );
s.build();
}
}