You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by ch...@apache.org on 2014/09/25 16:17:45 UTC

svn commit: r1627548 - in /uima/sandbox/uima-ducc/trunk: src/main/test/ uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/

Author: challngr
Date: Thu Sep 25 14:17:45 2014
New Revision: 1627548

URL: http://svn.apache.org/r1627548
Log:
UIMA-4023 CLI / API tests

Added:
    uima/sandbox/uima-ducc/trunk/src/main/test/
    uima/sandbox/uima-ducc/trunk/src/main/test/managed_reserve.py   (with props)
    uima/sandbox/uima-ducc/trunk/src/main/test/reserve.py   (with props)
    uima/sandbox/uima-ducc/trunk/src/main/test/runall.py   (with props)
    uima/sandbox/uima-ducc/trunk/src/main/test/service.py   (with props)
    uima/sandbox/uima-ducc/trunk/src/main/test/submit.py   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ManagedReserveAndCancel.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ReserveAndCancel.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ServiceTester.java
    uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/SubmitAndCancel.java

Added: uima/sandbox/uima-ducc/trunk/src/main/test/managed_reserve.py
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/src/main/test/managed_reserve.py?rev=1627548&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/src/main/test/managed_reserve.py (added)
+++ uima/sandbox/uima-ducc/trunk/src/main/test/managed_reserve.py Thu Sep 25 14:17:45 2014
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+
+# -----------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# -----------------------------------------------------------------------
+
+import os
+import sys
+import time
+import getopt
+import subprocess
+
+# Must be self-contained using only the DUCC_HOME runtime
+#
+# Python-based CLI equivalent of the API tests
+#
+
+def usage(msg):
+    if ( msg != None ):
+        print msg
+    print "Usage: managed_reserve.py -d <DUCC_HOMe>"
+    print "   DUCC_HOME is the full path to your installed, working, and running ducc installation."
+    sys.exit(1);
+
+def mkcmd(CMD, props):
+    CMD = os.environ['DUCC_HOME'] + '/bin/' + CMD
+    for k in props.keys():
+        v = props[k]
+        if ( v == None ):
+            CMD = CMD + ' --' + k 
+        else:
+            CMD = CMD + ' --' + k + ' ' + "'" + props[k] + "'"
+    print CMD
+    return CMD
+
+def main(argv):
+
+    ducc_home = None
+    testno = 0
+
+    try:
+        opts, args = getopt.getopt(argv, 'd:', ['ducc='])
+    except:
+        usage("Invalid arguments " + ' '.join(argv))
+
+    for ( o, a ) in opts:
+        if o in ('-d', '--ducc'):
+            ducc_home = a
+        else:
+            usage("Illegal arguments")
+
+
+    if ( ducc_home == None ):
+        usage('No ducc home')
+
+    os.environ['DUCC_HOME'] = ducc_home
+    print 'Starting test'
+        
+    props = {
+        'process_memory_size' : "4",
+        'process_executable'      : '/bin/sleep',
+        'process_executable_args' : '5',
+        'scheduling_class'        : 'fixed',  
+        }
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Managed Reserve ------------------------------'
+    props['description'] = 'Managed Reservation test ' + str(testno)
+    CMD = mkcmd('ducc_process_submit', props)
+    os.system(CMD)
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Managed Reserve ------------------------------'
+    props['description'] = 'Managed Reservation test ' + str(testno)
+    props['process_executable_args'] = '300'
+    CMD = mkcmd('ducc_process_submit', props)
+    proc = subprocess.Popen(CMD, bufsize=0, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)
+    stdout = proc.stdout
+    for line in stdout:        
+        line = line.strip()
+        print line
+        toks = line.split()
+        resid = toks[2]
+
+    print 'Waiting 20 seconds for reservation to start, then cancel'
+    time.sleep(20) 
+    CMD = mkcmd('ducc_process_cancel', {'id':resid} )
+    os.system(CMD)
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Managed Reservation with attached console ------------------------------'
+    props['description'] = 'Managed Reservation test ' + str(testno)
+    props['process_executable'] = '/bin/ls'
+    props['process_executable_args'] = '-atl ' + os.environ['HOME']
+    props['attach_console'] = None
+    CMD = mkcmd('ducc_process_submit', props)
+
+    os.system(CMD)
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Managed Reservation with wait for completion ------------------------------'
+    props['description'] = 'Managed Reservation test ' + str(testno)
+    props['process_executable'] = '/bin/sleep'
+    props['process_executable_args'] = '10'
+    del props['attach_console']
+    props['wait_for_completion'] = None
+    CMD = mkcmd('ducc_process_submit', props)
+
+    os.system(CMD)
+
+    print '------------------------------ Managed Reserve Testing Complete  ------------------------------'
+
+main(sys.argv[1:])

Propchange: uima/sandbox/uima-ducc/trunk/src/main/test/managed_reserve.py
------------------------------------------------------------------------------
    svn:executable = *

Added: uima/sandbox/uima-ducc/trunk/src/main/test/reserve.py
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/src/main/test/reserve.py?rev=1627548&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/src/main/test/reserve.py (added)
+++ uima/sandbox/uima-ducc/trunk/src/main/test/reserve.py Thu Sep 25 14:17:45 2014
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+
+# -----------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# -----------------------------------------------------------------------
+
+import os
+import sys
+import time
+import getopt
+import subprocess
+
+# Must be self-contained using only the DUCC_HOME runtime
+#
+# Python-based CLI equivalent of the API tests
+#
+
+def usage(msg):
+    if ( msg != None ):
+        print msg
+    print "Usage: reserve.py -d <DUCC_HOMe>"
+    print "   DUCC_HOME is the full path to your installed, working, and running ducc installation."
+    sys.exit(1);
+
+def mkcmd(CMD, props):
+    CMD = os.environ['DUCC_HOME'] + '/bin/' + CMD
+    for k in props.keys():
+        v = props[k]
+        if ( v == None ):
+            CMD = CMD + ' --' + k 
+        else:
+            CMD = CMD + ' --' + k + ' ' + "'" + props[k] + "'"
+    print CMD
+    return CMD
+
+def main(argv):
+
+    ducc_home = None
+    testno = 0
+
+    try:
+        opts, args = getopt.getopt(argv, 'd:', ['ducc='])
+    except:
+        usage("Invalid arguments " + ' '.join(argv))
+
+    for ( o, a ) in opts:
+        if o in ('-d', '--ducc'):
+            ducc_home = a
+        else:
+            usage("Illegal arguments")
+
+
+    if ( ducc_home == None ):
+        usage('No ducc home')
+
+    os.environ['DUCC_HOME'] = ducc_home
+    print 'Starting test'
+        
+    props = {
+        'instance_memory_size' : "4",
+        'number_of_instances'  : "1",
+        'scheduling_class'              : 'fixed',  
+        }
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Reserve and Cancel ------------------------------'
+    props['description'] = 'Reserve test ' + str(testno)
+    CMD = mkcmd('ducc_reserve', props)
+    proc = subprocess.Popen(CMD, bufsize=0, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)
+    stdout = proc.stdout
+    for line in stdout:        
+        line = line.strip()
+        print line
+        if ( 'submitted' in line ):
+            toks = line.split()
+            resid = toks[1]
+    
+    CMD = mkcmd('ducc_unreserve', {'id': resid} )
+    os.system(CMD)
+
+    print '------------------------------ Reserve Testing Complete  ------------------------------'
+
+main(sys.argv[1:])

Propchange: uima/sandbox/uima-ducc/trunk/src/main/test/reserve.py
------------------------------------------------------------------------------
    svn:executable = *

Added: uima/sandbox/uima-ducc/trunk/src/main/test/runall.py
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/src/main/test/runall.py?rev=1627548&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/src/main/test/runall.py (added)
+++ uima/sandbox/uima-ducc/trunk/src/main/test/runall.py Thu Sep 25 14:17:45 2014
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+
+# -----------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# -----------------------------------------------------------------------
+import os
+import sys
+import getopt
+
+def usage(msg):
+    if ( msg != None ):
+        print msg
+    print "Usage: runall.py -d <DUCC_HOMe>"
+    print "   DUCC_HOME is the full path to your installed, working, and running ducc installation."
+    print ''
+    print 'This runs all the tests'
+    sys.exit(1);
+
+def main(argv):
+
+    ducc_home = None
+    testno = 0
+
+    try:
+        opts, args = getopt.getopt(argv, 'd:', ['ducc='])
+    except:
+        usage("Invalid arguments " + ' '.join(argv))
+
+    for ( o, a ) in opts:
+        if o in ('-d', '--ducc'):
+            ducc_home = a
+        else:
+            usage("Illegal arguments")
+
+
+    if ( ducc_home == None ):
+        usage('No ducc home')
+
+    os.environ['DUCC_HOME'] = ducc_home
+    os.system("./reserve.py -d " + ducc_home)
+    os.system("./managed_reserve.py -d " + ducc_home)
+    os.system("./service.py -d " + ducc_home)
+    os.system("./submit.py -d " + ducc_home)
+
+main(sys.argv[1:])

Propchange: uima/sandbox/uima-ducc/trunk/src/main/test/runall.py
------------------------------------------------------------------------------
    svn:executable = *

Added: uima/sandbox/uima-ducc/trunk/src/main/test/service.py
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/src/main/test/service.py?rev=1627548&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/src/main/test/service.py (added)
+++ uima/sandbox/uima-ducc/trunk/src/main/test/service.py Thu Sep 25 14:17:45 2014
@@ -0,0 +1,432 @@
+#!/usr/bin/env python
+
+# -----------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# -----------------------------------------------------------------------
+
+import re
+import os
+import sys
+import time
+import getopt
+import subprocess
+
+import string
+# Must be self-contained using only the DUCC_HOME runtime
+#
+# Python-based CLI equivalent of the API tests
+#
+
+class DuccPropertiesException(Exception):
+    def __init__(self, msg):
+        self.msg = msg
+
+    def __str__(self):
+        return repr(self.msg)
+
+
+class DuccProperties:
+    # copied in from ducc_base to read ducc.properties.  maybe should make into its own file some day
+    def __init__(self):
+        self.props = {}
+        self.builtin = {}
+
+    #
+    # Expand all ${} values from env or from this properties file itself
+    # The search order is:
+    #    1 look in this properties file
+    #    2 look in the environment
+    #
+    def do_subst(self, st):
+        key = None
+        p = re.compile("\\$\\{[a-zA-Z0-9_\\.\\-]+\\}")
+        ndx = 0
+        response = st.strip()
+        m = p.search(response, ndx)    
+        while ( m != None ):
+            key = m.group()[2:-1]
+            
+            val = None
+            if ( self.has_key(key) ):
+                val = self.get(key)
+            elif (self.builtin.has_key(key) ):
+                val = self.builtin[key]
+
+            if ( val != None ):    
+                response = string.replace(response, m.group() , val)
+            ndx = m.start()+1
+            m = p.search(response, ndx)
+        
+        return response
+
+    def mkitem(self, line):
+        ndx = line.find('#')   # remove comments - like the java DuccProperties
+        if ( ndx >= 0 ):
+            line = line[0:ndx]     # strip the comment
+        ndx = line.find('//')   # remove comments - like the java DuccProperties
+        if ( ndx >= 0 ):
+            line = line[0:ndx]     # strip the comment
+        line = line.strip()    # clear leading and trailing whitespace
+        if ( line == '' ):     # empty line?
+            return
+
+        mobj = re.search('[ =:]+', line)
+        if ( mobj ):
+            key = line[:mobj.start()].strip()
+            val = line[mobj.end():].strip()
+            #print 'NEXT', mobj.start(), 'END', mobj.end(), 'KEY', key, 'VAL', val
+            # val = self.do_subst(val)   # we'll do lazy subst on get instead
+            self.props[key] = val
+        else:
+            self.props[line] = None
+
+    #
+    # Load reads a properties file and adds it contents to the
+    # hash.  It may be called several times; each call updates
+    # the internal has, thus building it up.  The input file is
+    # in the form of a java-like properties file.
+    #
+    def load(self, propsfile, ducchome=None):
+        if ( not os.path.exists(propsfile) ):
+            raise DuccPropertiesException(propsfile +  ' does not exist and cannot be loaded.')
+
+        if (ducchome != None):
+            self.props['DUCC_HOME'] = ducchome
+        f = open(propsfile);
+        for line in f:
+            self.mkitem(line.strip())
+        f.close()
+
+    def load_from_manifest(self, jarfile):
+        z = zipfile.ZipFile(jarfile)
+        items = z.read('META-INF/MANIFEST.MF').split('\n')
+        for item in items:
+            self.mkitem(item)
+
+    #
+    # Try to load a properties file.  Just be silent if it doesn't exist.
+    #
+    def load_if_exists(self, propsfile):
+        if ( os.path.exists(propsfile) ):
+            return self.load(propsfile)
+        
+    #
+    # Put something into the hash.
+    #
+    def put(self, key, value):
+        self.props[key] = value
+
+    #
+    # Get something from the hash.
+    #
+    def get(self, key):
+        if ( self.props.has_key(key) ):
+            return self.do_subst(self.props[key])   # we'll do lazy subst on get instead
+        return None
+
+    #
+    # Remove an item if it exists
+    #
+    def delete(self, key):
+        if ( self.props.has_key(key) ):
+            del self.props[key]
+    #
+    # Write the has as a Java-like properties file
+    #
+    def write(self, propsfile):
+        f = open(propsfile, 'w')
+        items = self.props.items()
+        for (k, v) in items:
+            #print 'WRITING', k, '=', v
+            f.write(k + ' = ' + str(v) + '\n')
+        f.close()
+
+    #
+    # return a shallow copy of the dictionary
+    #
+    def copy_dictionary(self):
+        return self.props.copy()
+
+    #
+    # return the entries in the dictionary
+    #
+    def items(self):
+        return self.props.items()
+
+    #
+    # check to see if the key exists in the dictionary
+    #
+    def has_key(self, key):
+        return self.props.has_key(key)
+
+    #
+    # Return the length of the dictionary
+    #
+    def __len__(self):
+        return len(self.props)
+
+def usage(msg):
+    if ( msg != None ):
+        print msg
+    print "Usage: reserve.py -d <DUCC_HOMe>"
+    print "   DUCC_HOME is the full path to your installed, working, and running ducc installation."
+    sys.exit(1);
+
+def mkcmd(CMD, props):
+    CMD = os.environ['DUCC_HOME'] + '/bin/' + CMD
+    for k in props.keys():
+        v = props[k]
+        if ( v == None ):
+            CMD = CMD + ' --' + k 
+        else:
+            CMD = CMD + ' --' + k + ' ' + "'" + props[k] + "'"
+    return CMD
+
+def mkBrokerUrl(ducc_home):
+    props = DuccProperties()
+    props.load(ducc_home + '/resources/ducc.properties')
+    protocol = props.get('ducc.broker.protocol')
+    host     = props.get('ducc.broker.hostname')
+    port     = props.get('ducc.broker.port')
+    return protocol + '://' + host + ':' + port
+
+
+def waitForState(state, sid):
+    print 'Waiting for state', state
+    while True:
+        CMD = mkcmd('ducc_services', {'query':sid})
+        proc = subprocess.Popen(CMD, bufsize=0, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)
+        stdout = proc.stdout
+        for line in stdout:
+            line = line.strip()
+            if ( 'Service State' in line ):
+                if ( state in line ):
+                    return
+                else:
+                    print ' ...', line
+        time.sleep(5)
+
+
+def waitForEnable(sid):
+    print 'Waiting for service to be Enabled'
+    while True:
+        CMD = mkcmd('ducc_services', {'query':sid})
+        proc = subprocess.Popen(CMD, bufsize=0, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)
+        stdout = proc.stdout
+        for line in stdout:
+            line = line.strip()
+            if ( 'Start Mode' in line ):
+                if ( 'Enabled' in line ):
+                    return
+                else:
+                    print line
+        time.sleep(5)
+
+def waitForDisable(sid):
+    print 'Waiting for service to be Disabled'
+    while True:
+        CMD = mkcmd('ducc_services', {'query':sid})
+        proc = subprocess.Popen(CMD, bufsize=0, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)
+        stdout = proc.stdout
+        for line in stdout:
+            line = line.strip()
+            if ( 'Start Mode' in line ):
+                if ( 'Disabled' in line ):
+                    return
+                else:
+                    print line
+        time.sleep(5)
+
+def waitForStartState(state, sid):
+    print 'Waiting for service start state', state
+    while True:
+        CMD = mkcmd('ducc_services', {'query':sid})
+        proc = subprocess.Popen(CMD, bufsize=0, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)
+        stdout = proc.stdout
+        for line in stdout:
+            line = line.strip()
+            if ( 'Start Mode' in line ):
+                if ( state in line ):
+                    return
+                else:
+                    print ' ...', line
+        time.sleep(5)
+
+
+def main(argv):
+
+    ducc_home = None
+    testno = 0
+
+    try:
+        opts, args = getopt.getopt(argv, 'd:', ['ducc='])
+    except:
+        usage("Invalid arguments " + ' '.join(argv))
+
+    for ( o, a ) in opts:
+        if o in ('-d', '--ducc'):
+            ducc_home = a
+        else:
+            usage("Illegal arguments")
+
+
+    if ( ducc_home == None ):
+        usage('No ducc home')
+
+    os.environ['DUCC_HOME'] = ducc_home
+    print 'Starting test'
+
+    broker = mkBrokerUrl(ducc_home)
+    print broker
+
+    props = {
+        "process_jvm_args"      : "-Xmx100M -DdefaultBrokerURL=" + broker,
+        "classpath"             : "${DUCC_HOME}/lib/uima-ducc/examples/*:${DUCC_HOME}/apache-uima/lib/*:${DUCC_HOME}/apache-uima/apache-activemq/lib/*:${DUCC_HOME}/examples/simple/resources/service",
+        "service_ping_arguments": "broker-jmx-port=1099",
+        "environment"           : "AE_INIT_TIME=5000 AE_INIT_RANGE=1000 INIT_ERROR=0 LD_LIBRARY_PATH=/yet/a/nother/dumb/path",
+        "process_memory_size"   : "15",
+        "process_DD"            : "${DUCC_HOME}/examples/simple/resources/service/Service_FixedSleep_1.xml",
+        "scheduling_class"      : "fixed",
+        "working_directory"     : "${HOME}",
+        "service_linger"        : "30000",
+    }
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Clear services at start ------------------------------'
+    CMD = mkcmd('ducc_services', {'query':None})
+    proc = subprocess.Popen(CMD, bufsize=0, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)
+    stdout = proc.stdout
+    for line in stdout:
+        line = line.strip()
+        print line
+        if ( 'Service Class' in line ):
+            toks = line.split()
+            sid = toks[6]
+            user = re.split('[\[\]]', toks[7] )[1]
+            if ( user == os.environ['LOGNAME'] ):
+                print 'Unregister service', user, sid, line
+                os.system(mkcmd('ducc_services', {'unregister':sid}))
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Register ------------------------------'
+    props['description'] = 'Service test ' + str(testno)
+    props['register'] = None
+    CMD = mkcmd('ducc_services', props)
+    proc = subprocess.Popen(CMD, bufsize=0, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)
+    stdout = proc.stdout
+    for line in stdout:
+        line = line.strip()
+        print line
+        if ( 'succeeded' in line ):
+            toks = line.split()
+            sid = re.split('[\[\]]', toks[7] )[1]
+    print '======= service id', sid
+
+    time.sleep(3)
+    os.system(mkcmd('ducc_services', {'query':None}))
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Start ------------------------------'
+    os.system(mkcmd('ducc_services', {'start':sid}))
+    waitForState("Available", sid)
+    print "Service is started:"
+    os.system(mkcmd('ducc_services', {'query':sid}))
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Stop ------------------------------'
+    os.system(mkcmd('ducc_services', {'stop':sid}))
+    waitForState("Stopped", sid)
+    print "Service is stopped:"
+    os.system(mkcmd('ducc_services', {'query':sid}))
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Enable ------------------------------'
+    os.system(mkcmd('ducc_services', {'enable':sid}))
+    waitForEnable(sid)
+    os.system(mkcmd('ducc_services', {'query':sid}))
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Disable ------------------------------'
+    os.system(mkcmd('ducc_services', {'disable':sid}))
+    waitForDisable(sid)
+    os.system(mkcmd('ducc_services', {'query':sid}))
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Modify ------------------------------'
+    os.system(mkcmd('ducc_services', {'enable':sid}))      # first enable it
+    waitForEnable(sid)
+    os.system(mkcmd('ducc_services', {'query':sid}))
+    os.system(mkcmd('ducc_services', {'modify':sid, 'autostart':'true'}))
+
+    print 'Waiting for service to start'
+    waitForState("Available", sid)
+    os.system(mkcmd('ducc_services', {'query':sid}))
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Switch to reference start 1 ------------------------------'
+    os.system(mkcmd('ducc_services', {'modify':sid, 'autostart':'false'}))
+    waitForStartState('manual', sid)      # this can take a few moments
+    os.system(mkcmd('ducc_services', {'observe_references':sid}))      # first enable it
+    waitForStartState('reference', sid)
+    print 'Waiting for service to linger stop'
+    waitForState("Stopped", sid)
+    os.system(mkcmd('ducc_services', {'query':sid}))
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Switch to reference start 2 ------------------------------'
+    print 'Start service in manual mode then switch to reference'
+    os.system(mkcmd('ducc_services', {'start':sid} ))
+    waitForState("Available", sid)
+    os.system(mkcmd('ducc_services', {'query':sid}))
+    os.system(mkcmd('ducc_services', {'observe_references':sid}))      # first enable it
+    waitForStartState('reference', sid)
+    os.system(mkcmd('ducc_services', {'query':sid}))
+
+    print 'Waiting for service to linger stop'
+    waitForState("Stopped", sid)
+    os.system(mkcmd('ducc_services', {'query':sid}))
+
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Switch to reference start 3 ------------------------------'
+    print 'Start service in manual mode then switch to reference, then back before it stops'
+    os.system(mkcmd('ducc_services', {'start':sid} ))                # start in manual
+    waitForState("Available", sid)
+    os.system(mkcmd('ducc_services', {'query':sid}))
+
+    os.system(mkcmd('ducc_services', {'observe_references':sid}))    # swith to reference
+    waitForStartState('reference', sid)
+    os.system(mkcmd('ducc_services', {'query':sid}))
+
+    os.system(mkcmd('ducc_services', {'ignore_references':sid}))      # switch back to manual
+    waitForStartState('manual', sid)
+    os.system(mkcmd('ducc_services', {'query':sid}))
+
+    os.system(mkcmd('ducc_services', {'stop':sid} ))                 # done, stop
+    print 'Waiting for service to linger stop'
+    waitForState("Stopped", sid)
+    os.system(mkcmd('ducc_services', {'query':sid}))
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Unregister ------------------------------'
+    print 'Unregisteres the service before completion of the test.'
+    os.system(mkcmd('ducc_services', {'unregister':sid} ))                # start in manual
+
+    print '------------------------------ Service Testing Complete  ------------------------------'
+
+main(sys.argv[1:])

Propchange: uima/sandbox/uima-ducc/trunk/src/main/test/service.py
------------------------------------------------------------------------------
    svn:executable = *

Added: uima/sandbox/uima-ducc/trunk/src/main/test/submit.py
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/src/main/test/submit.py?rev=1627548&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/src/main/test/submit.py (added)
+++ uima/sandbox/uima-ducc/trunk/src/main/test/submit.py Thu Sep 25 14:17:45 2014
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+
+# -----------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# -----------------------------------------------------------------------
+
+import os
+import sys
+import time
+import getopt
+import subprocess
+
+# Must be self-contained using only the DUCC_HOME runtime
+#
+# Python-based CLI equivalent of the API tests
+#
+
+def usage(msg):
+    if ( msg != None ):
+        print msg
+    print "Usage: submit.py -d <DUCC_HOMe>"
+    print "   DUCC_HOME is the full path to your installed, working, and running ducc installation."
+    sys.exit(1);
+
+def mkcmd(CMD, props):
+
+    CMD = os.environ['DUCC_HOME'] + '/bin/' + CMD
+    for k in props.keys():
+        v = props[k]
+        if ( v == None ):
+            CMD = CMD + ' --' + k 
+        else:
+            CMD = CMD + ' --' + k + ' ' + "'" + props[k] + "'"
+    print CMD
+    return CMD
+
+def main(argv):
+
+    ducc_home = None
+    testno = 0
+
+    try:
+        opts, args = getopt.getopt(argv, 'd:', ['ducc='])
+    except:
+        usage("Invalid arguments " + ' '.join(argv))
+
+    for ( o, a ) in opts:
+        if o in ('-d', '--ducc'):
+            ducc_home = a
+        else:
+            usage("Illegal arguments")
+
+
+    if ( ducc_home == None ):
+        usage('No ducc home')
+
+    os.environ['DUCC_HOME'] = ducc_home
+    print 'Starting test'
+        
+    props = {
+        'driver_descriptor_CR'          : 'org.apache.uima.ducc.test.randomsleep.FixedSleepCR',
+        'driver_descriptor_CR_overrides': 'jobfile=' + ducc_home + '/examples/simple/1.inputs compression=10 error_rate=0.0',
+        'driver_jvm_args'               : '-Xmx500M',
+        
+        'process_descriptor_AE'         : 'org.apache.uima.ducc.test.randomsleep.FixedSleepAE',
+        'process_memory_size'           : '2',
+        'classpath'                     : ducc_home + '/lib/uima-ducc/examples/*',
+        'process_jvm_args'              : '-Xmx100M ',
+        'process_thread_count'          : '2',
+        'process_per_item_time_max'     : '5',
+        'environment'                   : 'AE_INIT_TIME=5 AE_INIT_RANGE=5 INIT_ERROR=0 LD_LIBRARY_PATH=/yet/a/nother/dumb/path',
+        'process_deployments_max'       : '999',
+        
+        'scheduling_class'              : 'normal',  
+        'working_directory'             : os.environ['HOME'],
+        }
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Submit ------------------------------'
+    props['description'] = 'Submit test ' + str(testno)
+    CMD = mkcmd('ducc_submit', props)
+    os.system(CMD)
+
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Submit and Cancel ------------------------------'
+    props['description'] = 'Submit test ' + str(testno)
+    CMD = mkcmd('ducc_submit', props)
+    os.system(CMD)
+    proc = subprocess.Popen(CMD, bufsize=0, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)
+    stdout = proc.stdout
+    for line in stdout:
+        line = line.strip()
+        toks = line.split()
+
+    print ' ... pause 10 seconds and then cancel ...'
+    time.sleep(10)
+
+    CMD = mkcmd('ducc_cancel', {'id': toks[1]})
+    os.system(CMD)
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Submit And Wait For Completion ------------------------------'
+    props['description'] = 'Submit test ' + str(testno)
+    props['wait_for_completion'] = None 
+    CMD = mkcmd('ducc_submit', props)
+    os.system(CMD)
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Submit With Attached Console ------------------------------'
+    del props['wait_for_completion']
+    props['description'] = 'Submit test ' + str(testno)
+    props['attach_console'] = None 
+    CMD = mkcmd('ducc_submit', props)
+    os.system(CMD)
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Submit All In One Local ------------------------------'
+    del props['attach_console']
+    props['description'] = 'Submit test ' + str(testno)
+    props['all_in_one'] = 'local'
+    CMD = mkcmd('ducc_submit', props)
+    os.system(CMD)
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Submit All In One Remote ------------------------------'
+    props['description'] = 'Submit test ' + str(testno)
+    props['all_in_one'] = 'remote'
+    props['scheduling_class'] = 'fixed'
+    CMD = mkcmd('ducc_submit', props)
+    os.system(CMD)
+
+    testno = testno + 1
+    print '------------------------------ Test', testno, 'Submit All In One Bogus ------------------------------'
+    props['description'] = 'Submit test ' + str(testno)
+    props['all_in_one'] = 'bogus'
+    CMD = mkcmd('ducc_submit', props)
+    os.system(CMD)
+
+    print '------------------------------ Submit Testing Complete  ------------------------------'
+
+main(sys.argv[1:])

