From: <bsc...@us...> - 2007-09-25 15:04:19
|
Revision: 1674 http://unicore.svn.sourceforge.net/unicore/?rev=1674&view=rev Author: bschuller Date: 2007-09-25 08:04:17 -0700 (Tue, 25 Sep 2007) Log Message: ----------- set USPACE_DIR in legacy TSI (fixes sf bug #1791483); add user email support (part of feature req#1801098); add "execute script"; add exit code support with legacy TSI (bug #1784660); add JMX bean for managing the legacy tsi Modified Paths: -------------- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/Configuration.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/XNJS.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/ems/ExecutionContext.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/Execution.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/LegacyTSI.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/TSIConnection.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/TSIConnectionFactory.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/TSIUtils.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/BasicExecution.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/LocalECManager.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/LocalExecution.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/LocalTS.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/tsi/TSI.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/tsi/TSIBusyException.java xnjs/trunk/xnjs-module-core/src/test/java/de/fzj/unicore/xnjs/functional/TestTSI.java xnjs/trunk/xnjs-module-core/src/test/java/de/fzj/unicore/xnjs/legacy/TestLegacyTSI.java xnjs/trunk/xnjs-module-core/src/test/java/de/fzj/unicore/xnjs/simple/TestLocalTS.java Added Paths: ----------- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/LegacyTSIJmx.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/LegacyTSIJmxMBean.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/tsi/TSIUnavailableException.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/util/ExecuteScript.java xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/util/ResultHolder.java Modified: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/Configuration.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/Configuration.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/Configuration.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -302,10 +302,11 @@ } /** - * process JMX mbeans declared on the class + * process JMX mbeans declared on the class using + * a {@link ManagedComponent} annotation * @param c */ - private void registerMBeans(Class<? extends Object> c){ + public void registerMBeans(Class<? extends Object> c){ ManagedComponent mb=(ManagedComponent)(c.getAnnotation(ManagedComponent.class)); if(mb!=null){ logger.finer("Processing MBean declaration for: "+c.getName()); Modified: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/XNJS.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/XNJS.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/XNJS.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -40,10 +40,10 @@ import de.fzj.unicore.xnjs.util.ConfigUtils; /** - * XNJS main class<br> + * XNJS main class<br/> * + * * @author schuller - * @version $Id: XNJS.java,v 1.7 2006/08/01 07:16:03 schuller Exp $ */ public class XNJS { Modified: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/ems/ExecutionContext.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/ems/ExecutionContext.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/ems/ExecutionContext.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -67,6 +67,8 @@ private String userName; //and role private Role role; + //and email address + private String userEmail; //create an uninitialized ExecutionContext public ExecutionContext(){ @@ -189,7 +191,23 @@ public void setRole(Role role) { this.role = role; } + /** + * get the user's email address + * @return the user email address or null if not set + */ + public String getUserEmail() { + return userEmail; + } + + /** + * set the user email + * @param userEmail the email address of the user + */ + public void setUserEmail(String userEmail) { + this.userEmail = userEmail; + } + /** * return the exit code (=null if undefined) * @return */ Modified: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/Execution.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/Execution.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/Execution.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -33,6 +33,9 @@ package de.fzj.unicore.xnjs.legacy; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; import java.util.Hashtable; import java.util.Map; import java.util.logging.Level; @@ -47,6 +50,7 @@ import de.fzj.unicore.xnjs.ems.ExecutionException; import de.fzj.unicore.xnjs.management.Dependency; import de.fzj.unicore.xnjs.simple.BasicExecution; +import de.fzj.unicore.xnjs.tsi.TSI; /** * IExecution interface implemented against a classic Unicore 4.x TSI<br> @@ -56,8 +60,10 @@ @Dependency(classes={TSIConnectionFactory.class}) public class Execution extends BasicExecution { private Map<String,String> bssJobStates; - long lastupdate=-1; + private long lastupdate=-1; + public static int UPDATE_INTERVAL=1000; + public Execution(Configuration config){ super(config); bssJobStates=new Hashtable<String,String>(); @@ -69,7 +75,7 @@ */ protected void doSubmit(POSIXApplicationType appDescription, Action job, ExecutionContext ec) throws ExecutionException { try{ - updateExecutionContext(ec, appDescription); + updateExecutionContext(ec, appDescription, job); String tsiCmd=TSIUtils.makeSubmitCommand(appDescription, job, ec); //user/group @@ -85,7 +91,7 @@ catch(Exception ex){} if(group==null)group="NONE"; - TSIConnection conn=TSIConnectionFactory.getTSIConnection(user+" "+group); + TSIConnection conn=TSIConnectionFactory.getTSIConnection(user+" "+group, true); String res=conn.send(tsiCmd); job.addLogTrace("Command is: \n"+tsiCmd); if(!res.contains("OK")){ @@ -111,28 +117,32 @@ */ public void updateStatus(Action job) throws ExecutionException { try{ - updateBSSStates(); + if(!updateBSSStates())return; String bssid=job.getBSID(); String status=bssJobStates.get(bssid); if(status==null) { //just assume it's done, no sneaky tricks with checking stdout files... job.setStatus(ActionStatus.POSTPROCESSING); + //check outcome and set status code... + if(job.getExecutionContext().getExitCode()==null)getExitCode(job); } }catch(Exception ex){//wrap it + logger.log(Level.SEVERE,"Error updating job status list.",ex); throw new ExecutionException(ex); } } //updates the status hashmap - protected void updateBSSStates() throws Exception { - //only update at most every 2 secs - if(lastupdate+2000>System.currentTimeMillis()) return; + protected boolean updateBSSStates() throws Exception { + //only update at some configurable rate + if(lastupdate+UPDATE_INTERVAL>System.currentTimeMillis()) return false; lastupdate=System.currentTimeMillis(); logger.fine("Updating status on legacy TSI"); - TSIConnection conn=TSIConnectionFactory.getTSIConnection(TSIConnectionFactory.getBSSUSer()+" NONE"); + TSIConnection conn=TSIConnectionFactory.getTSIConnection(TSIConnectionFactory.getBSSUSer()+" NONE", true); String res=conn.send(TSIUtils.makeStatusCommand()); bssJobStates = TSIUtils.parseStatusListing(res); conn.done(); + return true; } @Override @@ -148,17 +158,38 @@ String status=bssJobStates.get(bssid); if(status!=null) { logger.fine("Aborting job <"+bssid+"> on legacy TSI"); - TSIConnection conn=TSIConnectionFactory.getTSIConnection(TSIConnectionFactory.getBSSUSer()+" NONE"); + TSIConnection conn=TSIConnectionFactory.getTSIConnection(TSIConnectionFactory.getBSSUSer()+" NONE", true); String res=conn.send(TSIUtils.makeAbortCommand(bssid)); bssJobStates = TSIUtils.parseStatusListing(res); conn.done(); } }catch(Exception ex){//wrap it + logger.log(Level.SEVERE,"Error aborting.",ex); throw new ExecutionException(ex); } } } + /** + * get the exit code + * + * @param job + */ + protected void getExitCode(Action job)throws Exception{ + TSI tsi=getConfiguration().getTargetSystemInterface(job.getClient()); + InputStream is=tsi.getInputStream(job.getExecutionContext().getWorkingDirectory()+"/"+TSIUtils.EXITCODE_FILENAME); + String s=new BufferedReader(new InputStreamReader(is)).readLine(); + if(s!=null){ + try{ + int i=Integer.parseInt(s); + job.getExecutionContext().setExitCode(i); + job.addLogTrace("Exit code <"+i+">"); + logger.finer("Script exited with code <"+i+">"); + }catch(Exception e){ + logger.log(Level.WARNING,"Could not retrieve exit code.",e); + } + } + } } Modified: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/LegacyTSI.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/LegacyTSI.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/LegacyTSI.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -36,6 +36,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; import java.io.StringReader; import java.util.ArrayList; @@ -109,6 +110,11 @@ public void setClient(Client client){ this.client=client; + if(client!=null){ + try{ + user=client.getAttributes().get(Client.ATTRIBUTE_XLOGIN); + }catch(Exception e){} + } } /* (non-Javadoc) @@ -158,7 +164,7 @@ if(logger.isLoggable(Level.FINEST))logger.finest(tsiCmd); TSIConnection conn=null; try{ - conn=TSIConnectionFactory.getTSIConnection(user+" "+group); + conn=TSIConnectionFactory.getTSIConnection(user+" "+group, true); res=conn.send(tsiCmd); if(logger.isLoggable(Level.FINEST))logger.finest(res); if(!res.contains("TSI_OK"))throw new ExecutionException("Command execution on TSI failed. Reply was: "+res); @@ -186,6 +192,26 @@ commands.append(what+"\n"); this.ec=ec; } + + public void execAndWait(String what, ExecutionContext ec) throws ExecutionException { + try{ + begin(); + commands.append(CD+" "+ec.getWorkingDirectory()+"\n"); + commands.append(what+"\n"); + this.ec=ec; + commit(); + System.out.println("Executed "+what+" in "+ec.getWorkingDirectory()); + //get exit code + InputStream is=getInputStream(ec.getWorkingDirectory()+"/"+TSIUtils.EXITCODE_FILENAME); + String s=new BufferedReader(new InputStreamReader(is)).readLine(); + int i=Integer.parseInt(s); + ec.setExitCode(i); + logger.finer("Script exited with code <"+i+">"); + }catch(Exception e){ + logger.log(Level.SEVERE,"Can't execute script.",e); + throw new ExecutionException(e); + } + } /* (non-Javadoc) * @see de.fzj.unicore.xnjs.tsi.TSI#getAutoCommit() @@ -218,7 +244,7 @@ public String getHomePath(String user)throws ExecutionException{ try{ - TSIConnection conn=TSIConnectionFactory.getTSIConnection(user+" NONE"); + TSIConnection conn=TSIConnectionFactory.getTSIConnection(user+" NONE", true); String cmd="echo $HOME"; String tsicmd=TSIUtils.makeExecuteScript(cmd,null); String res=TSIUtils.parseSubmitReply(conn.send(tsicmd)); @@ -338,13 +364,14 @@ String cmd=PERL+" "+loc; if(normal)cmd+=" N "+file; else cmd+=" A "+file; - if(logger.isLoggable(Level.FINEST))logger.finest("Executing tsi ls() command: "+cmd); + logger.finest("Executing tsi ls() command: "+cmd); String res=""; String role=getRole(); String tsicmd=TSIUtils.makeExecuteScript(cmd, null); - TSIConnection conn=TSIConnectionFactory.getTSIConnection(user+" "+role); + TSIConnection conn=TSIConnectionFactory.getTSIConnection(user+" "+role, true); res=conn.send(tsicmd); conn.done(); + logger.finest("TSILS Reply: "+res); return res; } @@ -352,25 +379,21 @@ * for the format see the comment for {@link #ls()} * @param line - TSI listing line * @return a XnjsFile describing the file + * @throws Exception in case of parsing errors */ - protected static XnjsFile parseLine(String line){ + protected static XnjsFile parseLine(String line)throws Exception{ String[]tok=line.substring(7).split(" ",3); - try{ - int l=tok.length; - String name=tok[l-1]; - boolean isDirectory=line.charAt(1)=='D'; - boolean isReadable=line.charAt(2)=='R'; - boolean isWritable=line.charAt(3)=='W'; - boolean isExecutable=line.charAt(4)=='X'; - long lastMod=Long.parseLong(tok[l-2]); - long size=Long.parseLong(tok[l-3]); - Permissions p=new Permissions(isReadable,isWritable,isExecutable); - XnjsFile f=new XnjsFileImpl(name,size,isDirectory,lastMod,p); - return f; - }catch(Exception e){ - logger.warning("Error parsing: '"+line+"'"); - return null; - } + int l=tok.length; + String name=tok[l-1]; + boolean isDirectory=line.charAt(1)=='D'; + boolean isReadable=line.charAt(2)=='R'; + boolean isWritable=line.charAt(3)=='W'; + boolean isExecutable=line.charAt(4)=='X'; + long lastMod=Long.parseLong(tok[l-2]); + long size=Long.parseLong(tok[l-3]); + Permissions p=new Permissions(isReadable,isWritable,isExecutable); + XnjsFile f=new XnjsFileImpl(name,size,isDirectory,lastMod,p); + return f; } @@ -380,7 +403,7 @@ public InputStream getInputStream(final String file) throws ExecutionException { //figure out length of file try{ - logger.info("Reading from "+file); + logger.fine("Reading from "+file); return new InputStream(){ //read buffer byte[] buffer=new byte[bufsize]; @@ -464,7 +487,7 @@ break; }else break; } - logger.info("length="+lengthFromLS); + logger.fine("length="+lengthFromLS); return lengthFromLS; } @@ -475,7 +498,7 @@ } String tsicmd=TSIUtils.makeGetFileChunkCommand(file,offset,length); String role =getRole(); - TSIConnection conn=TSIConnectionFactory.getTSIConnection(user+" "+role); + TSIConnection conn=TSIConnectionFactory.getTSIConnection(user+" "+role, false); String res=conn.send(tsicmd); if(!res.contains("TSI_OK")){ throw new ExecutionException("GetFileChunk on legacy TSI failed. Reply was "+res); @@ -547,7 +570,7 @@ String tsicmd=TSIUtils.makePutFilesCommand(append); String role =getRole(); - TSIConnection conn=TSIConnectionFactory.getTSIConnection(user+" "+role); + TSIConnection conn=TSIConnectionFactory.getTSIConnection(user+" "+role, false); String res=conn.send(tsicmd); if(!res.contains("TSI_OK")){ throw new IOException("Execution on legacy TSI failed. Reply was "+res); Added: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/LegacyTSIJmx.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/LegacyTSIJmx.java (rev 0) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/LegacyTSIJmx.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -0,0 +1,85 @@ +/********************************************************************************* + * Copyright (c) 2007 Forschungszentrum Juelich GmbH + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * (1) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer at the end. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * (2) Neither the name of Forschungszentrum Juelich GmbH nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * DISCLAIMER + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *********************************************************************************/ + +package de.fzj.unicore.xnjs.legacy; + +/** + * JMX Mbean implementation for the Legacy TSI and its connection pools + * + * @author schuller + */ +public class LegacyTSIJmx implements LegacyTSIJmxMBean { + + /* (non-Javadoc) + * @see de.fzj.unicore.xnjs.legacy.LegacyTSIJmxMBean#getPoolSize() + */ + public int getPoolSize(){ + return TSIConnectionFactory.getNumberOfPooledConnections(); + } + + /* (non-Javadoc) + * @see de.fzj.unicore.xnjs.legacy.LegacyTSIJmxMBean#getBSSUser() + */ + public String getBSSUser(){ + return TSIConnectionFactory.getBSSUSer(); + } + + /* (non-Javadoc) + * @see de.fzj.unicore.xnjs.legacy.LegacyTSIJmxMBean#getTSIMachine() + */ + public String getTSIMachine(){ + return TSIConnectionFactory.getMachine(); + } + + /* (non-Javadoc) + * @see de.fzj.unicore.xnjs.legacy.LegacyTSIJmxMBean#getTSIPort() + */ + public int getTSIPort(){ + return TSIConnectionFactory.getPort(); + } + + /* (non-Javadoc) + * @see de.fzj.unicore.xnjs.legacy.LegacyTSIJmxMBean#getLocalPort() + */ + public int getLocalPort(){ + return TSIConnectionFactory.getReplyport(); + } + + /* (non-Javadoc) + * @see de.fzj.unicore.xnjs.legacy.LegacyTSIJmxMBean#getConnectionStatus() + */ + public String getConnectionStatus(){ + return TSIConnectionFactory.getConnectionStatus(); + } + + +} Added: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/LegacyTSIJmxMBean.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/LegacyTSIJmxMBean.java (rev 0) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/LegacyTSIJmxMBean.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -0,0 +1,17 @@ +package de.fzj.unicore.xnjs.legacy; + +public interface LegacyTSIJmxMBean { + + public abstract int getPoolSize(); + + public abstract String getBSSUser(); + + public abstract String getTSIMachine(); + + public abstract int getTSIPort(); + + public abstract int getLocalPort(); + + public abstract String getConnectionStatus(); + +} \ No newline at end of file Modified: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/TSIConnection.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/TSIConnection.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/TSIConnection.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -172,6 +172,7 @@ * */ public boolean isAlive() { + logger.info("Alive check"); return command != null && command.isAlive(); } @@ -318,18 +319,9 @@ try { output.print(data); - if (send_user) - output.print("\n#TSI_IDENTITY " + id_line + "\n"); // Send - // the - // user's - // identity - // in - // case - // the - // TSI - // changes - // per - // command + if (send_user){ + output.print("\n#TSI_IDENTITY " + id_line + "\n"); + } output.print("\nENDOFMESSAGE\n"); output.flush(); Modified: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/TSIConnectionFactory.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/TSIConnectionFactory.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/TSIConnectionFactory.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -43,7 +43,9 @@ import java.util.logging.Logger; import de.fzj.unicore.xnjs.XnjsComponentImpl; +import de.fzj.unicore.xnjs.management.ManagedComponent; import de.fzj.unicore.xnjs.management.Startable; +import de.fzj.unicore.xnjs.tsi.TSIUnavailableException; /** * create and pool conections to "legacy" Unicore TSIs<br> @@ -52,6 +54,7 @@ * @author schuller * @version $Id: TSIConnectionFactory.java,v 1.4 2006/09/23 10:48:03 schuller Exp $ */ +@ManagedComponent(mbean={LegacyTSIJmx.class},name="LegacyTSI") public class TSIConnectionFactory extends XnjsComponentImpl implements Startable{ protected static Logger log=Logger.getLogger(TSIConnectionFactory.class.getName()); @@ -59,8 +62,8 @@ private static InetAddress source_addr=null; private static ServerSocket server=null; private static String machine=""; - private static int port=-1; - private static int replyport=-1; + static int port=-1; + static int replyport=-1; public static final String TSI_MACHINE="CLASSICTSI.machine"; public static final String TSI_PORT="CLASSICTSI.port"; public static final String TSI_MYPORT="CLASSICTSI.replyport"; @@ -68,19 +71,27 @@ private static int count=1; private static String bssuser; + private static boolean connStatus=false; + /** * return a connection that executes commands under the given user id * @param userID + * @param checkAlive - whether to test if the TSI is not responding * @return a valid connection object or null in case of errors */ - public static synchronized TSIConnection getTSIConnection(String userID){ + public static synchronized TSIConnection getTSIConnection(String userID, boolean checkAlive){ log.finer("User id line: "+userID); //have one left? TSIConnection conn=null; if(pool.size()>0) { conn=pool.remove(0); - log.finer("Reusing TSIConnection"); - +// if(checkAlive && !conn.isAlive()){ +// conn.dead(); +// conn=null; +// } +// else{ + log.finer("Reusing TSIConnection"); +// } } if(conn==null){ try{ @@ -92,11 +103,16 @@ } } - if(conn!=null) conn.setIdLine(userID); + if(conn!=null){ + connStatus=true; + conn.setIdLine(userID); + } + else connStatus=false; + return conn; } - private static TSIConnection createNewTSIConnection() throws Exception { + private static TSIConnection createNewTSIConnection() throws TSIUnavailableException { TSIConnection newConn=null; // Ask shepherd for a new worker @@ -105,7 +121,7 @@ } catch(Exception ex) { log.severe("TSI shepherd is not available"); - throw new Exception("TSI shepherd is not available"); + throw new TSIUnavailableException("TSI shepherd is not available"); } try { @@ -126,7 +142,7 @@ if(!commands_socket.getInetAddress().equals(source_addr)) { commands_socket.close(); data_socket.close(); - throw new Exception("Invalid new TSI connection (wrong machine). Contact site administration"); // ?? OK + throw new RuntimeException("Invalid new TSI connection (wrong machine). Contact site administration"); // ?? OK } @@ -135,12 +151,12 @@ } catch(InterruptedIOException iioex) { - throw new Exception("TSI connection startup timed out (no TSI running?). Contact site administration"); + throw new TSIUnavailableException("TSI connection startup timed out (no TSI running?). Contact site administration"); } catch(Exception ex) { // This happened when we were expecting to be able // to talk properly. - throw new Exception("Error while making a new TSI connection. Contact site administration"); // ?? OK + throw new RuntimeException("Error while making a new TSI connection. Contact site administration"); // ?? OK } return newConn; @@ -199,6 +215,7 @@ " ** User id for querying list of jobs on BSS: '"+bssuser+"'"); server=new ServerSocket(replyport); + getConfiguration().registerMBeans(this.getClass()); } catch(Exception ex){ //die, crappy config @@ -250,9 +267,20 @@ return replyport; } /** - * @return Returns the replyport. + * @return Returns the user for retrieving job stati. */ public static String getBSSUSer() { return bssuser; } + + public static String getConnectionStatus(){ + try{ + TSIConnection c=createNewTSIConnection(); + c.dead(); + }catch(Exception e){ + return "TSI UNAVAILABLE"; + } + return "OK"; + } + } Modified: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/TSIUtils.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/TSIUtils.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/legacy/TSIUtils.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -56,6 +56,9 @@ */ public class TSIUtils { protected static Logger logger=Logger.getLogger(TSIUtils.class.getName()); + + public static final String EXITCODE_FILENAME="UNICORE_SCRIPT_EXIT_CODE"; + private TSIUtils(){} /** @@ -85,16 +88,7 @@ String queue="NONE"; String hostname="none"; - String jobname="Unicore_Job"; - //job id stuff - try { - String n=jdd.getJobDefinition().getId(); - if(n!=null)jobname=n; - } catch (RuntimeException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - logger.info("Jobname: "+jobname); + if(rt!=null){ //CPUs per node, this implies we have nodes defined as well if(rt.getIndividualCPUCount()!=null){ @@ -141,9 +135,20 @@ commands.append("#TSI_SUBMIT\n" ); - commands.append("#TSI_JOBNAME "+jobname.trim().replace(' ','_') +"\n"); + //job name + String jobname="Unicore_Job"; + try { + String n=jdd.getJobDefinition().getId(); + if(n!=null)jobname=n; + } catch (NullPointerException e1) { } + logger.fine("Jobname: "+jobname); + commands.append("#TSI_JOBNAME "+jobname.trim().replace(' ','_') +"\n"); + + //working dir commands.append("#TSI_OUTCOME_DIR "+ec.getWorkingDirectory() +"\n"); - //resources + commands.append("#TSI_USPACE_DIR "+ec.getWorkingDirectory() +"\n"); + + //resources commands.append("#TSI_TIME " + (new Double(run_time)).intValue() + "\n"); commands.append("#TSI_MEMORY "+ (new Double(memory)).intValue() + "\n"); // Allow for serial jobs (SvdB 29-11-02) - existing TSIs expect NONE as serial marker @@ -157,11 +162,15 @@ } commands.append("#TSI_HOST_NAME "+ hostname + "\n"); commands.append("#TSI_STORAGE_REQUEST USPACE 0 \n"); //unused by 4.x TSIs - commands.append("#TSI_EMAIL NONE\n"); commands.append("#TSI_QUEUE " + queue + "\n"); - //TODO add dynamic ones here +// TODO add dynamic ones here + + String email=ec.getUserEmail()!=null?ec.getUserEmail():"NONE"; + commands.append("#TSI_EMAIL "+email+"\n"); + + // last bit to introduce script (extends to end of incarnation) commands.append("#TSI_SCRIPT\n"); @@ -209,6 +218,8 @@ } } commands.append("\n"); + //write the application exit code to a special file + commands.append("echo $? > "+ec.getWorkingDirectory()+"/"+EXITCODE_FILENAME+"\n"); return commands.toString(); } @@ -233,8 +244,11 @@ commands.append("# supplied environment variables end.\n"); } commands.append(script+"\n"); + if(ec!=null)commands.append("echo $? > "+ec.getWorkingDirectory()+"/"+EXITCODE_FILENAME+"\n"); return commands.toString(); } + + /** * parse the status listing returned by TSI GetStatusListing * Modified: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/BasicExecution.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/BasicExecution.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/BasicExecution.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -37,6 +37,8 @@ import java.util.HashMap; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.ggf.schemas.jsdl.x2005.x11.jsdl.ApplicationDocument; import org.ggf.schemas.jsdl.x2005.x11.jsdl.ApplicationType; @@ -47,6 +49,10 @@ import org.ggf.schemas.jsdl.x2005.x11.jsdlPosix.POSIXApplicationDocument; import org.ggf.schemas.jsdl.x2005.x11.jsdlPosix.POSIXApplicationType; +import sun.security.x509.X500Name; + +import javax.security.auth.x500.X500Principal; + import de.fzj.unicore.xnjs.Configuration; import de.fzj.unicore.xnjs.XnjsComponentImpl; import de.fzj.unicore.xnjs.ems.Action; @@ -69,6 +75,10 @@ protected static Logger logger=Logger.getLogger(BasicExecution.class.getName()); private IExecutionContextManager ecm; + //pattern for extracting email address from DN + final protected static String emailRE= "([\\w-]+)@([\\w-]+\\.)([\\w-]+)(\\.[\\w-]+)*"; + final protected static Pattern pattern = Pattern.compile(emailRE); + public BasicExecution(Configuration config) { this.configuration=config; ecm=configuration.getExecutionContextMgr(); @@ -127,8 +137,8 @@ */ protected void doSubmit (POSIXApplicationType appDescription, Action job, ExecutionContext ec)throws Exception{ TSI tsi=getConfiguration().getTargetSystemInterface(job.getClient()); + updateExecutionContext(ec, appDescription, job); //start execution - updateExecutionContext(ec, appDescription); tsi.setAutoCommit(false); tsi.begin(); tsi.cd(ec.getWorkingDirectory()); @@ -142,7 +152,7 @@ * @param ec ExecutionContext to update * @param appDescription */ - protected void updateExecutionContext(ExecutionContext ec, POSIXApplicationType appDescription){ + protected void updateExecutionContext(ExecutionContext ec, POSIXApplicationType appDescription, Action job){ //stdin, etc if(appDescription.getOutput()!=null)ec.setStdout(appDescription.getOutput().getStringValue()); if(appDescription.getError()!=null)ec.setStderr(appDescription.getError().getStringValue()); @@ -155,7 +165,22 @@ value=et.getStringValue(); map.put(name,value); } + + //user email --- could be set in job, but for now just get it from the DN + try{ + String dn=job.getClient().getDistinguishedName(); + //need format which includes plain text email... + X500Principal p=new X500Principal(dn); + Matcher m=pattern.matcher(p.toString()); + if(m.find()){ + ec.setUserEmail(m.group()); + } + }catch(Exception e){ + + } //others? + + } /** Modified: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/LocalECManager.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/LocalECManager.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/LocalECManager.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -83,7 +83,7 @@ if (targetSystem==null) { throw new RuntimeException("Critical error: no TSI instance loaded."); } - String wd=targetSystem.getBaseDirectory()+targetSystem.getFileSeparator()+action.getUUID(); + String wd=targetSystem.getBaseDirectory()+targetSystem.getFileSeparator()+action.getUUID()+targetSystem.getFileSeparator(); targetSystem.begin(); targetSystem.mkdir(wd); Modified: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/LocalExecution.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/LocalExecution.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/LocalExecution.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -12,8 +12,6 @@ import java.util.logging.Level; import java.util.logging.Logger; -import sun.reflect.ReflectionFactory.GetReflectionFactoryAction; - import de.fzj.unicore.xnjs.ems.ExecutionContext; public class LocalExecution implements Runnable { @@ -50,6 +48,8 @@ public void run() { try{ + if(actionID!=null)runningJobs.add(actionID); + long start=System.currentTimeMillis(); String what=replaceEnvVars(cmd, ec); logger.info("Executing '"+what+"' in "+workDir); @@ -57,8 +57,6 @@ pb.directory(new File(workDir)); copyEnv(ec.getEnvironment(),pb.environment()); pb.command(what.split(" +")); - if(actionID!=null)runningJobs.add(actionID); - Process p=pb.start(); //write stdout/stderr files @@ -143,8 +141,8 @@ } }while(!finishedIn || !finishedErr); - fos1.flush(); fos1.close(); - fos2.flush(); fos2.close(); + fos1.flush(); fos1.close(); + fos2.flush(); fos2.close(); long diff=System.currentTimeMillis()-start; logger.info("Done with '"+what+"' exit code "+exit+", took "+diff+" ms."); //save exit code... Modified: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/LocalTS.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/LocalTS.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/simple/LocalTS.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -291,6 +291,25 @@ throw new ExecutionException(ex);} } + /** + * Execute a command. This delegates execution to a executor thread pool. + */ + public void execAndWait(String orig, ExecutionContext ec) throws TSIBusyException,ExecutionException { + try{ + LocalExecution ex=new LocalExecution(orig,getWorkingDir(),ec); + es.execute(ex); + while(LocalExecution.isRunning(ec.getActionID())){ + Thread.sleep(50); + } + Thread.sleep(50); + ec.setExitCode(LocalExecution.getExitCode(ec.getActionID())); + }catch(RejectedExecutionException re){ + throw new TSIBusyException("Execution currently not possible."); + }catch(Exception ex){ + logger.log(Level.SEVERE, "Error while executing.",ex); + throw new ExecutionException(ex);} + } + public String getBaseDirectory(){ return baseDirectory; } Modified: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/tsi/TSI.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/tsi/TSI.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/tsi/TSI.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -103,8 +103,26 @@ */ public XnjsFile[] ls() throws ExecutionException; + /** + * execute a command asynchtonously + * + * @param what the shell script to execute + * @param ec the {@link ExecutionContext] + * @throws TSIBusyException + * @throws ExecutionException + */ public void exec(String what, ExecutionContext ec) throws TSIBusyException,ExecutionException; + /** + * execute a command synchtonously + * + * @param what the shell script to execute + * @param ec the {@link ExecutionContext] + * @throws TSIBusyException + * @throws ExecutionException + */ + public void execAndWait(String what, ExecutionContext ec) throws TSIBusyException,ExecutionException; + // file things /** Modified: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/tsi/TSIBusyException.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/tsi/TSIBusyException.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/tsi/TSIBusyException.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -11,12 +11,10 @@ public TSIBusyException(String msg) { super(msg); - // TODO Auto-generated constructor stub } public TSIBusyException(Throwable t) { super(t); - // TODO Auto-generated constructor stub } } Added: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/tsi/TSIUnavailableException.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/tsi/TSIUnavailableException.java (rev 0) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/tsi/TSIUnavailableException.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -0,0 +1,23 @@ +package de.fzj.unicore.xnjs.tsi; + +public class TSIUnavailableException extends Exception { + + private static final long serialVersionUID = 1L; + + public TSIUnavailableException() { + super(); + } + + public TSIUnavailableException(String message, Throwable cause) { + super(message, cause); + } + + public TSIUnavailableException(String message) { + super(message); + } + + public TSIUnavailableException(Throwable cause) { + super(cause); + } + +} Added: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/util/ExecuteScript.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/util/ExecuteScript.java (rev 0) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/util/ExecuteScript.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -0,0 +1,70 @@ +package de.fzj.unicore.xnjs.util; + +import de.fzj.unicore.xnjs.Configuration; +import de.fzj.unicore.xnjs.aaa.Client; +import de.fzj.unicore.xnjs.ems.Action; +import de.fzj.unicore.xnjs.ems.ExecutionContext; +import de.fzj.unicore.xnjs.ems.ExecutionException; +import de.fzj.unicore.xnjs.tsi.TSI; +import de.fzj.unicore.xnjs.tsi.TSIBusyException; + +/** + * helpers to execute a script on the TSI + * + * @author schuller + */ +public class ExecuteScript { + + private ExecuteScript(){} + + /** + * Execute a shell script in a temporary directory. + * After execution, this directory is removed. + * + * @param script - the script to execute + * @param client - the client for which to execute the script + * @param config - config object + * @throws ExecutionException + * @throws TSIBusyException + * @return a {@link ResultHolder} for retrieving the results + */ + public static ResultHolder executeScript(String script, Client client, Configuration config) throws ExecutionException, TSIBusyException{ + TSI tsi=config.getTargetSystemInterface(client); + Action action=new Action(); + action.setType("Excecute IDB script"); + ExecutionContext ec=config.getExecutionContextMgr().getContext(action); + tsi.execAndWait(script, ec); + return new ResultHolder(action,config); + } + + /** + * execute a shell script defined in the IDB + * @param script - the name of the script to execute + * @param client - the client for which to execute the script + * @param config - config object + * @throws ExecutionException + * @throws TSIBusyException + * @return a {@link ResultHolder} for retrieving the results + */ + public static ResultHolder executeIDBScript(String scriptName, Client client, Configuration config) throws ExecutionException, TSIBusyException{ + String script=config.getGrounder().getScript(scriptName); + if(script==null)throw new IllegalArgumentException("Script <"+scriptName+"> is not defined in the IDB."); + return executeScript(script, client, config); + } + + /** + * Execute a shell script defined in the IDB in the USpace of the given action. + * The script is executed using the client information from th action<br/> + * + * @param script - the name of the script to execute + * @param action - the action in whose Uspace the script shall be run + * @param config - config object + * @throws ExecutionException + * @throws TSIBusyException + * @return a {@link ResultHolder} for retrieving the results + */ + public static ResultHolder executeIDBScript(String scriptName, Action action, Configuration config) throws ExecutionException, TSIBusyException{ + return executeIDBScript(scriptName, action.getClient(), config); + } + +} Added: xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/util/ResultHolder.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/util/ResultHolder.java (rev 0) +++ xnjs/trunk/xnjs-module-core/src/main/java/de/fzj/unicore/xnjs/util/ResultHolder.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -0,0 +1,70 @@ +package de.fzj.unicore.xnjs.util; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import de.fzj.unicore.xnjs.Configuration; +import de.fzj.unicore.xnjs.ems.Action; +import de.fzj.unicore.xnjs.ems.ExecutionException; +import de.fzj.unicore.xnjs.tsi.TSI; + +/** + * Holds the results of an execution. + * Allows to (lazily) get stdout and stderr. + * + * @author schuller + */ +public class ResultHolder { + + private Action a; + private Configuration config; + + //limit the sizes of files if these are read into memory fully + public static final int LIMIT=256000; + + public ResultHolder(Action a, Configuration config){ + this.config=config; + this.a=a; + } + + /** + * remove the working directory + * @throws ExecutionException + */ + public void done()throws ExecutionException{ + config.getExecutionContextMgr().destroyContext(a); + } + + + public Integer getExitCode(){ + return a.getExecutionContext().getExitCode(); + } + + public InputStream getInputStream(String stream)throws IOException, ExecutionException{ + TSI tsi=config.getTargetSystemInterface(a.getClient()); + return tsi.getInputStream(stream); + } + + /** + * get the contents of a file + * @param file The filename (relative to the execution directory) + * @return file content as String + * @throws IOException + * @throws ExecutionException + */ + public String readFile(String file)throws IOException, ExecutionException{ + TSI tsi=config.getTargetSystemInterface(a.getClient()); + String name=a.getExecutionContext().getWorkingDirectory()+"/"+file; + BufferedReader r=new BufferedReader(new InputStreamReader( tsi.getInputStream(name))); + ByteArrayOutputStream bos=new ByteArrayOutputStream(); + int c=0; + while( (c = r.read())!=-1){ + bos.write(c); + if(bos.size()>LIMIT)throw new IOException("Buffer size "+LIMIT+" exceeded!"); + } + return bos.toString(); + } +} Modified: xnjs/trunk/xnjs-module-core/src/test/java/de/fzj/unicore/xnjs/functional/TestTSI.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/test/java/de/fzj/unicore/xnjs/functional/TestTSI.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/test/java/de/fzj/unicore/xnjs/functional/TestTSI.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -39,7 +39,10 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import de.fzj.unicore.xnjs.aaa.Client; import de.fzj.unicore.xnjs.beans.engine.EngineConfigurationDocument.EngineConfiguration; import de.fzj.unicore.xnjs.beans.engine.PropertiesDocument.Properties; import de.fzj.unicore.xnjs.beans.engine.PropertyDocument.Property; @@ -49,6 +52,8 @@ import de.fzj.unicore.xnjs.legacy.LegacyTSI; import de.fzj.unicore.xnjs.legacy.TSIConnectionFactory; import de.fzj.unicore.xnjs.tsi.TSI; +import de.fzj.unicore.xnjs.util.ExecuteScript; +import de.fzj.unicore.xnjs.util.ResultHolder; /** * this presupposes a running legacy TSI (ports 4433/7654) @@ -75,7 +80,7 @@ p5.setValue(System.getProperty("user.name")); Property p6=props.addNewProperty(); p6.setName("CLASSICTSI.TSI_LS"); - p6.setValue("/tmp/uas/uas-testing/tsi/tsi_NOBATCH/tsi_ls"); + p6.setValue("/tmp/unicore-quickstart-6.0.0/tsi/tsi_NOBATCH/tsi_ls"); } @@ -132,6 +137,35 @@ assertTrue(new File(tmpdir+"/"+tmp+"/out").exists()); } + public void testExecAndWait()throws Exception{ + String tmpdir=System.getProperty("java.io.tmpdir"); + LegacyTSI tsi=(LegacyTSI)xnjs.getConfig().getTargetSystemInterface(null); + tsi.begin(); + tsi.cd(tmpdir); + String tmp="test_"+System.currentTimeMillis()+""; + tsi.mkdir(tmp); + tsi.cd(tmp); + tsi.commit(); + ExecutionContext ec=new ExecutionContext(); + ec.setWorkingDirectory(tmpdir+"/"+tmp+"/"); + ec.setUserName(System.getProperty("user.name")); + tsi.execAndWait("echo tsi > out",ec); + assertTrue(new File(tmpdir+"/"+tmp+"/out").exists()); + assertNotNull(ec.getExitCode()); + } + + public void testExecAndWaitHelper()throws Exception{ + Client client=new Client(); + client.setDistinguishedName("testing"); + Map<String,String>attr=new HashMap<String,String>(); + attr.put(Client.ATTRIBUTE_XLOGIN,System.getProperty("user.name")); + client.setAttributes(attr); + ResultHolder result=ExecuteScript.executeScript("/bin/date > stdout", client, xnjs.getConfig()); + System.out.println("result: "+result.getExitCode()); + String out=result.readFile("stdout"); + System.out.println("stdout: '" + out+"'"); + } + public void testLS() throws Exception { String tmpdir=System.getProperty("java.io.tmpdir"); LegacyTSI tsi=(LegacyTSI)xnjs.getConfig().getTargetSystemInterface(null); @@ -209,7 +243,6 @@ LegacyTSI tsi=(LegacyTSI)xnjs.getConfig().getTargetSystemInterface(null); String s=System.getProperty("user.home"); String r=tsi.getHomePath(System.getProperty("user.name")); - System.out.println(r); assertEquals(s,r); } Modified: xnjs/trunk/xnjs-module-core/src/test/java/de/fzj/unicore/xnjs/legacy/TestLegacyTSI.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/test/java/de/fzj/unicore/xnjs/legacy/TestLegacyTSI.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/test/java/de/fzj/unicore/xnjs/legacy/TestLegacyTSI.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -8,16 +8,21 @@ public class TestLegacyTSI extends TestCase{ public void testParseLine(){ - String s1=" RW O 442 1153064193 filename"; - String s2=" DRWXO 442232323 1153064193 filename with spaces"; - System.out.println(s1.substring(7)); - XnjsFile f1=LegacyTSI.parseLine(s1); - assertEquals("filename", f1.getPath()); - assertEquals(442, f1.getSize()); - assertEquals(new Date(1153064193), f1.getLastModified().getTime()); - XnjsFile f2=LegacyTSI.parseLine(s2); - assertEquals("filename with spaces", f2.getPath()); - assertEquals(442232323, f2.getSize()); - assertEquals(new Date(1153064193), f2.getLastModified().getTime()); + try{ + String s1=" RW O 442 1153064193 filename"; + String s2=" DRWXO 442232323 1153064193 filename with spaces"; + System.out.println(s1.substring(7)); + XnjsFile f1=LegacyTSI.parseLine(s1); + assertEquals("filename", f1.getPath()); + assertEquals(442, f1.getSize()); + assertEquals(new Date(1153064193), f1.getLastModified().getTime()); + XnjsFile f2=LegacyTSI.parseLine(s2); + assertEquals("filename with spaces", f2.getPath()); + assertEquals(442232323, f2.getSize()); + assertEquals(new Date(1153064193), f2.getLastModified().getTime()); + }catch(Exception e){ + e.printStackTrace(); + fail(); + } } } Modified: xnjs/trunk/xnjs-module-core/src/test/java/de/fzj/unicore/xnjs/simple/TestLocalTS.java =================================================================== --- xnjs/trunk/xnjs-module-core/src/test/java/de/fzj/unicore/xnjs/simple/TestLocalTS.java 2007-09-25 14:44:30 UTC (rev 1673) +++ xnjs/trunk/xnjs-module-core/src/test/java/de/fzj/unicore/xnjs/simple/TestLocalTS.java 2007-09-25 15:04:17 UTC (rev 1674) @@ -168,8 +168,33 @@ Thread.sleep(1000); String r=readTestFile(newdir+File.separator+"stdout"); assertTrue( r.contains("Hello")); + assertEquals(Integer.valueOf(0),ec.getExitCode()); } + + public void testExecAndWait()throws Exception { + tsi.begin(); + tsi.cd(tmpdir); + String newdir="newdirectory"+System.nanoTime(); + System.out.println(newdir); + tsi.mkdir(newdir); + tsi.cd(newdir); + tsi.commit(); + ExecutionContext ec=new ExecutionContext(); + ec.setWorkingDirectory(tsi.getWorkingDir()); + ec.setStdout("stdout"); + ec.setStderr("stderr"); + ec.setActionID("sdfsldf"); + File t=new File(tmpdir+File.separator+newdir); + assertTrue(t.exists()); + assertTrue(t.canWrite()); + tsi.execAndWait("/bin/echo Hello",ec); + assertNotNull(ec.getExitCode()); + String r=readTestFile(newdir+File.separator+"stdout"); + assertTrue( r.contains("Hello")); + assertEquals(Integer.valueOf(0),ec.getExitCode()); + } + public void testExecWithExtraSpacesInCmdLine()throws Exception { tsi.begin(); tsi.cd(tmpdir); @@ -252,6 +277,7 @@ private String readTestFile(String n) throws Exception { File f=new File(tmpdir+File.separator+n); + assertTrue(f.exists()); assertTrue(f.canRead()); FileInputStream fis=new FileInputStream(f); byte[] b=new byte[(int)f.length()]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |