The Mail protocol handler enables test agents to check SMTP, POP3 and IMAP services for scalability and functionality. This document shows how to use the new Mail protocol handler object in TestMaker test agents to accomplish the following:
The new Mail protocol handler object provides a simple interface to send and receive email messages in test agent scripts. See the Mail_Agent.a for examples of the Mail protocol handler in action.
Simple email messages contain address information and a text encoded message. The address information includes the host name, and the to and from addresses. The body of the message is simply a text string. Here is an example TestMaker script to illustrate how to send a simple email message:
from com.pushtotest.tool.protocolhandler import ProtocolHandler, MailBody
protocol = ProtocolHandler.getProtocol("mail")
protocol.setHost("mail.pushtotest.com")
body = MailBody( protocol.getSession() )
protocol.setBody(body)
body.setFrom( "fcohen@pushtotest.com" )
body.addAddress( "buddy@pushtotest.com" )
body.setSubject( "Hey Buddy!" )
body.setText( "Time to go skiing." )
protocol.send()
Next we look at the functions used in the script.
from com.pushtotest.tool.protocolhandler import ProtocolHandler, MailBody
The import command tells the Jython scripting language where to find the ProtocolHandler and MailBody objects.
protocol = ProtocolHandler.getProtocol("mail")
This creates a new instance of the Mail protocol object that we will reference in the protocol variable.
protocol.setHost("mail.pushtotest.com")
This tells the MailProtocol object where to find the email host. PushToTest created an email account on mail.pushtotest.com to enable you to run the test agent for real. Please do not abuse this email account.
body = MailBody( protocol.getSession() )
protocol.setBody(body)
A new MailBody object will be used to define the parameters of the email message. In typical object-oriented programming fashion test agent scripts could maintain a number of MailBody objects depending on the message to be sent.
body.setFrom( "fcohen@pushtotest.com" )
body.addAddress( "buddy@pushtotest.com" )
body.setSubject( "Hey Buddy!" )
body.setText( "Time to go skiing." )
These commands set the parameters of the email message body. In a later section we will see how to add MIME-encoded file attachments to the message body.
protocol.send()
Lastly, the send method sends the email message to the host. The send method will throw an exception when the message is unsuccessful. The exception will include text describing the problem, including badly formed From and To addresses, bad host name, or bad host connectivity.
The Mail protocol handler includes functions for reading an email host. Here is an example TestMaker script to illustrate how to receive simple email messages:
from com.pushtotest.tool.protocolhandler import ProtocolHandler, MailBody
from javax.mail import Folder
protocol = ProtocolHandler.getProtocol("mail")
protocol.setHost("fries.pushtotest.com")
protocol.setUsername("buddy")
protocol.setPassword( "email" )
response = protocol.connect()
response.setPermission( Folder.READ_ONLY )
#response.setPermission( Folder.READ_WRITE )
response.setFolder( "INBOX" )
messages = response.getMessages()
for i in messages:
print i.getFrom()[0], i.getSubject()
i.setFlag( Flag.DELETED, 1 )
response.close( 1 )
print "done"
Next we look at the functions used in the script.
from com.pushtotest.tool.protocolhandler import ProtocolHandler, MailBody
from javax.mail import Folder
The import command tells the Jython scripting language where to find the ProtocolHandler and MailBody objects. Additionally the Folder object will be used in this agent script to address email message commands such as read and delete on the mail host. protocol = ProtocolHandler.getProtocol("mail") This creates a new instance of the MailProtocol object that we will reference in the protocol variable.
protocol.setHost("fries.pushtotest.com")
protocol.setUsername("buddy")
protocol.setPassword( "email" )
These commands tell the MailProtocol object where to find the email host and which account to use. PushToTest created the buddy email account on mail.pushtotest.com to enable you to run the test agent for real. Please do not abuse this email account.
response = protocol.connect()
The connect method returns a response object that opens a session with the mail host. The response object provides the methods needed to read and delete email messages. By default the connection to the mail host uses the POP3 protocol. TestMaker includes IMAP support. To change protocols use the protocol.setProtocol("imap") method before using the connect() method.
response.setPermission( Folder.READ_ONLY )
The setPermission method instructs the mail host on our test agent's intentions. Folder.READ_ONLY by default tells the mail host we will be reading email messages but not deleting them from the host. Folder.READ_WRITE tells the mail host to expect message delete commands.
response.setFolder( "INBOX" )
The POP3 protocol uses a single folder titled INBOX by default. The IMAP protocol supports multiple folders.
messages = response.getMessages()
The getMessages() method receives a list of messages from the host.
for i in messages:
print i.getFrom()[0], i.getSubject()
print i.writeTo()
The for loop iterates through each message. The getFrom, getSubject and writeTo methods return the from, subject and message body.
i.setFlag( Flag.DELETED, 1 )
The setFlag method enables the agent script to mark the email message for deletion from the mail host. The flag is set in this loop but does not actually happen until the close() method executes. The flag has no effect if the setPermission method is not set to Folder.READ_WRITE.
response.close( 1 )
Closes the connection to the host. The close method takes a single boolean parameter. When the parameter is set to True or 1 then the close command instructs the mail host to delete any flagged messages. A False or 0 parameter tells the mail host to ignore the deleted messages.
Previously we showed how to construct a test agent script to send a simple text message. Email messages use MIME encoding to attach files, icons, and binary data to a message body. The Mail protocol handler supports MIME encoding too. The agent script below illustrates how to send an email message with a file attachment:
from com.pushtotest.tool.protocolhandler import ProtocolHandler, MailBody
from javax.activation import DataSource, FileDataSource, DataHandler
protocol = ProtocolHandler.getProtocol("mail")
protocol.setHost("fries.pushtotest.com")
body = MailBody( protocol.getSession() )
protocol.setBody(body)
body.setFrom( "fcohen@pushtotest.com" )
body.addAddress( "buddy@pushtotest.com" )
body.setSubject( "Hey Buddy!" )
body.setText( "Time to go skiing." )
part = body.getNewBodyPart()
part.setText("Big idea")
fn = "c:\\wiki_man.gif"
source = FileDataSource( fn )
part.setDataHandler( DataHandler( source ) )
part.setFileName ( source.getName() )
part = body.getNewBodyPart()
part.setText("Big ski time")
fn = "C:\\FileExchange\\Photo Library\\2001\\2001-02-23 Sagogn\\DVC00008.JPG"
source = FileDataSource( fn )
part.setDataHandler( DataHandler( source ) )
part.setFileName ( source.getName() )
protocol.send()
print "message sent."
Next we look at the functions used in the script.
from com.pushtotest.tool.protocolhandler import ProtocolHandler, MailBody
from javax.activation import DataSource, FileDataSource, DataHandler
The import command tells the Jython scripting language where to find the ProtocolHandler and MailBody objects. Additionally the DataSource, FileDataSource and DataHandler objects help to construct a multipart MIME encoded message body.
protocol = ProtocolHandler.getProtocol("mail")
As in the previous example we use the getProtocol() method to create a new Mail protocol handler that we will reference using the protocol variable.
protocol.setHost("fries.pushtotest.com")
The setHost() method defines the domain of the mail host.
body = MailBody( protocol.getSession() )
protocol.setBody(body)
Next we create a MailBody object and link it to the Mail protocol handler object. This enables us to have multiple MailBody objects to put to use.
body.setFrom( "fcohen@pushtotest.com" )
body.addAddress( "buddy@pushtotest.com" )
The setFrom() and addAddress() methods enable us to address the email message. The addresses must be SMTP email addresses. addAddress() may be used to address the single message to as many people as we wish.
body.setSubject( "Hey Buddy!" )
body.setText( "Time to go skiing." )
Next we define the subject line and body text of the email message. The setText method sets the simple body of the message. Most email clients will automatically show the simple body message text and the attached files in-line. Now we're ready to attach 2 files to this message body.
part = body.getNewBodyPart()
part.setText("Big idea")
We create a new MIME body part to hold the first file. This file is a simple GIF image residing at the C:\ directory. Any file, or even in-memory datastream, could be used instead of this particular file.
fn = "c:\\wiki_man.gif"
source = FileDataSource( fn )
part.setDataHandler( DataHandler( source ) )
part.setFileName ( source.getName() )
The setDataHandler() method identifies the input source of the file contents for when the actual email message is composed. If an email client cannot display the attached file then it displays the file name set by setFileName(). That's all there is to attaching a file. When the agent needs to attach another file to the same message the agent script get another new body part.
part = body.getNewBodyPart()
part.setText("Big ski time")
fn = "C:\\FileExchange\\Photo Library\\2001\\2001-02-23 Sagogn\\DVC00008.JPG"
source = FileDataSource( fn )
part.setDataHandler( DataHandler( source ) )
part.setFileName ( source.getName() )
The second file is titled "Big ski time" and is sent to the mail host using the same attachment procedure.
protocol.send()
The last step is to tell the Mail protocol handler to send the email message. The handler packages all necessary information and instantly sends the email message to the email server.
Previously we showed how to construct a test agent script to receive a simple text message. Email messages use MIME encoding to attach files, icons, and binary data to a message body. The Mail protocol handler supports MIME decoding too. The agent script below illustrates how to receive an email message with a file attachments. Getting attachments from an email message is more involved then sending them. MIME has no simple notation of attachments. That is mostly because MIME came after SMTP and POP3 and the IETF lost its way trying to further these email protocols while the Internet revolution was taking off. First we will show the agent script in its entirety, then we will describe how each function operates.
from com.pushtotest.tool.protocolhandler import ProtocolHandler, MailBody
from javax.mail import Folder, Multipart, Part
from java.io import File, FileInputStream, FileOutputStream
protocol = ProtocolHandler.getProtocol("mail")
protocol.setHost("fries.pushtotest.com")
protocol.setUsername("buddy")
protocol.setPassword( "email" )
response = protocol.connect()
response.setPermission( Folder.READ_ONLY )
#response.setPermission( Folder.READ_WRITE )
response.setFolder( "INBOX" )
messages = response.getMessages()
counter = 1
for msg in messages:
print msg.getFrom()[0], msg.getSubject()
#msg.setFlag( Flag.DELETED, 1 )
if msg.isMimeType( "multipart/*" ):
mp = msg.getContent()
for i in range( mp.getCount() ):
part = mp.getBodyPart( i )
disp = part.getDisposition()
if ( disp != None ) and ( ( disp == Part.ATTACHMENT ) or ( disp == Part.INLINE ) ):
inp = part.getInputStream()
out = File( "c:\\myfile" + str( counter ) )
fos = FileOutputStream( out )
more = 1
while more:
c = inp.read()
if c == -1:
more = 0
else:
fos.write(c)
inp.close()
fos.close()
print counter
counter+=1
else:
mp = msg.getContent()
print "mp=",mp
response.close( 0 )
print "done"
This agent script opens a connection to the mail host and reads each of the waiting email messages from a special email account hosted on the PushToTest service. PushToTest created an email account on mail.pushtotest.com to enable you to run the test agent for real. Please do not abuse this email account. Next we will look at the functions used in the script:
from com.pushtotest.tool.protocolhandler import ProtocolHandler, MailBody
from javax.mail import Folder, Multipart, Part
from java.io import File, FileInputStream, FileOutputStream
The import command tells the Jython scripting language where to find the ProtocolHandler and MailBody objects. Additionally the Folder, Multipart, Part, File, FileInputStream and FileOutputStream objects help to find the MIME encoded file attachments in email messages.
protocol = ProtocolHandler.getProtocol("mail")
As in the previous example we use the getProtocol() method to create a new Mail protocol handler that we will reference using the protocol variable. By default this handler will use the POP3 protocol to receive email messages from the email host.
protocol.setHost("fries.pushtotest.com")
protocol.setUsername("buddy")
protocol.setPassword( "email" )
The setHost() method defines the domain of the mail host. We also define the email account name and password to check for email.
response = protocol.connect()
The connect() method initiates a connection and establishes a session with the email host. The connect method returns a response object that opens a session with the mail host. The response object provides the methods needed to read and delete email messages.
response.setPermission( Folder.READ_ONLY )
By default the connection to the email host is Read-Only. That is email messages may be read from the host but not deleted from the host. To read and delete email messages use the Folder.READ_WRITE permission.
response.setFolder( "INBOX" )
The POP3 protocol uses a single folder titled INBOX by default. The IMAP protocol supports multiple folders. messages = response.getMessages() The getMessages() method receives a list of waiting messages from the host.
counter = 1
for msg in messages:
We look through all the waiting messages, handling each one at a time.
print msg.getFrom()[0], msg.getSubject()
The getFrom and getSubject return the from and subject of the message.
#msg.setFlag( Flag.DELETED, 1 )
Once the message is read we may want to delete it from the email host. To do so we set a flag that this message is to be deleted. Only when we close the current connection and session do the messages become deleted.
if msg.isMimeType( "multipart/*" ):
First we check to make sure the message contains a MIME encoded message body. If it is not MIME encoded then we should expect that it is a simple text message and handle it accordingly.
mp = msg.getContent()
for i in range( mp.getCount() ):
The MIME encoded message may contain one or more attachments. We loop through each attachment in the current message.
part = mp.getBodyPart( i )
disp = part.getDisposition()
if ( disp != None ) and ( ( disp == Part.ATTACHMENT ) or ( disp == Part.INLINE ) ):
Each part of the MIME encoded message body is marked with a disposition. Parts marked with a disposition of Part.ATTACHMENT are clearly attachments. However, attachments can also come across with no disposition and a non-text MIME type or a disposition of Part.INLINE. When the disposition is either Part.ATTACHMENT or Part.INLINE you can save off the content for that message part by getting an input stream from the part's contents.
inp = part.getInputStream()
out = File( "c:\\myfile" + str( counter ) )
fos = FileOutputStream( out )
more = 1
while more:
c = inp.read()
if c == -1:
more = 0
else:
fos.write(c)
inp.close()
fos.close()
These script commands move the attachment contents into a file on the local file system. It is up to you to change the File( ) declaration above to something more meaningful.
print counter
counter+=1
If this message fails the isMimeType() method above so treat it like a simple text message with no attachments.
else:
mp = msg.getContent()
print "mp=",mp
The getContent method gets the simple message body and displays it in the output window.
response.close( 1 )
Closes the connection to the host. The close method takes a single boolean parameter. When the parameter is set to True or 1 then the close command instructs the mail host to delete any flagged messages. A False or 0 parameter tells the mail host to ignore the deleted messages.
print "done"
The Mail protocol handler object provides a simple interface to send and receive email messages in test agent scripts. The Mail object uses the underlying Java Mail API, the standard Java library for working with email protocols. The Java Mail API provides SMTP, POP3 and IMAP service. The Java Mail API implements a simple API for adding new email services over time. The docs.pushtotest.com document library hosts the Javadoc comments for the Java Mail API at http://docs.pushtotest.com/javamail/javadocs/
Click here for a good tutorial on using the Java Mail API functions from Java.
Additional
documentation, product downloads and updates are at
www.PushToTest.com.
While the TestMaker software is distributed under
an open-source license, the documentation remains
(c) 2007 PushToTest. All rights
reserved.
![]()
![]()