Propchange: uima/sandbox/uima-ducc/trunk/src/main/test/submit.py
------------------------------------------------------------------------------
    svn:executable = *

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ManagedReserveAndCancel.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ManagedReserveAndCancel.java?rev=1627548&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ManagedReserveAndCancel.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ManagedReserveAndCancel.java Thu Sep 25 14:17:45 2014
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+
+package org.apache.uima.ducc.cli.test;
+
+import java.util.Properties;
+
+import org.apache.uima.ducc.cli.DuccManagedReservationCancel;
+import org.apache.uima.ducc.cli.DuccManagedReservationSubmit;
+import org.apache.uima.ducc.cli.IDuccCallback;
+
+public class ManagedReserveAndCancel
+{
+
+    public static void main(String[] args) 
+    {
+
+        try {
+            Properties reserve_props = new Properties();
+            int testid = 1;
+            reserve_props.setProperty("description", "Managed Reserve And Cancel " + testid++);
+            reserve_props.setProperty("process_memory_size", "4");
+            reserve_props.setProperty("process_executable", "/bin/sleep");
+            reserve_props.setProperty("process_executable_args", "5");
+            reserve_props.setProperty("scheduling_class", "fixed");
+
+            DuccManagedReservationSubmit reserve;
+
+
+            System.out.println("------------------------------ Managed Reservation Sleep Normal ------------------------------");
+            reserve = new DuccManagedReservationSubmit(reserve_props);
+            if ( reserve.execute() ) {
+                System.out.println("Managed reservation " + reserve.getDuccId() + " submitted successfully, rc =" + reserve.getReturnCode());
+            } else {
+                System.out.println("Managed reservation submit failed, rc = " + reserve.getReturnCode());
+            }
+
+            System.out.println("------------------------------ Managed Reservation Sleep and Cancel ------------------------------");
+            reserve_props.setProperty("description", "Managed Reserve And Cancel " + testid++);
+            reserve_props.setProperty("process_executable_args", "30");
+            reserve = new DuccManagedReservationSubmit(reserve_props);
+            if ( reserve.execute() ) {
+                System.out.println("Managed reservation " + reserve.getDuccId() + " submitted successfully, rc =" + reserve.getReturnCode());
+            } else {
+                System.out.println("Managed reservation submit failed, rc = " + reserve.getReturnCode());
+            }
+
+            Thread.sleep(10000);
+            Properties cancel_props = new Properties();
+            cancel_props.setProperty("id", ""+reserve.getDuccId());
+            DuccManagedReservationCancel cancel = new DuccManagedReservationCancel(cancel_props);
+            if ( cancel.execute() ) {
+                System.out.println("Reservation " + cancel.getDuccId() + " cancelled, rc = " + reserve.getReturnCode() + " " + cancel.getResponseMessage());
+            } else {                
+                System.out.println("Reservation " + cancel.getDuccId() + " cancel failed, rc = " + reserve.getReturnCode() + " " + cancel.getResponseMessage());
+            }
+
+            System.out.println("------------------------------ Managed Reservation ls with Attached Console ------------------------------");
+            reserve_props.setProperty("description", "Managed Reserve And Cancel " + testid++);
+            reserve_props.setProperty("process_executable", "/bin/ls");
+            reserve_props.setProperty("process_executable_args", "-atl ${HOME}*");
+            reserve_props.setProperty("attach_console", "true");
+            reserve = new DuccManagedReservationSubmit(reserve_props);
+            if ( reserve.execute() ) {
+                System.out.println("Managed reservation " + reserve.getDuccId() + " submitted successfully, rc =" + reserve.getReturnCode());
+            } else {
+                System.out.println("Managed reservation submit failed, rc = " + reserve.getReturnCode());
+            }
+
+
+            System.out.println("------------------------------ Managed Reservation ls Wait For Completion ------------------------------");
+            reserve_props.setProperty("description", "Managed Reserve And Cancel " + testid++);
+            reserve_props.setProperty("process_executable", "/bin/ls");
+            reserve_props.setProperty("process_executable_args", "-atl ${HOME}");
+            reserve_props.setProperty("attach_console", "true");
+            reserve_props.setProperty("wait_for_completion", "true");
+            reserve = new DuccManagedReservationSubmit(reserve_props);
+            if ( reserve.execute() ) {
+                System.out.println("Managed reservation " + reserve.getDuccId() + " submitted successfully, rc =" + reserve.getReturnCode());
+            } else {
+                System.out.println("Managed reservation submit failed, rc = " + reserve.getReturnCode());
+            }
+
+            System.out.println("------------------------------ Managed Reservation ls With Callback ------------------------------");
+            MyCallback cb = new MyCallback();
+            reserve_props.setProperty("description", "Managed Reserve And Cancel " + testid++);
+            reserve_props.setProperty("process_executable", "/bin/ls");
+            reserve_props.setProperty("process_executable_args", "-atl ${HOME}");
+            reserve_props.setProperty("attach_console", "true");
+            reserve_props.setProperty("wait_for_completion", "true");
+            reserve = new DuccManagedReservationSubmit(reserve_props, cb);
+            if ( reserve.execute() ) {
+                System.out.println("Managed reservation " + reserve.getDuccId() + " submitted successfully, rc =" + reserve.getReturnCode());
+            } else {
+                System.out.println("Managed reservation submit failed, rc = " + reserve.getReturnCode());
+            }
+
+
+            // Must see this, otherwise something is crashing that we didn't expect
+            System.out.println("------------------------------ Reservation Test Ends ------------------------------");
+
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        
+    }
+    
+    static class MyCallback
+        implements IDuccCallback
+    {
+        public void console(int pnum, String  msg)
+        {
+            System.out.println("---> " + pnum + " " + msg);
+        }
+
+        public void status(String msg)
+        {
+            System.out.println("---> " +msg);
+        }
+    }
+
+}

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ReserveAndCancel.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ReserveAndCancel.java?rev=1627548&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ReserveAndCancel.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ReserveAndCancel.java Thu Sep 25 14:17:45 2014
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+
+package org.apache.uima.ducc.cli.test;
+
+import java.util.Properties;
+
+import org.apache.uima.ducc.cli.DuccReservationCancel;
+import org.apache.uima.ducc.cli.DuccReservationSubmit;
+import org.apache.uima.ducc.cli.IDuccCallback;
+
+public class ReserveAndCancel
+{
+
+    public static void main(String[] args) 
+    {
+
+        try {
+            Properties reserve_props = new Properties();
+            DuccReservationSubmit reserve;
+            int testid = 1;
+
+            System.out.println("------------------------------ Reserve Normal ------------------------------");
+            reserve_props.setProperty("description", "Reserve And Cancel " + testid++);
+            reserve_props.setProperty("instance_memory_size", "4");
+            reserve_props.setProperty("number_of_instances", "2");
+            reserve_props.setProperty("scheduling_class", "fixed");
+            reserve = new DuccReservationSubmit(reserve_props);
+            if ( reserve.execute() ) {
+                System.out.println("Reservation " + reserve.getDuccId() + " successful, rc =" + reserve.getReturnCode() + ": " + reserve.getHostsAsString());
+                String[] hosts = reserve.getHosts();
+                System.out.println("" + hosts.length + " hosts assigned");
+                if ( hosts.length > 0 ) {
+                    for ( String h : reserve.getHosts() ) {
+                        System.out.println("   " + h);
+                    }
+                }
+
+            } else {
+                System.out.println("Reservation failed, rc = " + reserve.getReturnCode());
+            }
+
+
+            Properties cancel_props = new Properties();
+            cancel_props.setProperty("id", ""+reserve.getDuccId());
+            DuccReservationCancel cancel = new DuccReservationCancel(cancel_props);
+            if ( cancel.execute() ) {
+                System.out.println("Reservation " + cancel.getDuccId() + " cancelled, rc = " + reserve.getReturnCode() + " " + cancel.getResponseMessage());
+            } else {                
+                System.out.println("Reservation " + cancel.getDuccId() + " cancel failed, rc = " + reserve.getReturnCode() + " " + cancel.getResponseMessage());
+            }
+
+            System.out.println("------------------------------ Reserve Fail ------------------------------");
+            reserve_props.setProperty("description", "Reserve And Cancel " + testid++);
+            reserve_props.setProperty("instance_memory_size", "99");
+            reserve_props.setProperty("number_of_instances", "99");
+            reserve_props.setProperty("scheduling_class", "fixed");
+            reserve = new DuccReservationSubmit(reserve_props);
+            if ( reserve.execute() ) {
+                System.out.println("Reservation " + reserve.getDuccId() + " successful, rc =" + reserve.getReturnCode() + ": " + reserve.getHostsAsString());
+                String[] hosts = reserve.getHosts();
+                System.out.println("" + hosts.length + " hosts assigned");
+                if ( hosts.length > 0 ) {
+                    for ( String h : reserve.getHosts() ) {
+                        System.out.println("   " + h);
+                    }
+                }
+            } else {
+                System.out.println("Reservation failed, rc = " + reserve.getReturnCode());
+            }
+
+            System.out.println("------------------------------ Cancel Fail ------------------------------");
+            cancel_props.setProperty("id", "99999999999999");
+            cancel = new DuccReservationCancel(cancel_props);
+            if ( cancel.execute() ) {
+                System.out.println("Reservation " + cancel.getDuccId() + " cancelled, rc = " + cancel.getReturnCode() + " " + cancel.getResponseMessage());
+            } else {                
+                System.out.println("Reservation " + cancel.getDuccId() + " cancel failed, rc = " + cancel.getReturnCode() + " " + cancel.getResponseMessage());
+            }
+
+            // Must see this, otherwise something is crashing that we didn't expect
+            System.out.println("------------------------------ Reservation Test Ends ------------------------------");
+
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        
+    }
+    
+    static class MyCallback
+        implements IDuccCallback
+    {
+        public void console(int pnum, String  msg)
+        {
+            System.out.println("---> " + pnum + " " + msg);
+        }
+
+        public void status(String msg)
+        {
+            System.out.println("---> " +msg);
+        }
+    }
+
+}

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ServiceTester.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ServiceTester.java?rev=1627548&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ServiceTester.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/ServiceTester.java Thu Sep 25 14:17:45 2014
@@ -0,0 +1,516 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+
+package org.apache.uima.ducc.cli.test;
+
+import java.io.FileInputStream;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.uima.ducc.cli.DuccServiceApi;
+import org.apache.uima.ducc.cli.IDuccCallback;
+import org.apache.uima.ducc.common.IServiceStatistics;
+import org.apache.uima.ducc.common.utils.DuccProperties;
+import org.apache.uima.ducc.common.utils.id.ADuccId;
+import org.apache.uima.ducc.transport.event.sm.IServiceDescription;
+import org.apache.uima.ducc.transport.event.sm.IServiceReply;
+
+
+// things to do here ...
+//    register a service
+//    unrgister a service
+//    query a service
+//    modify a service
+//    start
+//    stop
+//    observe
+//    ignore
+//    enable
+//    disable
+
+public class ServiceTester
+{
+
+    static String[] props = {
+        "--description",            "Test Service 1",
+        "--process_jvm_args",       "-Xmx100M -DdefaultBrokerURL=",  // note broken, gets fixed in a while
+        "--classpath",              "${DUCC_HOME}/lib/uima-ducc/examples/*:${DUCC_HOME}/apache-uima/lib/*:${DUCC_HOME}/apache-uima/apache-activemq/lib/*:${DUCC_HOME}/examples/simple/resources/service",
+        "--service_ping_arguments", "broker-jmx-port=1099",
+        "--environment",            "AE_INIT_TIME=5000 AE_INIT_RANGE=1000 INIT_ERROR=0 LD_LIBRARY_PATH=/yet/a/nother/dumb/path",
+        "--process_memory_size",    "15",
+        "--process_DD",             "${DUCC_HOME}/examples/simple/resources/service/Service_FixedSleep_1.xml",
+        "--scheduling_class",       "fixed",
+        "--working_directory",       "${HOME}",
+        "--service_linger",         "30000",
+    };
+
+    /**
+     * Must look into ducc.properties to find the broker.
+     */
+    static String mkBrokerString(String ducc_home)
+    	throws Exception
+    {
+        DuccProperties props = new DuccProperties();
+        props.load(new FileInputStream(ducc_home + "/resources/ducc.properties"));
+        String proto = props.getStringProperty("ducc.broker.protocol");
+        String host = props.getStringProperty("ducc.broker.hostname");
+        String port = props.getStringProperty("ducc.broker.port");
+        return proto + "://" + host + ":" + port;
+    }
+
+    
+    // replicates ServiceDescription toString in order to test the interfaces
+     static String serviceToString(IServiceDescription desc)
+     {
+         StringBuffer sb = new StringBuffer();
+
+         String type = desc.getType().toString();
+
+         sb.append("Service: ");
+         sb.append(type);
+         sb.append(":");
+         sb.append(desc.getEndpoint());
+
+         if ( type.equals("UimaAs") ) {
+             sb.append(":");
+             sb.append(desc.getBroker());
+         }
+         sb.append("\n");
+
+         String subclass = desc.getSubclass().toString();
+         sb.append("   Service Class     : ");
+         sb.append(subclass);
+         if ( subclass.equals("Registered")) {
+             sb.append(" as ID ");
+             sb.append(desc.getId());
+             sb.append(" Owner[");
+             sb.append(desc.getUser());
+             sb.append("] instances[");
+             sb.append(Integer.toString(desc.getInstances()));
+             sb.append("] linger[");
+             sb.append(Long.toString(desc.getLinger()));
+             sb.append("]");
+       }
+       sb.append("\n");
+
+       sb.append("   Implementors      : ");
+       List<ADuccId> implementors = desc.getImplementors();
+       if ( implementors.size() > 0 ) {
+           for (ADuccId id : implementors) {
+               sb.append(id.getFriendly());
+               sb.append(" ");
+           }
+       } else {
+           sb.append("(N/A)");
+       }
+       sb.append("\n");
+         
+       sb.append("   References        : ");
+       List<ADuccId> references = desc.getReferences();
+       if ( references.size() > 0 ) {
+           for ( ADuccId id : references ) {
+               sb.append(id.getFriendly());
+               sb.append(" ");
+           }
+       } else {
+           sb.append("None");
+       }
+       sb.append("\n");
+       
+       sb.append("   Dependencies      : ");
+       Map<String, String> dependencies = desc.getDependencies();
+       if ( dependencies == null ) {
+           sb.append("none\n");
+       } else {
+           sb.append("\n");
+           for ( String s : dependencies.keySet() ) {
+               sb.append("      ");
+               sb.append(s);
+               sb.append(": ");
+               sb.append(dependencies.get(s));
+               sb.append("\n");
+           }
+       }
+
+       sb.append("   Service State     : ");
+       sb.append(desc.getServiceState());
+       sb.append("\n");
+
+       sb.append("   Ping Active       : ");
+       sb.append(desc.isActive());
+       sb.append("\n");
+
+       sb.append("   Start Mode        : ");
+       boolean autostart = desc.isAutostart();
+       boolean reference_start = desc.isReferenceStart();
+
+       if ( autostart )            { sb.append("autostart"); }
+       else if ( reference_start ) { sb.append("reference"); }
+       else {
+           if ( implementors.size() > 0 ) { 
+               sb.append("manual"); 
+           } else {
+               sb.append("stopped");
+           }
+       }
+        
+       if ( desc.isEnabled() ) {
+           sb.append(", Enabled");
+       } else {
+           sb.append(", Disabled; reason: ");
+           sb.append(desc.getDisableReason());
+       }
+       sb.append("\n");
+
+       sb.append("   Last Use          : ");
+       sb.append(desc.getLastUseString());
+       sb.append("\n");
+
+       sb.append("   Registration Date : ");
+       sb.append(desc.getRegistrationDate());
+       sb.append("\n");
+
+       String error_string = desc.getErrorString();
+       if ( error_string != null ) {
+           sb.append("   Errors            : ");
+           sb.append(error_string);
+           sb.append("\n");
+       }
+
+       sb.append("   Service Statistics: ");
+       IServiceStatistics qstats = desc.getQstats();
+       if ( qstats == null ) {
+           sb.append("None\n");
+       } else {
+           sb.append("\n       ");            
+           sb.append(qstats.toString());
+           sb.append("\n");
+       }
+         return sb.toString();
+     }
+
+    public static List<IServiceDescription> query()
+    {
+        DuccServiceApi api;
+        IServiceReply reply;
+
+        System.out.println("Query");
+        List<IServiceDescription> ret = null;
+        try {
+            api = new DuccServiceApi(null);
+            reply = api.query(new String[] {"--query"} );
+	   
+            ret = reply.getServiceDescriptions();
+
+			if ( ret.size() == 0 ) {
+			    System.out.println("No services in query.");
+			} else {
+			    for (IServiceDescription d : ret) {                
+			        System.out.println(serviceToString(d));         // this exercises the IServiceDescription methods
+			        System.out.println("       ------------------------------");
+			        System.out.println(d.toString());               // this is the actual query as returned by SM
+			    }
+			}
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+			System.exit(1);
+		}
+        return ret;
+    }
+
+    static IServiceDescription getServiceDescription(String id)
+    {
+        try {
+			DuccServiceApi api = new DuccServiceApi(null);
+			IServiceReply qreply;
+			List<IServiceDescription> service_list;
+			
+			qreply = api.query(new String[] {"--query", id});      // general service reply
+			service_list = qreply.getServiceDescriptions();        // list of service descriptions
+			return service_list.get(0);                            // failure here is test failure, no need to check too carefully
+		} catch (Exception e) {
+            System.out.println("Query failed, terminating test.");
+			e.printStackTrace();
+            System.exit(1);
+		}
+        return null; // impossible, stupid eclipse
+    }
+
+    static void waitForState(String desired_state, String id)
+    {
+        try {
+
+			IServiceDescription desc = getServiceDescription(id);
+			System.out.println("Waiting for service " + id + " to reach state " + desired_state);
+			String state = desc.getServiceState().toString();
+			while ( !state.equals(desired_state) ) {
+			    System.out.println(" ... " + state);
+			    Thread.sleep(5000);
+			    desc = getServiceDescription(id);
+			    state = desc.getServiceState().toString();
+			}
+		} catch (Exception e) {
+            System.out.println("Query failed, terminating test.");
+            System.exit(1);
+			e.printStackTrace();
+		}
+    }
+
+
+    static void waitForStartState(String desired_state, String id)
+    {
+        try {
+
+            do {
+                IServiceDescription desc = getServiceDescription(id);
+                List<ADuccId> implementors = desc.getImplementors();
+                System.out.println("Waiting for service " + id + " to reach start state " + desired_state);
+                System.out.println(" ... autostart " + desc.isAutostart() + " reference " + desc.isReferenceStart() + " n_implementors " + implementors.size());
+
+                if ( desc.isAutostart()      && desired_state.equals("autostart") ) return;
+                if ( desc.isReferenceStart() && desired_state.equals("reference") ) return;
+
+                if ( !desc.isAutostart() && (!desc.isReferenceStart()) ) {
+                    if ( implementors.size() >  0 && desired_state.equals("manual") ) return;
+                    if ( implementors.size() == 0 && desired_state.equals("stopped") ) return;
+                }
+                
+                System.out.println(" ... autostart " + desc.isAutostart() + " reference " + desc.isReferenceStart() + " n_implementors " + implementors.size());
+			    Thread.sleep(5000);
+			} while ( true );
+		} catch (Exception e) {
+            System.out.println("Query failed, terminating test.");
+            System.exit(1);
+			e.printStackTrace();
+		}
+    }
+    
+    public static void main(String[] args)
+    {
+        DuccServiceApi api;
+        IDuccCallback cb = new MyCallback();
+        IServiceReply reply;
+
+        try {
+            // Need broker location
+            String ducc_home = System.getProperty("DUCC_HOME");
+            if ( ducc_home == null ) {
+                throw new IllegalArgumentException("DUCC_HOME must be set into system properties.");
+            }
+            props[3] = "-Xmx100M -DdefaultBrokerURL=" + mkBrokerString(ducc_home);  // any failure, test setup is broken, don't bother with checking
+                                                                          // we'll crash soon enough if its broken
+            
+            // start by clearing all registrations owned by me
+            System.out.println("---------------------------------------- Init and Clear ----------------------------------------");
+            List<IServiceDescription> services = query();
+            if ( services.size() == 0 ) {
+                System.out.println("Init test: no services to clean");
+            } else {
+                for (IServiceDescription d : services ) {
+                    api = new DuccServiceApi(cb);
+                    System.out.println("Unregistering " + d.getId());
+                    reply = api.unregister(new String[] {"--unregister", "" + d.getId()});
+                    if ( reply.getReturnCode() ) {
+                        System.out.println("Service " + reply.getId() + " unregistered: " + reply.getEndpoint());
+                    } else {
+                        System.out.println("Service unregister failied: " + reply.getMessage());
+                    }                
+                    
+                }
+            }
+           
+            System.out.println("---------------------------------------- Register ----------------------------------------");
+			api = new DuccServiceApi(cb);
+			reply = api.register(props);
+            String service_id = "<none>";
+            if ( reply.getReturnCode() ) {
+                service_id = Long.toString(reply.getId());
+                System.out.println("Service " + service_id + " registered as " + reply.getEndpoint());
+                
+            } else {
+                System.out.println("Service register failied: " + reply.getMessage() + " terminating test.");
+                System.exit(1);
+            }
+            query();
+
+            System.out.println("---------------------------------------- Start ----------------------------------------");
+			api = new DuccServiceApi(cb);
+			reply = api.start(new String[] {"--start", "" + service_id });
+            if ( reply.getReturnCode() ) {
+                System.out.println("Service " + reply.getId() + " start requested " + reply.getEndpoint());
+            } else {
+                System.out.println("Service stop failied: " + reply.getMessage());
+            }
+            
+            // Now wait until it's Available
+            waitForState("Available", service_id);
+            
+            System.out.println("Service is started");
+            query();
+
+            System.out.println("---------------------------------------- Stop ----------------------------------------");
+			api = new DuccServiceApi(cb);
+			reply = api.stop(new String[] {"--stop", "" + service_id});
+            if ( reply.getReturnCode() ) {
+                System.out.println("Service " + reply.getId() + " stop requested " + reply.getEndpoint());
+            } else {
+                System.out.println("Service stop failied: " + reply.getMessage());
+            }
+            waitForState("Stopped", service_id);
+            System.out.println("Service is stopped");
+            query();
+
+            System.out.println("---------------------------------------- Enable ----------------------------------------");
+			api = new DuccServiceApi(cb);
+			reply = api.enable(new String[] {"--enable", "" + service_id});  // so disable has an effect
+            if ( reply.getReturnCode() ) {
+                System.out.println("Service " + reply.getId() + " enable requested " + reply.getEndpoint());
+            } else {
+                System.out.println("Service enable failied: " + reply.getMessage());
+            }
+            query();
+			
+
+            System.out.println("---------------------------------------- Disable ----------------------------------------");
+			api = new DuccServiceApi(cb);
+			reply = api.disable(new String[] {"--disable", "" + service_id});
+            if ( reply.getReturnCode() ) {
+                System.out.println("Service " + reply.getId() + " disable requested " + reply.getEndpoint());
+            } else {
+                System.out.println("Service disable failied: " + reply.getMessage());
+            }
+            query();
+			
+            System.out.println("---------------------------------------- Enable ----------------------------------------");
+			api = new DuccServiceApi(cb);
+			reply = api.enable(new String[] {"--enable", "" + service_id}); // again, so we can continue
+            if ( reply.getReturnCode() ) {
+                System.out.println("Service " + reply.getId() + " enable requested " + reply.getEndpoint());
+            } else {
+                System.out.println("Service enable failied: " + reply.getMessage());
+            }
+            query();
+
+            System.out.println("---------------------------------------- Modify ----------------------------------------");
+			api = new DuccServiceApi(cb);
+			reply = api.modify(new String[] {"--modify", "" + service_id, "--autostart", "true"}); // again, so we can continue
+            if ( reply.getReturnCode() ) {
+                System.out.println("Service " + reply.getId() + " autostart modified " + reply.getEndpoint());
+            } else {
+                System.out.println("Service autostart modified: " + reply.getMessage());
+            }
+            // wait for it to show in the query
+            waitForStartState("autostart", service_id);
+            query();
+
+            // Now wait until it's Available
+            waitForState("Available", service_id);
+            
+            System.out.println("Service is started from autostart");
+            query();
+
+
+            System.out.println("---------------------------------------- Switch to reference start part 1, from autostart off -------------------------------------");
+			api = new DuccServiceApi(cb);
+			reply = api.modify(new String[] {"--modify", "" + service_id, "--autostart", "false"}); // again, so we can continue
+            if ( reply.getReturnCode() ) {
+                System.out.println("Service " + reply.getId() + " autostart modified " + reply.getEndpoint());
+            } else {
+                System.out.println("Service autostart modify failedd: " + reply.getMessage());
+            }
+            waitForStartState("manual", service_id);
+            query();
+
+			api = new DuccServiceApi(cb);
+			reply = api.observeReferences(new String[] {"--observe_references", "" + service_id}); // again, so we can continue
+            if ( reply.getReturnCode() ) {
+                System.out.println("Service " + reply.getId() + " references being observed " + reply.getEndpoint());
+            } else {
+                System.out.println("Service cannot observe references:" + reply.getMessage());
+            }
+            waitForStartState("reference", service_id);
+            query();
+
+            waitForState("Stopped", service_id);            
+            query();
+
+            System.out.println("---------------------------------------- Switch to reference start part 2, from manual, then back ----------------------------------------");
+			api = new DuccServiceApi(cb);
+			reply = api.start(new String[] {"--start", "" + service_id}); // again, so we can continue
+            if ( reply.getReturnCode() ) {
+                System.out.println("Service " + reply.getId() + " service starting" + reply.getEndpoint());
+            } else {
+                System.out.println("Service start failed: " + reply.getMessage());
+            }
+            waitForState("Available", service_id);
+            query();
+
+			api = new DuccServiceApi(cb);
+			reply = api.observeReferences(new String[] {"--observe_references", "" + service_id}); // again, so we can continue
+            if ( reply.getReturnCode() ) {
+                System.out.println("Service " + reply.getId() + " references being observed " + reply.getEndpoint());
+            } else {
+                System.out.println("Service cannot observe references:" + reply.getMessage());
+            }
+            waitForStartState("reference", service_id);
+            query();
+
+			api = new DuccServiceApi(cb);
+			reply = api.ignoreReferences(new String[] {"--ignore_references", "" + service_id}); // again, so we can continue
+            if ( reply.getReturnCode() ) {
+                System.out.println("Service " + reply.getId() + " references being ignored " + reply.getEndpoint());
+            } else {
+                System.out.println("Service cannot ignore references:" + reply.getMessage());
+            }
+            waitForStartState("manual", service_id);
+            query();
+            
+            System.out.println("---------------------------------------- Test done, stopping service  ----------------------------------------");
+			api = new DuccServiceApi(cb);
+			reply = api.stop(new String[] {"--stop", "" + service_id});
+            if ( reply.getReturnCode() ) {
+                System.out.println("Service " + reply.getId() + " stop requested " + reply.getEndpoint());
+            } else {
+                System.out.println("Service stop failied: " + reply.getMessage());
+            }
+            waitForState("Stopped", service_id);
+            query();
+			
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+    }
+
+    static class MyCallback
+        implements IDuccCallback
+    {
+        public void console(int pnum, String  msg)
+        {
+            System.out.println("---> " + pnum + " " + msg);
+        }
+
+        public void status(String msg)
+        {
+            System.out.println("---> " +msg);
+        }
+    }
+
+}
+

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/SubmitAndCancel.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/SubmitAndCancel.java?rev=1627548&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/SubmitAndCancel.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-cli/src/test/java/org/apache/uima/ducc/cli/test/SubmitAndCancel.java Thu Sep 25 14:17:45 2014
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+*/
+package org.apache.uima.ducc.cli.test;
+
+import java.util.ArrayList;
+import java.util.Properties;
+
+import org.apache.uima.ducc.cli.DuccJobCancel;
+import org.apache.uima.ducc.cli.DuccJobSubmit;
+import org.apache.uima.ducc.cli.IDuccCallback;
+
+public class SubmitAndCancel
+{
+
+    static Properties mkproperties(String[] args)
+    {
+        Properties props = new Properties();
+        if ( args.length % 2 != 0 ) {
+            throw new IllegalStateException("Job arguments must be paired.  Found " + args.length + " arguments.");
+        }
+
+        for (int i = 0; i < args.length; i += 2) {
+            String k = args[i].substring(2);
+            String v = args[i+1];
+            props.setProperty(k, v);
+        }
+        return props;
+    }
+
+    public static void main(String[] args) 
+    {
+        String[] submit_args = new String[] {
+            "--driver_descriptor_CR",           "org.apache.uima.ducc.test.randomsleep.FixedSleepCR",
+            "--driver_descriptor_CR_overrides", "jobfile=${DUCC_HOME}/examples/simple/1.inputs compression=10 error_rate=0.0",
+            "--driver_jvm_args",                "-Xmx500M",
+            
+            "--process_descriptor_AE",          "org.apache.uima.ducc.test.randomsleep.FixedSleepAE",
+            "--process_memory_size",            "2",
+            "--classpath",                      "${DUCC_HOME}/lib/uima-ducc/examples/*",
+            "--process_jvm_args",               "-Xmx100M ",
+            "--process_thread_count",           "2",
+            "--process_per_item_time_max",      "5",
+            "--environment",                    "AE_INIT_TIME=5 AE_INIT_RANGE=5 INIT_ERROR=0 LD_LIBRARY_PATH=/yet/a/nother/dumb/path",
+            "--process_deployments_max",        "999",
+            
+            "--scheduling_class",               "normal",  
+        };
+
+        try {
+            DuccJobSubmit submit;
+
+            IDuccCallback cb = new MyCallback();
+            submit = new DuccJobSubmit(submit_args, (IDuccCallback) cb);
+            submit.setProperty("description", "Submit-And-Cancel job 1");
+            System.out.println("------------------------------ Submit with a callback ------------------------------");
+            System.out.println("Console attached: " + submit.isConsoleAttached());
+			if ( submit.execute() ) {
+                System.out.println("Job " + submit.getDuccId() + " submitted, rc = " + submit.getReturnCode());
+            } else {
+                System.out.println("Job " + submit.getDuccId() + " not submitted, rc = " + submit.getReturnCode());
+                return;
+            }
+
+            submit = new DuccJobSubmit(submit_args);
+            submit.setProperty("description", "Submit-And-Cancel job 2");
+            System.out.println("------------------------------ Submit normal ------------------------------");
+            System.out.println("Console attached: " + submit.isConsoleAttached());
+			if ( submit.execute() ) {
+                System.out.println("Job " + submit.getDuccId() + " submitted, rc = " + submit.getReturnCode());
+            } else {
+                System.out.println("Job " + submit.getDuccId() + " not submitted, rc = " + submit.getReturnCode());
+                return;
+            }
+
+            Thread.sleep(10000);
+
+            DuccJobCancel cancel = new DuccJobCancel(
+               new String[] {
+                   "--id", "" + submit.getDuccId(),
+               }
+            );
+
+            System.out.println("------------------------------ Cancel first job quickly ------------------------------");
+            if ( cancel.execute() ) {
+                System.out.println("Job " + submit.getDuccId() + " canceled, rc = " + cancel.getReturnCode());
+            } else {
+                System.out.println("Job " + submit.getDuccId() + " cancel failed, rc = " + cancel.getReturnCode());
+            }
+
+            cb = new MyCallback();         // insert a callback because the earlier one just tested the constructor
+                                           // this time the callback will actually get called from the monitor
+            submit = new DuccJobSubmit(submit_args, (IDuccCallback) cb);
+            submit.setProperty("wait_for_completion", "true");
+            submit.setProperty("description", "Submit-And-Cancel job 3");
+            System.out.println("------------------------------ Submit and wait for completion ------------------------------");
+			if ( submit.execute() ) {
+                System.out.println("Job " + submit.getDuccId() + " submitted, rc = " + submit.getReturnCode());
+            } else {
+                System.out.println("Job " + submit.getDuccId() + " not submitted, rc = " + submit.getReturnCode());
+                return;
+            }
+
+            // setProperty is broken for many things including attach_console. Copy the parms to a list and add
+            // attach console.
+            ArrayList<String> arglist = new ArrayList<String>();      // test ArrayList constructor
+            for ( String s : submit_args ) {
+                arglist.add(s);
+            }
+            arglist.add("--attach_console");
+            arglist.add("--description");
+            arglist.add("Submit-And-Cancel job 4");
+            
+
+			submit = new DuccJobSubmit(arglist);
+            System.out.println("------------------------------ Submit with attached console ------------------------------");
+            System.out.println("Console attached: " + submit.isConsoleAttached());
+			if ( submit.execute() ) {
+                System.out.println("Job " + submit.getDuccId() + " submitted, rc = " + submit.getReturnCode());
+            } else {
+                System.out.println("Job " + submit.getDuccId() + " not submitted, rc = " + submit.getReturnCode());
+                return;
+            }
+            
+
+            // Now some all-in-one variants - local
+            arglist = new ArrayList<String>();
+            for ( String s : submit_args ) {
+                arglist.add(s);
+            }
+            arglist.add("--all_in_one");
+            arglist.add("local");
+            arglist.add("--description");
+            arglist.add("Submit-And-Cancel job 5");
+
+            cb = new MyCallback(); // why not, lets go nuts
+            submit = new DuccJobSubmit(arglist, (IDuccCallback) cb);
+            System.out.println("------------------------------ Submit all_in_one local ------------------------------");
+            System.out.println("Console attached: " + submit.isConsoleAttached());
+			if ( submit.execute() ) {
+                System.out.println("Job " + submit.getDuccId() + " submitted, rc = " + submit.getReturnCode());
+            } else {
+                System.out.println("Job " + submit.getDuccId() + " not submitted, rc = " + submit.getReturnCode());
+                return;
+            }
+
+            Properties props = mkproperties(submit_args);      // test the constructor, plus easier to update
+            props.setProperty("all_in_one", "remote");
+            props.setProperty("scheduling_class", "fixed");
+            props.setProperty("description", "Submit-And-Cancel job 6");
+
+            cb = new MyCallback(); // why not, lets go nuts
+            submit = new DuccJobSubmit(props, (IDuccCallback) cb);
+            System.out.println("------------------------------ Submit all_in_one remote ------------------------------");
+            System.out.println("Console attached: " + submit.isConsoleAttached());
+			if ( submit.execute() ) {
+                System.out.println("Job " + submit.getDuccId() + " submitted, rc = " + submit.getReturnCode());
+            } else {
+                System.out.println("Job " + submit.getDuccId() + " not submitted, rc = " + submit.getReturnCode());
+                return;
+            }
+
+            props.setProperty("all_in_one", "bogus");
+            props.setProperty("description", "Submit-And-Cancel job 7");
+            props.setProperty("scheduling_class", "fixed");
+
+            cb = new MyCallback(); // why not, lets go nuts
+            try {
+                System.out.println("------------------------------ Submit all_in_one bogus, should fail ------------------------------");
+                System.out.println("Console attached: " + submit.isConsoleAttached());
+                submit = new DuccJobSubmit(props, (IDuccCallback) cb);
+                if ( submit.execute() ) {
+                    System.out.println("Job " + submit.getDuccId() + " submitted, rc = " + submit.getReturnCode());
+                } else {
+                    System.out.println("Job " + submit.getDuccId() + " not submitted, rc = " + submit.getReturnCode());
+                    return;
+                }
+            } catch (Exception e) {
+                System.out.println(" ... Expected failure ...");
+                e.printStackTrace();
+            }
+
+            // Must see this, otherwise something is crashing that we didn't expect
+            System.out.println("------------------------------ Submit Test Ends ------------------------------");
+
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+        
+    }
+    
+    static class MyCallback
+        implements IDuccCallback
+    {
+        public void console(int pnum, String  msg)
+        {
+            System.out.println("---> " + pnum + " " + msg);
+        }
+
+        public void status(String msg)
+        {
+            System.out.println("---> " +msg);
+        }
+    }
+
+}