#!/usr/local/bin/python
#==============================================================================
#
#  $Id: dopyclient,v 1.8 2001/08/04 19:23:24 mike Exp $
#
"""
   Sample DOPY client program.
   
   Usage:
      dopyclient [-v] [threads=none|select|com|func] [<server-host>]
   
   dopyclient attaches to the DOPY server program on the given host (using
   the local host name if non is specified) and performs a suite of test 
   message invocations.

   The "-v" option increases verbosity: tracebacks are shown.
   
"""
#
#  Copyright (C) 1999 Michael A. Muller
#
#  Permission is granted to use, modify and redistribute this code,
#  providing that the following conditions are met:
#
#  1) This copyright/licensing notice must remain intact.
#  2) If the code is modified and redistributed, the modifications must 
#  include documentation indicating that the code has been modified.
#  3) The author(s) of this code must be indemnified and held harmless
#  against any damage resulting from the use of this code.
#
#  This code comes with ABSOLUTELY NO WARRANTEE, not even the implied 
#  warrantee of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
#
#  $Log: dopyclient,v $
#  Revision 1.8  2001/08/04 19:23:24  mike
#  Added support for multiple threading modes.
#
#  Revision 1.7  1999/07/09 13:48:47  mike
#  Added tests for persistence services.
#
#  Revision 1.6  1999/06/16 14:32:22  mike
#  First cut at name services.
#
#  Revision 1.5  1999/06/14 17:50:15  mike
#  Added the ability to preserve tracebacks across remote method invocations.
#
#  Revision 1.4  1999/06/11 14:03:55  mike
#  Made remote objects transportable.
#
#  Revision 1.3  1999/04/24 20:58:13  mike
#  Cleaned up for distribution.
#
#
#==============================================================================

import os, sys

# remove the current directory from the search path so that this runs ok
# from the dopy library directory
if sys.path[0] in ('', os.curdir):
   del sys.path[0]

import dopy.tcp
from dopy import tb

import socket

# get command line parms
threadMode = -1
verbose = 0
host = socket.gethostname()
for arg in sys.argv[1:]:
   if arg[:8] == 'threads=':
      threadMode = \
         {
         'none': dopy.THRD_NONE,
         'select': dopy.THRD_SELECT,
         'func': dopy.THRD_FUNC,
         'com': dopy.THRD_COM
         }.get(arg[8:], -1)
      
      if threadMode == -1:
         print 'Unknown thread mode "%s"' % arg[8:]
   elif arg == '-v':
      verbose = 1
   else:
      host = arg

# TCP/IP port number to connect to
port = 9600

# get the hub to make sure that it is initialized using the correct thread
# mode
dopy.getHub(threadMode = threadMode)

# get the remote object

print 'connecting to %s:%d...' % (host, port)
obj = dopy.tcp.remote(host, port, 'test')

# try a simple method invocation

try:
   if obj.hello('client!') == 'hello client!':
      print 'test of basic method invocation ok'
   else:
      raise Exception()
except Exception, ex:
   if verbose: print tb.errorText(ex)
   print 'test of basic method invocation failed'

# try sending keyword parms

try:
   if obj.kwparms(p1 = 100, p2 = 200) == (100, 200):
      print 'test of keyword parms ok'
   else:
      raise Exception()
except Exception, ex:
   if verbose: print tb.errorText(ex)
   print 'test of keyword parms failed'

# try calling a function that raises an exception

try:
   obj.raiseException()
except Exception, ex:
   if verbose: print tb.errorText(ex)
   print 'test of exceptions ok'
else:
   print 'test of exceptions failed'

# try getting a transient object

try:
   trans = obj.getTransient()
   if trans.hello('world') != 'hello world':
      raise Exception()
except Exception, ex:
   if verbose: print tb.errorText(ex)
   print 'test of getting transient object failed'
else:
   print 'test of getting transient object ok'

# try providing a "callback object" to the server

class Callback:
   
   def doit(self, msg):
      print 'callback received message:', msg
      return msg

try:
   hub = dopy.getHub()
   remote = hub.makeAnonObject(Callback())
   if obj.testCallback(remote, 'some text') != 'some text':
      raise Exception()
except Exception, ex:
   if verbose: print tb.errorText(ex)
   print 'test of callbacks failed'
else:
   print 'test of callbacks ok'


# try registering the remote object with the server's name service
# (won't work if the previous exercise didn't)

try:
   # get the name server object, this time by constructing an object id
   # for it
   ns = hub.makeRemoteObject('tcp:' + host + ':' + `port` + ':naming')
   
   # register a transient object with the nameserver
   ns['transient'] = obj.getTransient()
   
   # now try getting the transient object back from the nameserver
   if ns['transient'].hello('another test') != 'hello another test':
      raise Exception()
   
   # now cleanup
   del ns['transient']
   
except Exception, ex:
   if verbose: print tb.errorText(ex)
   print 'test of name service failed'
else:
   print 'test of name service ok'

try:
   # get a remote object for the persistence repository
   pos = dopy.tcp.remote(host, port, 'pos')
   
   # check to see if there is a POSTest instance
   if not pos.has_key('postest'):
      
      # try to create one!
      from dopy.pos import POSTest
      pos['postest'] = POSTest()
      print 'created POSTest instance'
   
#   inst = pos['postest']
#   inst = dopy.tcp.remote(host, port, 'pos/postest')
   inst = pos.getRemote('postest')
   inst.add(10)
   print 'postest value=', inst.get()

except Exception, ex:
   if verbose: print tb.errorText(ex)
   print 'test of persistence failed'
else:
   print 'test of persistence ok'

