datacommsserver/esockserver/test/TE_ESock/EsockTestSection27.cpp
changeset 0 dfb7c4ff071f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/datacommsserver/esockserver/test/TE_ESock/EsockTestSection27.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,997 @@
+// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// This contains ESock Test cases from section 27
+// Integration test for DNS Query interface.
+// Note: These tests try to make different queries to the external DNS, using network connection.
+// This test requires a network connection and a properly configured DNS.
+// See also appropriate ini file, which contains information about DNS requests for testing.
+// 
+//
+
+// EPOC includes
+#include <e32base.h>
+#include <in_sock.h>
+#include <dns_qry.h>
+
+// Test system includes
+#include "EsockTestSection27.h"
+
+
+#ifdef _DEBUG
+// Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
+// (if it could happen through user error then you should give it an explicit, documented, category + code)
+_LIT(KSpecAssert_ESockTestEsckTst, "ESockTestEsckTst");
+#endif
+
+
+const TInt  KMaxStrLen = 256;
+
+// From ../../networking/inhook6/inc/dnd_err.h
+const TInt KErrDndNameNotFound = -5120; 
+
+
+//-------------------------------------------------------------------------------------------------------
+
+
+/**
+*   test preamble: open Host Resolver for using with implicit connection 
+*/
+
+TVerdict CTestRHostRslvQuery_27::doTestStepPreambleL (void)
+    {
+    
+    TInt    ret;
+    
+    //-- open host resolver on UDP
+    Logger().WriteFormat(_L("Opening host resolver on UDP using implicit connection scenario"));
+    ret = iHostRslv.Open(iEsockSuite->iSocketServer, KAfInet, KProtocolInetUdp);
+    
+    if(ret != KErrNone)
+        {
+        Logger().WriteFormat(_L("iHostRslv.Open error code: %d"), ret);    
+        return EFail;
+        }
+    
+    return EPass;
+    }
+
+	/**
+	*   test postamble: close Host Resolver
+*/
+TVerdict CTestRHostRslvQuery_27::doTestStepPostambleL(void)
+    {
+    Logger().WriteFormat(_L("Closing host resolver"));
+    iHostRslv.Close();
+    
+    return EPass;
+    }
+
+//-------------------------------------------------------------------------------------------------------
+
+/**
+*   Read string from .ini file into 8-bit string descriptor
+*
+*   @param  aSectName section name descriptor.
+*   @param  aKeyName  key name descriptor.  
+*   @param  aStr      ref. to the 8-bit descriptor for the result string.  
+*
+*   @return ETrue on success.
+*/
+TBool   CTestRHostRslvQuery_27::GetIniFileString8(const TDesC &aSectName, const TDesC &aKeyName, TDes8& aStr)
+    {
+    TBuf<KMaxStrLen>    buff;
+    TPtrC               buffPtr(buff);
+    
+    TBool bRes = GetStringFromConfig(aSectName, aKeyName, buffPtr);
+    
+    if(bRes)
+        aStr.Copy(buffPtr);
+    
+    return bRes;
+    }
+
+	/**
+	*   read IP address from .ini file, the address may have either IPv4 or IPv6 format.
+	*
+	*   @param  aSectName section name descriptor.
+	*   @param  aKeyName  key name descriptor.  
+	*   @param  aInetAddr will contain result.
+	*
+	*   @return ETrue on success
+*/
+TBool   CTestRHostRslvQuery_27::GetIniFileIpAddr(const TDesC &aSectName, const TDesC &aKeyName, TInetAddr& aInetAddr)
+    {
+    TBuf<KMaxStrLen>    buff;
+    TPtrC               buffPtr(buff);
+    
+    TBool bRes = GetStringFromConfig(aSectName, aKeyName, buffPtr);
+    if(!bRes) 
+        return EFalse;
+    
+    return aInetAddr.Input(buffPtr) == KErrNone ? ETrue : EFalse;
+    }
+
+
+/**
+*   Internal helper function to handle DND error codes
+*   
+*   @param  aErrCode    original code to process
+*   @param  aEntryCount determines whether it was Query() 0 or QueryGetNext >0
+*   @return possibly    modified new code.
+*/
+TInt CTestRHostRslvQuery_27::ProcessDndError(TInt aErrCode, TInt aEntryCount)
+	{
+    __ASSERT_DEBUG(aEntryCount >=0, User::Panic(KSpecAssert_ESockTestEsckTst, 1));
+    
+    if(aErrCode == KErrNone)
+        return KErrNone;
+	
+    if(aErrCode == KErrNotFound || aErrCode == KErrDndNameNotFound)
+		{
+		
+        if(aEntryCount == 0)
+			{//-- no result at all for the first Query(). DNS may be down or just has no records
+			//-- int his case test is inconsistent.
+			return KErrNotFound;
+			}
+        else
+			{//-- OK, no more resulsts for QueryGetNext(), normal situation
+			return KErrNone;
+			}
+		}
+	else //-- real error
+		{    
+		TBuf<KMaxStrLen>  tmpBuf;
+		tmpBuf.Format(_L("! Query finished with error code:%d"), aErrCode);
+		Logger().WriteFormat(tmpBuf);
+		}
+	
+	return aErrCode;
+	}
+
+
+	/**
+	*   Requests all RR of type 'A' for the given host and prints them out
+	*
+	*   @param      aHostName name of the nost
+	*
+	*   @return     standard error code
+*/
+TInt    CTestRHostRslvQuery_27::ListDnsRecordsA(const TDesC8& aHostName)
+    {
+    TInt    ret = KErrNone;
+    
+    TDnsQueryBuf      dnsQryBuf;
+    TDnsRespABuf      dnsRespABuf;
+    TBuf<KMaxStrLen>  addrBuf;
+    TBuf<KMaxStrLen>  tmpBuf;
+    
+    dnsQryBuf().SetType(KDnsRRTypeA);
+    dnsQryBuf().SetData(aHostName);
+    
+    tmpBuf.Copy(aHostName);
+    addrBuf.Copy(_L("* Listing 'A' RRs for the host: "));
+    addrBuf.Append(tmpBuf);
+    Logger().WriteFormat(addrBuf);
+    
+    
+    for(TInt recCnt=0; ;++recCnt)
+        {
+        //-- make an 'A' query. 
+        if(recCnt == 0) 
+            ret = iHostRslv.Query(dnsQryBuf, dnsRespABuf);  //-- make a query and get the result
+        else
+            ret = iHostRslv.QueryGetNext(dnsRespABuf);      //-- get the rest of the RRs
+        
+        const TDnsRespA& dnsRespA = dnsRespABuf();
+        
+        
+        if(ret == KErrNone)
+            {//-- everything is all right, print record data out
+            
+            tmpBuf.Format(_L("RR Type=%d, Class=%d, TTL=%d, Address="),dnsRespA.RRType(), dnsRespA.RRClass(), dnsRespA.RRTtl());
+            dnsRespA.HostAddress().Output(addrBuf);
+            tmpBuf.Append(addrBuf);
+            Logger().WriteFormat(tmpBuf);
+            }
+        else //-- real error
+            {
+			ret = ProcessDndError(ret, recCnt);
+			break;
+            }
+		
+        }// for
+    
+    
+    Logger().WriteFormat(_L(""));
+    return ret;
+    }
+
+	/**
+	*   Requests all RR of type 'SRV' for the given host and prints them out
+	*
+	*   @param      aQuery  a query string that contains desired service, protocol and host definition
+	*
+	*   @return     standard error code
+*/
+TInt    CTestRHostRslvQuery_27::ListDnsRecordsSRV(const TDesC8& aQuery)
+    {
+    TInt    ret = KErrNone;
+    
+    TDnsQueryBuf      dnsQryBuf;
+    TDnsRespSRVBuf    dnsRespSRVBuf;
+    TBuf<KMaxStrLen>  targetBuf;
+    TBuf<KMaxStrLen>  tmpBuf;
+    
+    dnsQryBuf().SetType(KDnsRRTypeSRV);
+    dnsQryBuf().SetData(aQuery);
+    
+    tmpBuf.Copy(aQuery);
+    targetBuf.Copy(_L("* Listing 'SRV' RRs according to the query: "));
+    targetBuf.Append(tmpBuf);
+    Logger().WriteFormat(targetBuf);
+    
+    for(TInt recCnt =0; ;++recCnt)
+        {
+        //-- make an 'SRV' query. 
+        
+        if(recCnt == 0) 
+            ret = iHostRslv.Query(dnsQryBuf, dnsRespSRVBuf);  //-- make a query and get the result
+        else
+            ret = iHostRslv.QueryGetNext(dnsRespSRVBuf);      //-- get the rest of the RRs
+        
+        const TDnsRespSRV& dnsRespSRV = dnsRespSRVBuf();
+        
+        if(ret == KErrNone)
+            {//-- everything is all right, print record data out
+            
+            tmpBuf.Format(_L("RR Type=%d, Class=%d, TTL=%d, target="),dnsRespSRV.RRType(), dnsRespSRV.RRClass(), dnsRespSRV.RRTtl());
+            targetBuf.Copy(dnsRespSRV.Target());
+            tmpBuf.Append(targetBuf);
+            Logger().WriteFormat(tmpBuf);
+            }
+        else //-- real error
+            {
+			ret = ProcessDndError(ret, recCnt);
+			break;
+            }
+		
+        }// for
+    
+    Logger().WriteFormat(_L(""));
+    return ret;
+    }
+
+
+	/**
+	*   Requests all RR of type 'PTR' for the given IP address and prints them out
+	*
+	*   @param      aQuery  string containing 'PTR' query, pointer address representation, 
+	*                       e.g "3.253.253.192.in-addr.arpa"  to resolve 192.253.253.2 address.
+	*
+	*   @return     standard error code
+*/
+TInt    CTestRHostRslvQuery_27::ListDnsRecordsPTR(const TDesC8& aQuery)
+    {
+    TInt    ret = KErrNone;
+    
+    TDnsQueryBuf      dnsQryBuf;
+    TDnsRespPTRBuf    dnsRespPTRBuf;
+    TBuf<KMaxStrLen>  targetBuf;
+    TBuf<KMaxStrLen>  tmpBuf;
+    
+    dnsQryBuf().SetType(KDnsRRTypePTR);
+    dnsQryBuf().SetData(aQuery);
+    
+    targetBuf.Copy(_L("* Listing 'PTR' RRs according to the address query: "));
+    tmpBuf.Copy(aQuery);
+    targetBuf.Append(tmpBuf);
+    Logger().WriteFormat(targetBuf);
+    
+    for(TInt recCnt =0; ;++recCnt)
+        {
+        //-- make an 'PTR' query. 
+        if(recCnt == 0) 
+            ret = iHostRslv.Query(dnsQryBuf, dnsRespPTRBuf);  //-- make a query and get the result
+        else
+            ret = iHostRslv.QueryGetNext(dnsRespPTRBuf);      //-- get the rest of the RRs
+        
+        const TDnsRespPTR& dnsRespPTR = dnsRespPTRBuf();
+        
+        if(ret == KErrNone)
+            {//-- everything is all right, print record data out
+            
+            tmpBuf.Format(_L("RR Type=%d, Class=%d, TTL=%d, host name="),dnsRespPTR.RRType(), dnsRespPTR.RRClass(), dnsRespPTR.RRTtl());
+            targetBuf.Copy(dnsRespPTR.HostName());
+            tmpBuf.Append(targetBuf);
+            Logger().WriteFormat(tmpBuf);
+            }
+        else //-- real error
+            {
+			ret = ProcessDndError(ret, recCnt);
+			break;
+            }
+		
+        }// for
+    
+    Logger().WriteFormat(_L(""));
+    return ret;
+    }
+
+
+
+	/**
+	*   Requests all RR of type 'NAPTR' for the given host and prints them out
+	*
+	*   @param      aHostName name of the nost
+	*
+	*   @return     standard error code
+*/
+TInt    CTestRHostRslvQuery_27::ListDnsRecordsNAPTR(const TDesC8& aHostName)
+    {
+    TInt    ret = KErrNone;
+    
+    TDnsQueryBuf      dnsQryBuf;
+    TDnsRespNAPTRBuf  dnsRespNAPTRBuf;
+    TBuf<KMaxStrLen>  targetBuf;
+    TBuf<KMaxStrLen>  tmpBuf;
+    
+    dnsQryBuf().SetType(KDnsRRTypeNAPTR);
+    dnsQryBuf().SetData(aHostName);
+    
+    
+    targetBuf.Copy(_L("* Listing 'NAPTR' RRs for host: "));
+    tmpBuf.Copy(aHostName);
+    targetBuf.Append(tmpBuf);
+    Logger().WriteFormat(targetBuf);
+    
+    for(TInt recCnt =0; ;++recCnt)
+        {
+        //-- make an 'SRV' query. 
+        if(recCnt == 0) 
+            ret = iHostRslv.Query(dnsQryBuf, dnsRespNAPTRBuf);  //-- make a query and get the result
+        else
+            ret = iHostRslv.QueryGetNext(dnsRespNAPTRBuf);      //-- get the rest of the RRs
+        
+        const TDnsRespNAPTR& dnsRespNAPTR = dnsRespNAPTRBuf();
+        
+        if(ret == KErrNone)
+            {//-- everything is all right, print record data out
+            
+            tmpBuf.Format(_L("RR Type=%d, Class=%d, TTL=%d, Order=%d, Pref=%d, Flags="),
+                dnsRespNAPTR.RRType(), dnsRespNAPTR.RRClass(), dnsRespNAPTR.RRTtl(), dnsRespNAPTR.Order(), dnsRespNAPTR.Pref());
+            
+            targetBuf.Copy(dnsRespNAPTR.Flags());
+            tmpBuf.Append(targetBuf);
+            Logger().WriteFormat(tmpBuf);
+            
+            tmpBuf.Copy(_L("Service: "));
+            targetBuf.Copy(dnsRespNAPTR.Service());
+            tmpBuf.Append(targetBuf);
+            
+            tmpBuf.Append(_L(", Regexp: "));
+            targetBuf.Copy(dnsRespNAPTR.Regexp());
+            tmpBuf.Append(targetBuf);
+            
+            tmpBuf.Append(_L(", Replacement: "));
+            targetBuf.Copy(dnsRespNAPTR.Replacement());
+            tmpBuf.Append(targetBuf);
+            
+            Logger().WriteFormat(tmpBuf);
+            }
+        else //-- real error
+            {
+			ret = ProcessDndError(ret, recCnt);
+			break;
+            }
+		
+		
+        }// for
+    
+    Logger().WriteFormat(_L(""));
+    return ret;
+    }
+
+	/**
+	*   Requests all RR of type 'MX' for the given host and prints them out
+	*
+	*   @param      aHostName name of the nost
+	*
+	*   @return     standard error code
+*/
+TInt    CTestRHostRslvQuery_27::ListDnsRecordsMX(const TDesC8& aHostName)
+    {
+    TInt    ret = KErrNone;
+    
+    TDnsQueryBuf      dnsQryBuf;
+    TDnsRespMXBuf     dnsRespMXBuf;
+    TBuf<KMaxStrLen>  addrBuf;
+    TBuf<KMaxStrLen>  tmpBuf;
+    
+    dnsQryBuf().SetType(KDnsRRTypeMX);
+    dnsQryBuf().SetData(aHostName);
+    
+    tmpBuf.Copy(aHostName);
+    addrBuf.Copy(_L("* Listing 'MX' RRs for the host: "));
+    addrBuf.Append(tmpBuf);
+    Logger().WriteFormat(addrBuf);
+    
+    for(TInt recCnt=0; ;++recCnt)
+        {
+        //-- make an 'MX' query. 
+        if(recCnt == 0) 
+            ret = iHostRslv.Query(dnsQryBuf, dnsRespMXBuf);  //-- make a query and get the result
+        else
+            ret = iHostRslv.QueryGetNext(dnsRespMXBuf);      //-- get the rest of the RRs
+        
+        const TDnsRespMX& dnsRespMX = dnsRespMXBuf();
+        
+        if(ret == KErrNone)
+            {//-- everything is all right, print record data out
+            
+            tmpBuf.Format(_L("RR Type=%d, Class=%d, TTL=%d, Pref=%d, HostName="),dnsRespMX.RRType(), dnsRespMX.RRClass(), dnsRespMX.RRTtl(), dnsRespMX.Pref());
+            addrBuf.Copy(dnsRespMX.HostName());
+            tmpBuf.Append(addrBuf);
+            Logger().WriteFormat(tmpBuf);
+            }
+        else //-- real error
+            {
+			ret = ProcessDndError(ret, recCnt);
+			break;
+            }
+		
+        }// for
+    
+    Logger().WriteFormat(_L(""));
+    return ret;
+    }
+
+	/**
+	*   Requests all RR of type 'AAAA' for the given host and prints them out
+	*
+	*   @param      aHostName name of the nost
+	*
+	*   @return     standard error code
+*/
+TInt    CTestRHostRslvQuery_27::ListDnsRecordsAAAA(const TDesC8& aHostName)
+    {
+    TInt    ret = KErrNone;
+    
+    TDnsQueryBuf      dnsQryBuf;
+    TDnsRespAAAABuf   dnsRespAAAABuf;
+    TBuf<KMaxStrLen>  addrBuf;
+    TBuf<KMaxStrLen>  tmpBuf;
+    
+    dnsQryBuf().SetType(KDnsRRTypeAAAA);
+    dnsQryBuf().SetData(aHostName);
+    
+    tmpBuf.Copy(aHostName);
+    addrBuf.Copy(_L("* Listing 'AAAA' RRs for the host: "));
+    addrBuf.Append(tmpBuf);
+    Logger().WriteFormat(addrBuf);
+    
+    for(TInt recCnt =0; ;++recCnt)
+        {
+        //-- make an 'AAAA' query. 
+        if(recCnt == 0) 
+            ret = iHostRslv.Query(dnsQryBuf, dnsRespAAAABuf);  //-- make a query and get the result
+        else
+            ret = iHostRslv.QueryGetNext(dnsRespAAAABuf);      //-- get the rest of the RRs
+        
+        const TDnsRespAAAA& dnsRespAAAA = dnsRespAAAABuf();
+        
+        if(ret == KErrNone)
+            {//-- everything is all right, print record data out
+            
+            tmpBuf.Format(_L("RR Type=%d, Class=%d, TTL=%d, Address="),dnsRespAAAA.RRType(), dnsRespAAAA.RRClass(), dnsRespAAAA.RRTtl());
+            
+            dnsRespAAAA.HostAddress().Output(addrBuf);
+            
+            //-- remove scope modifier from the end of address representation, it may look like "%1" and confuses 'Log'
+            TInt nPos = addrBuf.Locate('%');
+            if(nPos >= 0)
+                addrBuf.SetLength(nPos);
+            
+            tmpBuf.Append(addrBuf);
+            Logger().WriteFormat(tmpBuf);
+            }
+        else //-- real error
+            {
+			ret = ProcessDndError(ret, recCnt);
+			break;
+            }
+		
+        }// for
+    
+    Logger().WriteFormat(_L(""));
+    return ret;
+    }
+
+	/**
+	* Internal helper function for calling appropriate method of listing a certain type of RR
+	*
+	*@param     apFunct pointer to the one of the ListDnsRecords* methods to be called. 
+	*@return    a number of test substeps performed and passed.
+	*@leave     KErrNotFound if some error occured
+*/
+TInt    CTestRHostRslvQuery_27::ListDnsRecordsL(TpListRRFunct apFunct)
+	{
+    TBuf8<KMaxStrLen>   queryString;
+	
+    //-- read number of entries in .ini file section
+    TInt nEntries=0;
+    if(!GetIntFromConfig(TestStepName(), _L("Entries"), nEntries) || nEntries <=0)
+        {
+		Logger().WriteFormat(_L("* Unable to read number of entries from ini file!"));
+		User::Leave(KErrNotFound);
+        }
+    //-- make DNS query for every key data entry in .ini file section
+    TBuf<64>    keyName;
+    TInt        nTstExecuted=0;
+    TInt        ret;
+    for(TInt cnt=0; cnt<nEntries; cnt++)
+		{
+        keyName.Format(_L("Param%d"), cnt+1);//-- make key name for section parameter
+        
+        if(GetIniFileString8(TestStepName(), keyName, queryString))
+			{
+            //-- list RRs for the given query string, calling given function by pointer.
+            ret = (this->*apFunct)(queryString);
+            
+            if(ret == KErrNone)
+                nTstExecuted++;
+            else 
+				if(ret != KErrNotFound)
+					TESTEL(EFalse, ret);
+				
+			}
+		} //for
+    
+    if(!nTstExecuted) //-- no tests executed
+		{
+        Logger().WriteFormat(_L("* No tests executed, probably external DNS is down"));
+		}
+	
+    return nTstExecuted;
+	}
+
+
+//-------------------------------------------------------------------------------------------------------
+//--  Test step 27.1
+//--  Testing RHostResolver::Query() of 'A' type
+//-------------------------------------------------------------------------------------------------------
+
+const TDesC& CEsockTest27_1::GetTestName()
+    {
+    // store the name of this test case
+    _LIT(ret,"Test27.1");
+	
+	return ret;
+    }
+
+TVerdict CEsockTest27_1::easyTestStepL()
+    {
+    TInt                ret = KErrNone;
+    TVerdict            verdict = EPass;
+    TInt                nTstExecuted=0;
+    Logger().WriteFormat(_L("--- Testing RHostResolver::Query() of 'A' type"));
+	
+    TRAP(ret, nTstExecuted=ListDnsRecordsL(&CEsockTest27_1::ListDnsRecordsA));
+    TESTEL(ret == KErrNone, ret);
+	
+    if(!nTstExecuted) //-- no tests executed
+        verdict=EFail;
+    
+    return verdict;
+    }
+
+//-------------------------------------------------------------------------------------------------------
+//--  Test step 27.2
+//--  Testing RHostResolver::Query() of 'SVR' type
+//-------------------------------------------------------------------------------------------------------
+
+const TDesC& CEsockTest27_2::GetTestName()
+    {
+    // store the name of this test case
+    _LIT(ret,"Test27.2");
+	
+	return ret;
+    }
+
+TVerdict CEsockTest27_2::easyTestStepL()
+    {
+    TInt                ret = KErrNone;
+    TVerdict            verdict = EPass;
+    
+    
+    Logger().WriteFormat(_L("--- Testing RHostResolver::Query() of 'SRV' type"));
+    
+    TInt    nTstExecuted=0;
+    TRAP(ret, nTstExecuted=ListDnsRecordsL(&CEsockTest27_2::ListDnsRecordsSRV));
+    TESTEL(ret == KErrNone, ret);
+	
+    if(!nTstExecuted) //-- no tests executed
+        verdict=EFail;
+	
+    return verdict;
+    }
+
+//-------------------------------------------------------------------------------------------------------
+//--  Test step 27.3
+//--  Testing RHostResolver::Query() of 'PTR' type
+//-------------------------------------------------------------------------------------------------------
+
+const TDesC& CEsockTest27_3::GetTestName()
+    {
+    // store the name of this test case
+    _LIT(ret,"Test27.3");
+	
+	return ret;
+    }
+
+TVerdict CEsockTest27_3::easyTestStepL()
+    {
+    TInt                ret = KErrNone;
+    TVerdict            verdict = EPass;
+	
+    Logger().WriteFormat(_L("--- Testing RHostResolver::Query() of 'PTR' type"));
+	
+	
+    TInt    nTstExecuted=0;
+    TRAP(ret, nTstExecuted=ListDnsRecordsL(&CEsockTest27_3::ListDnsRecordsPTR));
+    TESTEL(ret == KErrNone, ret);
+	
+    if(!nTstExecuted) //-- no tests executed
+        verdict=EFail;
+    
+    return verdict;
+    }
+
+//-------------------------------------------------------------------------------------------------------
+//--  Test step 27.4
+//--  Testing RHostResolver::Query() of 'NAPTR' type
+//-------------------------------------------------------------------------------------------------------
+
+const TDesC& CEsockTest27_4::GetTestName()
+    {
+    // store the name of this test case
+    _LIT(ret,"Test27.4");
+	
+	return ret;
+    }
+
+TVerdict CEsockTest27_4::easyTestStepL()
+    {
+    TInt                ret = KErrNone;
+    TVerdict            verdict = EPass;
+    
+    Logger().WriteFormat(_L("--- Testing RHostResolver::Query() of 'NAPTR' type"));
+    
+    TInt    nTstExecuted=0;
+    TRAP(ret, nTstExecuted=ListDnsRecordsL(&CEsockTest27_4::ListDnsRecordsNAPTR));
+    TESTEL(ret == KErrNone, ret);
+	
+    if(!nTstExecuted) //-- no tests executed
+        verdict=EFail;
+	
+    return verdict;
+    }
+
+//-------------------------------------------------------------------------------------------------------
+//--  Test step 27.5
+//--  Testing RHostResolver::Query() of 'MX' type
+//-------------------------------------------------------------------------------------------------------
+
+const TDesC& CEsockTest27_5::GetTestName()
+    {
+    // store the name of this test case
+    _LIT(ret,"Test27.5");
+	
+	return ret;
+    }
+
+TVerdict CEsockTest27_5::easyTestStepL()
+    {
+    TInt                ret = KErrNone;
+    TVerdict            verdict = EPass;
+    
+    Logger().WriteFormat(_L("Testing RHostResolver::Query() of 'MX' type"));
+	
+	
+    TInt    nTstExecuted=0;
+    TRAP(ret, nTstExecuted=ListDnsRecordsL(&CEsockTest27_5::ListDnsRecordsMX));
+    TESTEL(ret == KErrNone, ret);
+	
+    if(!nTstExecuted) //-- no tests executed
+        verdict=EFail;
+    
+    return verdict;
+    }
+
+//-------------------------------------------------------------------------------------------------------
+//--  Test step 27.6
+//--  Testing RHostResolver::Query() of 'AAAA' type
+//-------------------------------------------------------------------------------------------------------
+
+const TDesC& CEsockTest27_6::GetTestName()
+    {
+    // store the name of this test case
+    _LIT(ret,"Test27.6");
+	
+	return ret;
+    }
+
+TVerdict CEsockTest27_6::easyTestStepL()
+    {
+    TInt                ret = KErrNone;
+    TVerdict            verdict = EPass;
+	
+    Logger().WriteFormat(_L("Testing RHostResolver::Query() of 'AAAA' type"));
+    
+    TInt    nTstExecuted=0;
+    TRAP(ret, nTstExecuted=ListDnsRecordsL(&CEsockTest27_6::ListDnsRecordsAAAA));
+    TESTEL(ret == KErrNone, ret);
+	
+    if(!nTstExecuted) //-- no tests executed
+        verdict=EFail;
+    
+    return verdict;
+    }
+
+
+
+//-------------------------------------------------------------------------------------------------------
+
+/**
+*   test preamble: open Host Resolver  using RConnection
+*/
+TVerdict CTestRHostRslvQuery_27_ExplConn::doTestStepPreambleL (void)
+    {
+    TInt    ret;
+    
+    //-- open and start connection
+    Logger().WriteFormat(_L("Opening and starting connection"));
+    
+    ret = iConnection.Open(iEsockSuite->iSocketServer);
+    if(ret != KErrNone)
+        {
+        Logger().WriteFormat(_L("iConnection.Open error code: %d"), ret);    
+        return EFail;
+        }
+    
+    ret = iConnection.Start();
+    if(ret != KErrNone)
+        {
+        Logger().WriteFormat(_L("iConnection.Start error code: %d"), ret);    
+        return EFail;
+        }
+    
+    //-- open host resolver on UDP
+    Logger().WriteFormat(_L("Opening host resolver on UDP for using explicit connection"));
+    ret = iHostRslv.Open(iEsockSuite->iSocketServer, KAfInet, KProtocolInetUdp, iConnection);
+    
+    if(ret != KErrNone)
+        {
+        Logger().WriteFormat(_L("iHostRslv.Open error code: %d"), ret);    
+        return EFail;
+        }
+    
+    return EPass;
+    }
+
+	/**
+	*   test postamble: close Host Resolver
+*/
+TVerdict CTestRHostRslvQuery_27_ExplConn::doTestStepPostambleL(void)
+    {
+    Logger().WriteFormat(_L("stopping and closing connection"));
+    iConnection.Stop();
+    iConnection.Close();
+    
+    Logger().WriteFormat(_L("Closing host resolver"));
+    iHostRslv.Close();
+    
+    return EPass;
+    }
+
+//-------------------------------------------------------------------------------------------------------
+//--  Testing RHostResolver::Query() of 'A' type.
+//--  Using Explicit connection.
+//-------------------------------------------------------------------------------------------------------
+const TDesC& CEsockTest27_1_ExplConn::GetTestName()
+    {
+    // store the name of this test case
+    _LIT(ret,"Test27.7");
+	
+	return ret;
+    }
+
+TVerdict CEsockTest27_1_ExplConn::easyTestStepL()
+    {
+    TInt                ret = KErrNone;
+    TVerdict            verdict = EPass;
+    
+    Logger().WriteFormat(_L("--- Testing RHostResolver::Query() of 'A' type"));
+	
+    TInt    nTstExecuted=0;
+    TRAP(ret, nTstExecuted=ListDnsRecordsL(&CEsockTest27_1_ExplConn::ListDnsRecordsA));
+    TESTEL(ret == KErrNone, ret);
+	
+    if(!nTstExecuted) //-- no tests executed
+        verdict=EFail;
+	
+    return verdict;
+    }
+
+
+//-------------------------------------------------------------------------------------------------------
+//  Testing RHostResolver::Query() functionality on several threads:       
+//  one thread performs Query() while another GetByName()
+//-------------------------------------------------------------------------------------------------------
+
+const TDesC& CEsockTest27_1_MThread::GetTestName()
+    {
+    // store the name of this test case
+    _LIT(ret,"Test27.8");
+	
+	return ret;
+    }
+
+
+	/**
+	*   thread parameter data ctructure for Tst27_M_Thread.
+*/
+class TTestMTreadParam
+    {
+    public:
+        
+        TTestMTreadParam() : m_nTrials(0), m_nPass(0) {}
+        
+    public:
+        
+        TBuf<KMaxStrLen>    m_hostName; //< host name to be resolved
+        TInt                m_nTrials;  //< number of name resolution trials
+        TInt                m_nPass;    //< number of trials passed;
+        
+    };
+
+
+	/**
+	*   Thread function for CEsockTest27_1_MThread test.
+	*   performs several GetByName calls.
+	*
+	*   @param  aParam pointer to the thread parameter structure, see TTestMTreadParam.
+	*   @return standard error code.
+*/
+TInt Tst27_M_Thread(TAny* aParam)
+    {
+    //-- sorry, logging isn't available here.
+    //-- the output will be thread completion code and counter of successful name resolutions attempts
+    //-- see TTestMTreadParam
+    
+    TTestMTreadParam* pTestParam = static_cast<TTestMTreadParam*> (aParam);
+    
+    if(! pTestParam)
+        User::Invariant();
+    
+    TInt ret = KErrNone;
+    
+    RHostResolver hostRslv;
+    RSocketServ   socketServer;
+    
+    //-- connect to the socket server and open host resolver
+    if(socketServer.Connect() != KErrNone || hostRslv.Open(socketServer, KAfInet, KProtocolInetUdp) != KErrNone)
+        {    
+        ret = KErrGeneral;    
+        }
+    else
+        {   //-- make several name resolution attempts.
+        //-- if there was no error, increase pass counter
+        TNameEntry  nameEntry;
+        
+        for(TInt i=0; i<pTestParam->m_nTrials; ++i)
+            {
+            TInt nRes = hostRslv.GetByName(pTestParam->m_hostName, nameEntry);
+            //TSockAddr sockAddr = nameEntry().iAddr;
+            
+            if(nRes == KErrNone)
+                pTestParam->m_nPass++;    
+            }
+        }
+    
+    //-- close resolver and socket server
+    hostRslv.Close();
+    socketServer.Close();
+    
+    return ret;
+    }
+
+TVerdict CEsockTest27_1_MThread::easyTestStepL()
+    {
+    TInt                ret = KErrNone;
+    TVerdict            verdict = EPass;
+    TTestMTreadParam    threadParam;
+    TNameEntry          nameEntry;
+    
+    Logger().WriteFormat(_L("--- Testing RHostResolver::Query() functionality with several threads"));
+    
+    //-- try to check thread functionality firstly.
+    //-- try to resolve the host name and if OK, start the thread
+    TPtrC buffPtr(threadParam.m_hostName);
+    TESTL(GetStringFromConfig(TestStepName(), _L("Param1"), buffPtr)); //-- get host name to resolve
+    threadParam.m_hostName.Copy(buffPtr);
+    
+    ret = iHostRslv.GetByName(threadParam.m_hostName, nameEntry);
+    TESTL(ret == KErrNone);
+    
+    //-- set up thread parameters
+    threadParam.m_nTrials = 20; //-- how many attempts the threal will make
+    threadParam.m_nPass   = 0;
+    
+    //-- start thread that will use RHostResolver simultaniously with this one.
+    Logger().WriteFormat(_L("- Creating additional thread"));
+    
+    RThread         thread;
+    TRequestStatus  reqStat;
+    
+    _LIT(KThreadName,"Test27_Thread");
+    const TInt KStackSize   =0x8000;
+    const TInt KHeapSize    =0x8000;
+    const TInt KMaxHeapSize =0x80000;
+    
+    ret=thread.Create(KThreadName, Tst27_M_Thread, KStackSize,KHeapSize, KMaxHeapSize, &threadParam);
+    TESTL(ret == KErrNone);
+    
+    thread.Resume();
+    thread.Logon(reqStat);
+    
+    Logger().WriteFormat(_L("- additional thread has started"));
+    
+    //-- now make several host resolver queries at the same time with thread that 
+    //-- makes name resolution attempts.
+    TBuf8<KMaxStrLen>   queryString;
+    TInt                nTstExecuted = 0;
+    const TInt          numTrials    = 10;
+    
+    TESTL(GetIniFileString8(TestStepName(), _L("Param2"), queryString)); //-- get the query string
+    
+    Logger().WriteFormat(_L("- making %d queries in the main thread"), numTrials);
+    
+    //-- just query SRV records several times
+    for(TInt cnt = 0; cnt < numTrials; ++cnt)
+        {
+        ret = ListDnsRecordsSRV(queryString);
+        TESTL(ret == KErrNone);
+        nTstExecuted++;
+        
+        }// for
+    
+    if(!nTstExecuted) //-- no tests executed in this thread
+        verdict=EInconclusive;
+    
+    //-- wait for the thread to finish and check the result of its job
+    Logger().WriteFormat(_L("- Waiting for additional thread to finish"));
+    User::WaitForRequest(reqStat);
+    thread.Close();
+    
+    TESTL(reqStat.Int() == KErrNone);                  //-- thread completion code
+    if( threadParam.m_nPass != threadParam.m_nTrials ) //-- check the thread's job result
+        verdict=EInconclusive;
+    
+    
+    return verdict;
+    }
+
+
+