📄 testtransactionfsm.cxx
字号:
const char* now;
bool isWireInject = false;
if (!strncasecmp(start, "inject_wire", strlen("inject_wire")))
{
isWireInject = true;
}
else if (!strncasecmp(start, "inject_tu", strlen("inject_tu")))
{
isWireInject = false;
}
else
{
DebugLog(<< "Warning: error parsing test specification.");
TestSpecParseBuf->skipToChar('}');
TestSpecParseBuf->skipChar();
return;
}
TestSpecParseBuf->skipToChar('{');
TestSpecParseBuf->skipChar();
TestSpecParseBuf->skipWhitespace();
start = TestSpecParseBuf->position();
now = TestSpecParseBuf->skipToChar('}');
*const_cast<char*>(now) = 0;
DebugLog(<< "Injecting (isWireInject=" << isWireInject << "): " << start);
TestSpecParseBuf->skipChar();
if (isWireInject)
{
// sendToWire() is a helper function for TestTransport stuff.
// sendToWire(start);
SipMessage* message = TestSupport::makeMessage(start, true);
assert(message);
TestFSM::addMessage(client,message); // does a client->mStateMacFifo.add(message);
}
else
{
SipMessage* message = TestSupport::makeMessage(start, false);
assert(message);
client->send(*message);
}
}
void
processExpect()
{
const char* start = TestSpecParseBuf->position();
const char* now;
unsigned int expireTime = 1;
WaitNode* thisWait = new WaitNode;
assert(thisWait);
thisWait->mResponseCode = 0;
if (!strncasecmp(start, "expect_wire", strlen("expect_wire")))
{
thisWait->mIsTransport = true;
}
else if (!strncasecmp(start, "expect_tu", strlen("expect_tu")))
{
thisWait->mIsTransport = false;
}
else
{
DebugLog(<< "Warning: error parsing test specification");
TestSpecParseBuf->skipToChar('}');
TestSpecParseBuf->skipChar();
delete thisWait;
return;
}
TestSpecParseBuf->skipToChar('{');
TestSpecParseBuf->skipChar();
TestSpecParseBuf->skipWhitespace();
start = TestSpecParseBuf->position();
// We will want to get two of these in an expect_ clause.
for (int i = 0; i < 2; i++)
{
TestSpecParseBuf->skipToChar('=');
TestSpecParseBuf->skipChar();
TestSpecParseBuf->skipWhitespace();
if (!strncasecmp(start, "method", strlen("method")))
{
start = TestSpecParseBuf->position();
now = TestSpecParseBuf->skipToOneOf(ParseBuffer::Whitespace);
thisWait->mIsRequest = true;
thisWait->mMethod = getMethodType(start, now-start);
}
else if (!strncasecmp(start, "status", strlen("status")))
{
TestSpecParseBuf->skipToOneOf("0123456789");
thisWait->mIsRequest = false;
thisWait->mResponseCode = TestSpecParseBuf->integer();
}
else if (!strncasecmp(start, "timeout", strlen("timeout")))
{
TestSpecParseBuf->skipToOneOf("0123456789");
expireTime = TestSpecParseBuf->integer();
}
else
{
DebugLog(<< "Warning: error parsing test specification");
TestSpecParseBuf->skipToChar('}');
TestSpecParseBuf->skipChar();
delete thisWait;
return;
}
TestSpecParseBuf->skipWhitespace();
start = TestSpecParseBuf->position();
}
assert(thisWait);
gettimeofday(&thisWait->mExpiry, NULL);
thisWait->mExpiry.tv_sec += expireTime / 1000;
thisWait->mExpiry.tv_usec += (expireTime % 1000) * 1000;
WaitQueue.push_front(thisWait);
TestSpecParseBuf->skipToChar('}');
TestSpecParseBuf->skipChar();
/*
cerr << "-> Expecting " << endl;
cerr << " mIsTransport = " << (thisWait->mIsTransport == true) << endl;
cerr << " mIsRequest = " << (thisWait->mIsRequest == true) << endl;
cerr << " mResponseCode = " << (thisWait->mResponseCode) << endl;
cerr << " mExpiry = " << (thisWait->mExpiry.tv_sec) << endl;
*/
}
void
processDelays()
{
TestSpecParseBuf->skipToChar('{');
TestSpecParseBuf->skipChar();
TestSpecParseBuf->skipWhitespace();
TestSpecParseBuf->skipToOneOf("0123456789");
int sleepLength = TestSpecParseBuf->integer();
DebugLog( << "Pausing for " << sleepLength << " ms");
// We sleep this way to avoid conflict with SIGALRM from alarm().
struct timespec ts, remainder;
ts.tv_sec = sleepLength / 1000;
ts.tv_nsec = (sleepLength % 1000) * 1000000;
while (nanosleep(&ts, &remainder) < 0)
{
ts = remainder;
}
TestSpecParseBuf->skipToChar('}');
TestSpecParseBuf->skipChar();
}
bool
processClause()
{
TestSpecParseBuf->skipWhitespace();
// Look for 'i'/'e'/'d' for inject... or expect... or delay respectively.
const char* now = TestSpecParseBuf->skipToOneOf("ied#");
switch (*now)
{
case 'i':
processInject();
break;
case 'e':
processExpect();
break;
case 'd':
processDelays();
break;
case '#':
TestSpecParseBuf->skipToChar('\n');
TestSpecParseBuf->skipChar();
break;
default:
DebugLog(<< "Warning: error parsing test specification");
TestSpecParseBuf->skipToChar('}');
TestSpecParseBuf->skipChar();
}
TestSpecParseBuf->skipWhitespace();
return !TestSpecParseBuf->eof();
}
int
main(int argc, char *argv[])
{
ProgramName = argv[0];
if (NULL == argv[1]) {
exitusage();
}
struct stat buf;
if (stat(argv[1], &buf) < 0)
{
cerr << "Error: " << strerror(errno) << endl;
exitusage();
}
ifstream testSpec;
testSpec.open(argv[1], ifstream::in);
if (!testSpec.is_open())
{
cerr << "Error: could not open "<< argv[1] << endl;
exitusage();
}
TestSpecBuf = new char[buf.st_size+1];
assert(TestSpecBuf);
testSpec.read(TestSpecBuf, buf.st_size);
TestSpecParseBuf = new ParseBuffer(TestSpecBuf, buf.st_size);
assert(TestSpecParseBuf);
int clientFd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
clientSa.sin_family = PF_INET;
clientSa.sin_addr.s_addr = inet_addr("127.0.0.1");
clientSa.sin_port = htons(PORT);
int clientFdFlags = fcntl(clientFd, F_GETFL, 0);
fcntl(clientFd, F_SETFL, clientFdFlags | O_NONBLOCK);
client = new SipStack();
assert(client);
client->addTransport(UDP, PORT);
signal(SIGALRM, processTimeouts);
// Cause a signal to be generated with setitimer for its resolution
struct itimerval timer;
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 100000; // 100 ms resolution
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 100000; // 100 ms resolution
setitimer(ITIMER_REAL, &timer, NULL);
while (processClause())
{
}
// Catch any remaining events.
processTimeouts(0);
if (!WaitQueue.empty())
{
DebugLog( << "Warning: ending with expect clauses outstanding");
++errorCount;
}
if (errorCount > 0)
{
cerr << "FAIL" << endl;
}
else
{
cerr << "PASS" << endl;
}
return errorCount;
}
#else
#include <iostream>
int
main(int argc, char *argv[])
{
std::cout << argv[0] << ": Sorry. This test driver hasn't been ported "
"to Windows yet." << std::endl;
return -1;
}
#endif
/* ====================================================================
* The Vovida Software License, Version 1.0
*
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
* and "Vovida Open Communication Application Library (VOCAL)" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact vocal@vovida.org.
*
* 4. Products derived from this software may not be called "VOCAL", nor
* may "VOCAL" appear in their name, without prior written
* permission of Vovida Networks, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* ====================================================================
*
* This software consists of voluntary contributions made by Vovida
* Networks, Inc. and many individuals on behalf of Vovida Networks,
* Inc. For more information on Vovida Networks, Inc., please see
* <http://www.vovida.org/>.
*
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -