Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

7457 lines (6388 sloc) 284.973 kB
/** @file
Implements unit test for SDK APIs
@section license License
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.
*/
// Turn off -Wdeprecated so that we can still test our own deprecated APIs.
#if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3)
#pragma GCC diagnostic ignored "-Wdeprecated"
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#include "ink_config.h"
#include <sys/types.h>
#include <errno.h>
// extern int errno;
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "Regression.h"
#include "api/ts/ts.h"
#include "api/ts/experimental.h"
#include "I_RecCore.h"
#include <sys/types.h>
#include "InkAPITestTool.cc"
#include "http/HttpSM.h"
#include "ts/TestBox.h"
#define TC_PASS 1
#define TC_FAIL 0
#define UTDBG_TAG "sdk_ut"
/******************************************************************************/
/* Use SDK_RPRINT to report failure or success for each test case */
int
SDK_RPRINT(RegressionTest *t, const char *api_name, const char *testcase_name, int status, const char *err_details_format, ...)
{
int l;
char buffer[8192];
char format2[8192];
snprintf(format2, sizeof(format2), "[%s] %s : [%s] <<%s>> { %s }\n", t->name, api_name, testcase_name,
status == TC_PASS ? "PASS" : "FAIL", err_details_format);
va_list ap;
va_start(ap, err_details_format);
l = ink_bvsprintf(buffer, format2, ap);
va_end(ap);
fputs(buffer, stderr);
return (l);
}
/*
REGRESSION_TEST(SDK_<test_name>)(RegressionTest *t, int atype, int *pstatus)
RegressionTest *test is a pointer on object that will run the test.
Do not modify.
int atype is one of:
REGRESSION_TEST_NONE
REGRESSION_TEST_QUICK
REGRESSION_TEST_NIGHTLY
REGRESSION_TEST_EXTENDED
int *pstatus should be set to one of:
REGRESSION_TEST_PASSED
REGRESSION_TEST_INPROGRESS
REGRESSION_TEST_FAILED
REGRESSION_TEST_NOT_RUN
Note: pstatus is polled and can be used for asynchroneous tests.
*/
/* Misc */
////////////////////////////////////////////////
// SDK_API_TSTrafficServerVersionGet
//
// Unit Test for API: TSTrafficServerVersionGet
////////////////////////////////////////////////
REGRESSION_TEST(SDK_API_TSTrafficServerVersionGet)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
*pstatus = REGRESSION_TEST_INPROGRESS;
/* Assume the UT runs on TS5.0 and higher */
const char *ts_version = TSTrafficServerVersionGet();
if (!ts_version) {
SDK_RPRINT(test, "TSTrafficServerVersionGet", "TestCase1", TC_FAIL, "can't get traffic server version");
*pstatus = REGRESSION_TEST_FAILED;
return;
}
int major_ts_version = 0;
int minor_ts_version = 0;
int patch_ts_version = 0;
// coverity[secure_coding]
if (sscanf(ts_version, "%d.%d.%d", &major_ts_version, &minor_ts_version, &patch_ts_version) != 3) {
SDK_RPRINT(test, "TSTrafficServerVersionGet", "TestCase2", TC_FAIL, "traffic server version format is incorrect");
*pstatus = REGRESSION_TEST_FAILED;
return;
}
if (major_ts_version < 2) {
SDK_RPRINT(test, "TSTrafficServerVersionGet", "TestCase3", TC_FAIL, "traffic server major version is incorrect");
*pstatus = REGRESSION_TEST_FAILED;
return;
}
SDK_RPRINT(test, "TSTrafficServerVersionGet", "TestCase1", TC_PASS, "ok");
*pstatus = REGRESSION_TEST_PASSED;
return;
}
////////////////////////////////////////////////
// SDK_API_TSPluginDirGet
//
// Unit Test for API: TSPluginDirGet
// TSInstallDirGet
////////////////////////////////////////////////
REGRESSION_TEST(SDK_API_TSPluginDirGet)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
*pstatus = REGRESSION_TEST_INPROGRESS;
const char *plugin_dir = TSPluginDirGet();
const char *install_dir = TSInstallDirGet();
if (!plugin_dir) {
SDK_RPRINT(test, "TSPluginDirGet", "TestCase1", TC_FAIL, "can't get plugin dir");
*pstatus = REGRESSION_TEST_FAILED;
return;
}
if (!install_dir) {
SDK_RPRINT(test, "TSInstallDirGet", "TestCase1", TC_FAIL, "can't get installation dir");
*pstatus = REGRESSION_TEST_FAILED;
return;
}
if (strstr(plugin_dir, TS_BUILD_LIBEXECDIR) == NULL) {
SDK_RPRINT(test, "TSPluginDirGet", "TestCase2", TC_FAIL, "plugin dir(%s) is incorrect, expected (%s) in path.", plugin_dir,
TS_BUILD_LIBEXECDIR);
*pstatus = REGRESSION_TEST_FAILED;
return;
}
if (strstr(plugin_dir, install_dir) == NULL) {
SDK_RPRINT(test, "TSInstallDirGet", "TestCase2", TC_FAIL, "install dir is incorrect");
*pstatus = REGRESSION_TEST_FAILED;
return;
}
SDK_RPRINT(test, "TSPluginDirGet", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(test, "TSInstallDirGet", "TestCase1", TC_PASS, "ok");
*pstatus = REGRESSION_TEST_PASSED;
return;
}
/* TSConfig */
////////////////////////////////////////////////
// SDK_API_TSConfig
//
// Unit Test for API: TSConfigSet
// TSConfigGet
// TSConfigRelease
// TSConfigDataGet
////////////////////////////////////////////////
static int my_config_id = -1;
typedef struct {
const char *a;
const char *b;
} ConfigData;
static void
config_destroy_func(void *data)
{
ConfigData *config = (ConfigData *)data;
TSfree(config);
return;
}
REGRESSION_TEST(SDK_API_TSConfig)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
*pstatus = REGRESSION_TEST_INPROGRESS;
ConfigData *config = (ConfigData *)TSmalloc(sizeof(ConfigData));
config->a = "unit";
config->b = "test";
my_config_id = TSConfigSet(0, config, config_destroy_func);
TSConfig test_config = NULL;
test_config = TSConfigGet(my_config_id);
if (!test_config) {
SDK_RPRINT(test, "TSConfigSet", "TestCase1", TC_FAIL, "can't correctly set global config structure");
SDK_RPRINT(test, "TSConfigGet", "TestCase1", TC_FAIL, "can't correctly get global config structure");
TSConfigRelease(my_config_id, reinterpret_cast<TSConfig>(config));
*pstatus = REGRESSION_TEST_FAILED;
return;
}
if (TSConfigDataGet(test_config) != config) {
SDK_RPRINT(test, "TSConfigDataGet", "TestCase1", TC_FAIL, "failed to get config data");
TSConfigRelease(my_config_id, reinterpret_cast<TSConfig>(config));
*pstatus = REGRESSION_TEST_FAILED;
return;
}
SDK_RPRINT(test, "TSConfigGet", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(test, "TSConfigSet", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(test, "TSConfigDataGet", "TestCase1", TC_PASS, "ok");
TSConfigRelease(my_config_id, reinterpret_cast<TSConfig>(config));
*pstatus = REGRESSION_TEST_PASSED;
return;
}
/* TSNetVConn */
//////////////////////////////////////////////
// SDK_API_TSNetVConn
//
// Unit Test for API: TSNetVConnRemoteIPGet
// TSNetVConnRemotePortGet
// TSNetAccept
// TSNetConnect
//////////////////////////////////////////////
struct SDK_NetVConn_Params {
SDK_NetVConn_Params(const char *_a, RegressionTest *_t, int *_p) : buffer(NULL), api(_a), port(0), test(_t), pstatus(_p), vc(NULL)
{
this->status.client = this->status.server = REGRESSION_TEST_INPROGRESS;
}
~SDK_NetVConn_Params()
{
if (this->buffer) {
TSIOBufferDestroy(this->buffer);
}
if (this->vc) {
TSVConnClose(this->vc);
}
}
TSIOBuffer buffer;
const char *api;
unsigned short port;
RegressionTest *test;
int *pstatus;
TSVConn vc;
struct {
int client;
int server;
} status;
};
int
server_handler(TSCont contp, TSEvent event, void *data)
{
SDK_NetVConn_Params *params = (SDK_NetVConn_Params *)TSContDataGet(contp);
if (event == TS_EVENT_NET_ACCEPT) {
// Kick off a read so that we can receive an EOS event.
SDK_RPRINT(params->test, params->api, "ServerEvent NET_ACCEPT", TC_PASS, "ok");
params->buffer = TSIOBufferCreate();
params->vc = (TSVConn)data;
TSVConnRead((TSVConn)data, contp, params->buffer, 100);
} else if (event == TS_EVENT_VCONN_EOS) {
// The server end of the test passes if it receives an EOF event. This means that it must have
// connected to the endpoint. Since this always happens *after* the accept, we know that it is
// safe to delete the params.
TSContDestroy(contp);
SDK_RPRINT(params->test, params->api, "ServerEvent EOS", TC_PASS, "ok");
*params->pstatus = REGRESSION_TEST_PASSED;
delete params;
} else {
SDK_RPRINT(params->test, params->api, "ServerEvent", TC_FAIL, "received unexpected event %d", event);
*params->pstatus = REGRESSION_TEST_FAILED;
delete params;
}
return 1;
}
int
client_handler(TSCont contp, TSEvent event, void *data)
{
SDK_NetVConn_Params *params = (SDK_NetVConn_Params *)TSContDataGet(contp);
if (event == TS_EVENT_NET_CONNECT_FAILED) {
SDK_RPRINT(params->test, params->api, "ClientConnect", TC_FAIL, "can't connect to server");
*params->pstatus = REGRESSION_TEST_FAILED;
// no need to continue, return
// Fix me: how to deal with server side cont?
TSContDestroy(contp);
return 1;
} else {
sockaddr const *addr = TSNetVConnRemoteAddrGet(static_cast<TSVConn>(data));
uint16_t input_server_port = ats_ip_port_host_order(addr);
sleep(1); // XXX this sleep ensures the server end gets the accept event.
if (ats_is_ip_loopback(addr)) {
SDK_RPRINT(params->test, params->api, "TSNetVConnRemoteIPGet", TC_PASS, "ok");
} else {
ip_text_buffer s, ipb;
IpEndpoint loopback;
ats_ip4_set(&loopback, htonl(INADDR_LOOPBACK));
SDK_RPRINT(params->test, params->api, "TSNetVConnRemoteIPGet", TC_FAIL, "server ip [%s] is incorrect - expected [%s]",
ats_ip_ntop(addr, s, sizeof s), ats_ip_ntop(&loopback.sa, ipb, sizeof ipb));
TSContDestroy(contp);
// Fix me: how to deal with server side cont?
*params->pstatus = REGRESSION_TEST_FAILED;
return 1;
}
if (input_server_port == params->port) {
SDK_RPRINT(params->test, params->api, "TSNetVConnRemotePortGet", TC_PASS, "ok");
} else {
SDK_RPRINT(params->test, params->api, "TSNetVConnRemotePortGet", TC_FAIL, "server port [%d] is incorrect -- expected [%d]",
input_server_port, params->port);
TSContDestroy(contp);
// Fix me: how to deal with server side cont?
*params->pstatus = REGRESSION_TEST_FAILED;
return 1;
}
SDK_RPRINT(params->test, params->api, "TSNetConnect", TC_PASS, "ok");
// XXX We really ought to do a write/read exchange with the server. The sleep above works around this.
// Looks good from the client end. Next we disconnect so that the server end can set the final test status.
TSVConnClose((TSVConn)data);
}
TSContDestroy(contp);
return 1;
}
REGRESSION_TEST(SDK_API_TSNetVConn)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
*pstatus = REGRESSION_TEST_INPROGRESS;
SDK_NetVConn_Params *params = new SDK_NetVConn_Params("TSNetAccept", test, pstatus);
params->port = 12345;
TSCont server_cont = TSContCreate(server_handler, TSMutexCreate());
TSCont client_cont = TSContCreate(client_handler, TSMutexCreate());
TSContDataSet(server_cont, params);
TSContDataSet(client_cont, params);
TSNetAccept(server_cont, params->port, -1, 0);
IpEndpoint addr;
ats_ip4_set(&addr, htonl(INADDR_LOOPBACK), htons(params->port));
TSNetConnect(client_cont, &addr.sa);
}
REGRESSION_TEST(SDK_API_TSPortDescriptor)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
*pstatus = REGRESSION_TEST_INPROGRESS;
TSPortDescriptor port;
char desc[64];
SDK_NetVConn_Params *params = new SDK_NetVConn_Params("TSPortDescriptorAccept", test, pstatus);
TSCont server_cont = TSContCreate(server_handler, TSMutexCreate());
TSCont client_cont = TSContCreate(client_handler, TSMutexCreate());
params->port = 54321;
TSContDataSet(server_cont, params);
TSContDataSet(client_cont, params);
port = TSPortDescriptorParse(NULL);
if (port) {
SDK_RPRINT(test, "TSPortDescriptorParse", "NULL port descriptor", TC_FAIL, "TSPortDescriptorParse(NULL) returned %s", port);
*pstatus = REGRESSION_TEST_FAILED;
return;
}
snprintf(desc, sizeof(desc), "%u", params->port);
port = TSPortDescriptorParse(desc);
if (TSPortDescriptorAccept(port, server_cont) == TS_ERROR) {
SDK_RPRINT(test, "TSPortDescriptorParse", "Basic port descriptor", TC_FAIL, "TSPortDescriptorParse(%s) returned TS_ERROR",
desc);
*pstatus = REGRESSION_TEST_FAILED;
return;
}
IpEndpoint addr;
ats_ip4_set(&addr, htonl(INADDR_LOOPBACK), htons(params->port));
TSNetConnect(client_cont, &addr.sa);
}
/* TSCache, TSVConn, TSVIO */
//////////////////////////////////////////////
// SDK_API_TSCache
//
// Unit Test for API: TSCacheReady
// TSCacheWrite
// TSCacheRead
// TSCacheKeyCreate
// TSCacheKeyDigestSet
// TSVConnCacheObjectSizeGet
// TSVConnClose
// TSVConnClosedGet
// TSVConnRead
// TSVConnReadVIOGet
// TSVConnWrite
// TSVConnWriteVIOGet
// TSVIOBufferGet
// TSVIOContGet
// TSVIOMutexGet
// TSVIONBytesGet
// TSVIONBytesSet
// TSVIONDoneGet
// TSVIONDoneSet
// TSVIONTodoGet
// TSVIOReaderGet
// TSVIOReenable
// TSVIOVConnGet
//////////////////////////////////////////////
// TSVConnAbort can't be tested
// Fix me: test TSVConnShutdown, TSCacheKeyDataTypeSet,
// TSCacheKeyHostNameSet, TSCacheKeyPinnedSet
// Logic of the test:
// - write OBJECT_SIZE bytes in the cache in 3 shots
// (OBJECT_SIZE/2, then OBJECT_SIZE-100 and finally OBJECT_SIZE)
// - read object from the cache
// - remove it from the cache
// - try to read it (should faild)
#define OBJECT_SIZE 100000 // size of the object we'll write/read/remove in cache
RegressionTest *SDK_Cache_test;
int *SDK_Cache_pstatus;
static char content[OBJECT_SIZE];
static int read_counter = 0;
typedef struct {
TSIOBuffer bufp;
TSIOBuffer out_bufp;
TSIOBufferReader readerp;
TSIOBufferReader out_readerp;
TSVConn write_vconnp;
TSVConn read_vconnp;
TSVIO read_vio;
TSVIO write_vio;
TSCacheKey key;
} CacheVConnStruct;
int
cache_handler(TSCont contp, TSEvent event, void *data)
{
Debug("sdk_ut_cache_write", "Event %d data %p", event, data);
CacheVConnStruct *cache_vconn = (CacheVConnStruct *)TSContDataGet(contp);
TSIOBufferBlock blockp;
char *ptr_block;
int64_t ntodo, ndone, nbytes, towrite, avail, content_length;
switch (event) {
case TS_EVENT_CACHE_OPEN_WRITE:
Debug(UTDBG_TAG "_cache_event", "TS_EVENT_CACHE_OPEN_WRITE %d %p", event, data);
SDK_RPRINT(SDK_Cache_test, "TSCacheWrite", "TestCase1", TC_PASS, "ok");
// data is write_vc
cache_vconn->write_vconnp = (TSVConn)data;
// Create buffers/readers to write and read data into the cache
cache_vconn->bufp = TSIOBufferCreate();
cache_vconn->readerp = TSIOBufferReaderAlloc(cache_vconn->bufp);
cache_vconn->out_bufp = TSIOBufferCreate();
cache_vconn->out_readerp = TSIOBufferReaderAlloc(cache_vconn->out_bufp);
// Write content into upstream IOBuffer
ntodo = OBJECT_SIZE;
ndone = 0;
while (ntodo > 0) {
blockp = TSIOBufferStart(cache_vconn->bufp);
ptr_block = TSIOBufferBlockWriteStart(blockp, &avail);
towrite = ((ntodo < avail) ? ntodo : avail);
memcpy(ptr_block, content + ndone, towrite);
TSIOBufferProduce(cache_vconn->bufp, towrite);
ntodo -= towrite;
ndone += towrite;
}
// first write half of the data. To test TSVIOReenable
cache_vconn->write_vio = TSVConnWrite((TSVConn)data, contp, cache_vconn->readerp, OBJECT_SIZE / 2);
return 1;
case TS_EVENT_CACHE_OPEN_WRITE_FAILED:
Debug(UTDBG_TAG "_cache_event", "TS_EVENT_CACHE_OPEN_WRITE_FAILED %d %p", event, data);
SDK_RPRINT(SDK_Cache_test, "TSCacheWrite", "TestCase1", TC_FAIL, "can't open cache vc, edtata = %p", data);
TSReleaseAssert(!"cache");
// no need to continue, return
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
case TS_EVENT_CACHE_OPEN_READ:
Debug(UTDBG_TAG "_cache_event", "TS_EVENT_CACHE_OPEN_READ %d %p", event, data);
if (read_counter == 2) {
SDK_RPRINT(SDK_Cache_test, "TSCacheRead", "TestCase2", TC_FAIL, "shouldn't open cache vc");
// no need to continue, return
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
}
SDK_RPRINT(SDK_Cache_test, "TSCacheRead", "TestCase1", TC_PASS, "ok");
cache_vconn->read_vconnp = (TSVConn)data;
content_length = TSVConnCacheObjectSizeGet(cache_vconn->read_vconnp);
Debug(UTDBG_TAG "_cache_read", "In cache open read [Content-Length: %" PRId64 "]", content_length);
if (content_length != OBJECT_SIZE) {
SDK_RPRINT(SDK_Cache_test, "TSVConnCacheObjectSizeGet", "TestCase1", TC_FAIL, "cached data size is incorrect");
// no need to continue, return
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
} else {
SDK_RPRINT(SDK_Cache_test, "TSVConnCacheObjectSizeGet", "TestCase1", TC_PASS, "ok");
cache_vconn->read_vio = TSVConnRead((TSVConn)data, contp, cache_vconn->out_bufp, content_length);
}
return 1;
case TS_EVENT_CACHE_OPEN_READ_FAILED:
Debug(UTDBG_TAG "_cache_event", "TS_EVENT_CACHE_OPEN_READ_FAILED %d %p", event, data);
if (read_counter == 1) {
SDK_RPRINT(SDK_Cache_test, "TSCacheRead", "TestCase1", TC_FAIL, "can't open cache vc");
// no need to continue, return
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
}
SDK_RPRINT(SDK_Cache_test, "TSCacheRead", "TestCase2", TC_PASS, "ok");
// ok, all tests passed!
break;
case TS_EVENT_CACHE_REMOVE:
Debug(UTDBG_TAG "_cache_event", "TS_EVENT_CACHE_REMOVE %d %p", event, data);
SDK_RPRINT(SDK_Cache_test, "TSCacheRemove", "TestCase1", TC_PASS, "ok");
// read the data which has been removed
read_counter++;
TSCacheRead(contp, cache_vconn->key);
return 1;
case TS_EVENT_CACHE_REMOVE_FAILED:
Debug(UTDBG_TAG "_cache_event", "TS_EVENT_CACHE_REMOVE_FAILED %d %p", event, data);
SDK_RPRINT(SDK_Cache_test, "TSCacheRemove", "TestCase1", TC_FAIL, "can't remove cached item");
// no need to continue, return
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
case TS_EVENT_VCONN_WRITE_COMPLETE:
Debug(UTDBG_TAG "_cache_event", "TS_EVENT_VCONN_WRITE_COMPLETE %d %p", event, data);
// VConn/VIO APIs
nbytes = TSVIONBytesGet(cache_vconn->write_vio);
ndone = TSVIONDoneGet(cache_vconn->write_vio);
ntodo = TSVIONTodoGet(cache_vconn->write_vio);
Debug(UTDBG_TAG "_cache_write", "Nbytes=%" PRId64 " Ndone=%" PRId64 " Ntodo=%" PRId64 "", nbytes, ndone, ntodo);
if (ndone == (OBJECT_SIZE / 2)) {
TSVIONBytesSet(cache_vconn->write_vio, (OBJECT_SIZE - 100));
TSVIOReenable(cache_vconn->write_vio);
Debug(UTDBG_TAG "_cache_write", "Increment write_counter in write_complete [a]");
return 1;
} else if (ndone == (OBJECT_SIZE - 100)) {
TSVIONBytesSet(cache_vconn->write_vio, OBJECT_SIZE);
TSVIOReenable(cache_vconn->write_vio);
Debug(UTDBG_TAG "_cache_write", "Increment write_counter in write_complete [b]");
return 1;
} else if (ndone == OBJECT_SIZE) {
Debug(UTDBG_TAG "_cache_write", "finishing up [c]");
SDK_RPRINT(SDK_Cache_test, "TSVIOReenable", "TestCase2", TC_PASS, "ok");
SDK_RPRINT(SDK_Cache_test, "TSVIONBytesSet", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(SDK_Cache_test, "TSVConnWrite", "TestCase1", TC_PASS, "ok");
} else {
SDK_RPRINT(SDK_Cache_test, "TSCacheWrite", "TestCase1", TC_FAIL, "Did not write expected # of bytes");
// no need to continue, return
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
}
if ((TSVIO)data != cache_vconn->write_vio) {
SDK_RPRINT(SDK_Cache_test, "TSVConnWrite", "TestCase1", TC_FAIL, "write_vio corrupted");
// no need to continue, return
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
}
Debug(UTDBG_TAG "_cache_write", "finishing up [d]");
if (TSVIOBufferGet(cache_vconn->write_vio) != cache_vconn->bufp) {
SDK_RPRINT(SDK_Cache_test, "TSVIOBufferGet", "TestCase1", TC_FAIL, "write_vio corrupted");
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
} else {
SDK_RPRINT(SDK_Cache_test, "TSVIOBufferGet", "TestCase1", TC_PASS, "ok");
}
if (TSVIOContGet(cache_vconn->write_vio) != contp) {
SDK_RPRINT(SDK_Cache_test, "TSVIOContGet", "TestCase1", TC_FAIL, "write_vio corrupted");
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
} else {
SDK_RPRINT(SDK_Cache_test, "TSVIOContGet", "TestCase1", TC_PASS, "ok");
}
Debug(UTDBG_TAG "_cache_write", "finishing up [f]");
if (TSVIOMutexGet(cache_vconn->write_vio) != TSContMutexGet(contp)) {
SDK_RPRINT(SDK_Cache_test, "TSVIOMutexGet", "TestCase1", TC_FAIL, "write_vio corrupted");
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
} else {
SDK_RPRINT(SDK_Cache_test, "TSVIOMutexGet", "TestCase1", TC_PASS, "ok");
}
if (TSVIOVConnGet(cache_vconn->write_vio) != cache_vconn->write_vconnp) {
SDK_RPRINT(SDK_Cache_test, "TSVIOVConnGet", "TestCase1", TC_FAIL, "write_vio corrupted");
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
} else {
SDK_RPRINT(SDK_Cache_test, "TSVIOVConnGet", "TestCase1", TC_PASS, "ok");
}
Debug(UTDBG_TAG "_cache_write", "finishing up [g]");
if (TSVIOReaderGet(cache_vconn->write_vio) != cache_vconn->readerp) {
SDK_RPRINT(SDK_Cache_test, "TSVIOReaderGet", "TestCase1", TC_FAIL, "write_vio corrupted");
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
} else {
SDK_RPRINT(SDK_Cache_test, "TSVIOReaderGet", "TestCase1", TC_PASS, "ok");
}
// tests for write is done, close write_vconnp
TSVConnClose(cache_vconn->write_vconnp);
cache_vconn->write_vconnp = NULL;
Debug(UTDBG_TAG "_cache_write", "finishing up [h]");
// start to read data out of cache
read_counter++;
TSCacheRead(contp, cache_vconn->key);
Debug(UTDBG_TAG "_cache_read", "starting read [i]");
return 1;
case TS_EVENT_VCONN_WRITE_READY:
Debug(UTDBG_TAG "_cache_event", "TS_EVENT_VCONN_WRITE_READY %d %p", event, data);
if ((TSVIO)data != cache_vconn->write_vio) {
SDK_RPRINT(SDK_Cache_test, "TSVConnWrite", "TestCase1", TC_FAIL, "write_vio corrupted");
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
}
nbytes = TSVIONBytesGet(cache_vconn->write_vio);
ndone = TSVIONDoneGet(cache_vconn->write_vio);
ntodo = TSVIONTodoGet(cache_vconn->write_vio);
Debug(UTDBG_TAG "_cache_write", "Nbytes=%" PRId64 " Ndone=%" PRId64 " Ntodo=%" PRId64 "", nbytes, ndone, ntodo);
TSVIOReenable(cache_vconn->write_vio);
return 1;
case TS_EVENT_VCONN_READ_COMPLETE:
Debug(UTDBG_TAG "_cache_event", "TS_EVENT_VCONN_READ_COMPLETE %d %p", event, data);
if ((TSVIO)data != cache_vconn->read_vio) {
SDK_RPRINT(SDK_Cache_test, "TSVConnRead", "TestCase1", TC_FAIL, "read_vio corrupted");
// no need to continue, return
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
}
nbytes = TSVIONBytesGet(cache_vconn->read_vio);
ntodo = TSVIONTodoGet(cache_vconn->read_vio);
ndone = TSVIONDoneGet(cache_vconn->read_vio);
Debug(UTDBG_TAG "_cache_read", "Nbytes=%" PRId64 " Ndone=%" PRId64 " Ntodo=%" PRId64 "", nbytes, ndone, ntodo);
if (nbytes != (ndone + ntodo)) {
SDK_RPRINT(SDK_Cache_test, "TSVIONBytesGet", "TestCase1", TC_FAIL, "read_vio corrupted");
SDK_RPRINT(SDK_Cache_test, "TSVIONTodoGet", "TestCase1", TC_FAIL, "read_vio corrupted");
SDK_RPRINT(SDK_Cache_test, "TSVIONDoneGet", "TestCase1", TC_FAIL, "read_vio corrupted");
// no need to continue, return
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
} else {
SDK_RPRINT(SDK_Cache_test, "TSVIONBytesGet", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(SDK_Cache_test, "TSVIONTodoGet", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(SDK_Cache_test, "TSVIONDoneGet", "TestCase1", TC_PASS, "ok");
TSVIONDoneSet(cache_vconn->read_vio, 0);
if (TSVIONDoneGet(cache_vconn->read_vio) != 0) {
SDK_RPRINT(SDK_Cache_test, "TSVIONDoneSet", "TestCase1", TC_FAIL, "fail to set");
// no need to continue, return
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
} else
SDK_RPRINT(SDK_Cache_test, "TSVIONDoneSet", "TestCase1", TC_PASS, "ok");
Debug(UTDBG_TAG "_cache_write", "finishing up [i]");
// now waiting for 100ms to make sure the key is
// written in directory remove the content
TSContSchedule(contp, 100, TS_THREAD_POOL_DEFAULT);
}
return 1;
case TS_EVENT_VCONN_READ_READY:
Debug(UTDBG_TAG "_cache_event", "TS_EVENT_VCONN_READ_READY %d %p", event, data);
if ((TSVIO)data != cache_vconn->read_vio) {
SDK_RPRINT(SDK_Cache_test, "TSVConnRead", "TestCase1", TC_FAIL, "read_vio corrupted");
// no need to continue, return
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
}
nbytes = TSVIONBytesGet(cache_vconn->read_vio);
ntodo = TSVIONTodoGet(cache_vconn->read_vio);
ndone = TSVIONDoneGet(cache_vconn->read_vio);
Debug(UTDBG_TAG "_cache_read", "Nbytes=%" PRId64 " Ndone=%" PRId64 " Ntodo=%" PRId64 "", nbytes, ndone, ntodo);
if (nbytes != (ndone + ntodo)) {
SDK_RPRINT(SDK_Cache_test, "TSVIONBytesGet", "TestCase1", TC_FAIL, "read_vio corrupted");
SDK_RPRINT(SDK_Cache_test, "TSVIONTodoGet", "TestCase1", TC_FAIL, "read_vio corrupted");
SDK_RPRINT(SDK_Cache_test, "TSVIONDoneGet", "TestCase1", TC_FAIL, "read_vio corrupted");
// no need to continue, return
*SDK_Cache_pstatus = REGRESSION_TEST_FAILED;
return 1;
} else {
SDK_RPRINT(SDK_Cache_test, "TSVIONBytesGet", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(SDK_Cache_test, "TSVIONTodoGet", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(SDK_Cache_test, "TSVIONDoneGet", "TestCase1", TC_PASS, "ok");
}
// Fix for bug INKqa12276: Must consume data from iobuffer
nbytes = TSIOBufferReaderAvail(cache_vconn->out_readerp);
TSIOBufferReaderConsume(cache_vconn->out_readerp, nbytes);
TSDebug(UTDBG_TAG "_cache_read", "Consuming %" PRId64 " bytes from cache read VC", nbytes);
TSVIOReenable(cache_vconn->read_vio);
Debug(UTDBG_TAG "_cache_read", "finishing up [j]");
return 1;
case TS_EVENT_TIMEOUT:
Debug(UTDBG_TAG "_cache_event", "TS_EVENT_TIMEOUT %d %p", event, data);
// do remove cached doc
TSCacheRemove(contp, cache_vconn->key);
return 1;
default:
TSReleaseAssert(!"Test SDK_API_TSCache: unexpected event");
}
Debug(UTDBG_TAG "_cache_event", "DONE DONE DONE");
// destroy the data structure
Debug(UTDBG_TAG "_cache_write", "all tests passed [z]");
TSIOBufferDestroy(cache_vconn->bufp);
TSIOBufferDestroy(cache_vconn->out_bufp);
TSCacheKeyDestroy(cache_vconn->key);
TSfree(cache_vconn);
*SDK_Cache_pstatus = REGRESSION_TEST_PASSED;
return 1;
}
REGRESSION_TEST(SDK_API_TSCache)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
*pstatus = REGRESSION_TEST_INPROGRESS;
SDK_Cache_test = test;
SDK_Cache_pstatus = pstatus;
int is_ready = 0;
// Check if Cache is ready
TSCacheReady(&is_ready);
if (!is_ready) {
SDK_RPRINT(test, "TSCacheReady", "TestCase1", TC_FAIL, "cache is not ready");
// no need to continue, return
*pstatus = REGRESSION_TEST_FAILED;
return;
} else {
SDK_RPRINT(test, "TSCacheReady", "TestCase1", TC_PASS, "ok");
}
// Create CacheKey
char key_name[] = "key_for_regression_test";
TSCacheKey key = TSCacheKeyCreate();
TSCacheKey key_cmp = TSCacheKeyCreate();
SDK_RPRINT(test, "TSCacheKeyCreate", "TestCase1", TC_PASS, "ok");
TSCacheKeyDigestSet(key, key_name, strlen(key_name));
TSCacheKeyDigestSet(key_cmp, key_name, strlen(key_name));
// TODO: This comparison makes no sense, since TSCacheKey is an opaque struct
#if 0
if (memcmp(key, key_cmp, sizeof(TSCacheKey)) != 0) {
SDK_RPRINT(test, "TSCacheKeySetDigest", "TestCase1", TC_FAIL, "digest is wrong");
// no need to continue, return
*pstatus = REGRESSION_TEST_FAILED;
TSCacheKeyDestroy(key);
TSCacheKeyDestroy(key_cmp);
return;
} else {
SDK_RPRINT(test, "TSCacheKeySetDigest", "TestCase1", TC_PASS, "ok");
TSCacheKeyDestroy(key_cmp);
}
#endif
// prepare caching content
// string, null-terminated.
for (int i = 0; i < (OBJECT_SIZE - 1); i++) {
content[i] = 'a';
}
content[OBJECT_SIZE - 1] = '\0';
// Write data to cache.
TSCont contp = TSContCreate(cache_handler, TSMutexCreate());
CacheVConnStruct *cache_vconn = (CacheVConnStruct *)TSmalloc(sizeof(CacheVConnStruct));
cache_vconn->key = key;
TSContDataSet(contp, cache_vconn);
TSCacheWrite(contp, key);
}
/* TSfopen */
//////////////////////////////////////////////
// SDK_API_TSfopen
//
// Unit Test for API: TSfopen
// TSclose
// TSfflush
// TSfgets
// TSfread
// TSfwrite
//////////////////////////////////////////////
#define PFX "plugin.config"
// Note that for each test, if it fails, we set the error status and return.
REGRESSION_TEST(SDK_API_TSfopen)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
*pstatus = REGRESSION_TEST_INPROGRESS;
char write_file_name[PATH_NAME_MAX];
TSFile source_read_file; // existing file
TSFile write_file; // to be created
TSFile cmp_read_file; // read & compare
char input_buffer[BUFSIZ];
char cmp_buffer[BUFSIZ];
struct stat stat_buffer_pre, stat_buffer_post, stat_buffer_input;
char *ret_val;
int read = 0, wrote = 0;
int64_t read_amount = 0;
char INPUT_TEXT_FILE[] = "plugin.config";
char input_file_full_path[BUFSIZ];
// Set full path to file at run time.
// TODO: This can never fail since we are
// returning the char[]
// Better check the dir itself.
//
if (TSInstallDirGet() == NULL) {
*pstatus = REGRESSION_TEST_FAILED;
return;
}
// Add "etc/trafficserver" to point to config directory
ink_filepath_make(input_file_full_path, sizeof(input_file_full_path), TSConfigDirGet(), INPUT_TEXT_FILE);
// open existing file for reading
if (!(source_read_file = TSfopen(input_file_full_path, "r"))) {
SDK_RPRINT(test, "TSfopen", "TestCase1", TC_FAIL, "can't open file for reading");
// no need to continue, return
*pstatus = REGRESSION_TEST_FAILED;
return;
} else
SDK_RPRINT(test, "TSfopen", "TestCase1", TC_PASS, "ok");
// Create unique tmp _file_name_, do not use any TS file_name
snprintf(write_file_name, PATH_NAME_MAX, "/tmp/%sXXXXXX", PFX);
int write_file_fd; // this file will be reopened below
if ((write_file_fd = mkstemp(write_file_name)) <= 0) {
SDK_RPRINT(test, "mkstemp", "std func", TC_FAIL, "can't create file for writing");
// no need to continue, return
*pstatus = REGRESSION_TEST_FAILED;
if (source_read_file != NULL)
TSfclose(source_read_file);
return;
}
close(write_file_fd);
// open file for writing, the file doesn't have to exist.
if (!(write_file = TSfopen(write_file_name, "w"))) {
SDK_RPRINT(test, "TSfopen", "TestCase2", TC_FAIL, "can't open file for writing");
// no need to continue, return
*pstatus = REGRESSION_TEST_FAILED;
if (source_read_file != NULL)
TSfclose(source_read_file);
return;
}
SDK_RPRINT(test, "TSfopen", "TestCase2", TC_PASS, "ok");
memset(input_buffer, '\0', BUFSIZ);
// source_read_file and input_file_full_path are the same file
if (stat(input_file_full_path, &stat_buffer_input) != 0) {
SDK_RPRINT(test, "stat", "std func", TC_FAIL, "source file and input file messed up");
// no need to continue, return
*pstatus = REGRESSION_TEST_FAILED;
if (source_read_file != NULL)
TSfclose(source_read_file);
if (write_file != NULL)
TSfclose(write_file);
return;
}
read_amount = (stat_buffer_input.st_size <= (off_t)sizeof(input_buffer)) ? (stat_buffer_input.st_size) : (sizeof(input_buffer));
// TSfgets
if ((ret_val = TSfgets(source_read_file, input_buffer, read_amount)) == NULL) {
SDK_RPRINT(test, "TSfgets", "TestCase1", TC_FAIL, "can't read from file");
// no need to continue, return
*pstatus = REGRESSION_TEST_FAILED;
if (source_read_file != NULL)
TSfclose(source_read_file);
if (write_file != NULL)
TSfclose(write_file);
return;
} else {
if (ret_val != input_buffer) {
SDK_RPRINT(test, "TSfgets", "TestCase2", TC_FAIL, "reading error");
// no need to continue, return
*pstatus = REGRESSION_TEST_FAILED;
if (source_read_file != NULL)
TSfclose(source_read_file);
if (write_file != NULL)
TSfclose(write_file);
return;
} else
SDK_RPRINT(test, "TSfgets", "TestCase1", TC_PASS, "ok");
}
// TSfwrite
wrote = TSfwrite(write_file, input_buffer, read_amount);
if (wrote != read_amount) {
SDK_RPRINT(test, "TSfwrite", "TestCase1", TC_FAIL, "writing error");
// no need to continue, return
*pstatus = REGRESSION_TEST_FAILED;
if (source_read_file != NULL)
TSfclose(source_read_file);
if (write_file != NULL)
TSfclose(write_file);
return;
}
SDK_RPRINT(test, "TSfwrite", "TestCase1", TC_PASS, "ok");
// TSfflush
if (stat(write_file_name, &stat_buffer_pre) != 0) {
SDK_RPRINT(test, "stat", "std func", TC_FAIL, "TSfwrite error");
// no need to continue, return
*pstatus = REGRESSION_TEST_FAILED;
if (source_read_file != NULL)
TSfclose(source_read_file);
if (write_file != NULL)
TSfclose(write_file);
return;
}
TSfflush(write_file); // write_file should point to write_file_name
if (stat(write_file_name, &stat_buffer_post) != 0) {
SDK_RPRINT(test, "stat", "std func", TC_FAIL, "TSfflush error");
// no need to continue, return
*pstatus = REGRESSION_TEST_FAILED;
if (source_read_file != NULL)
TSfclose(source_read_file);
if (write_file != NULL)
TSfclose(write_file);
return;
}
if ((stat_buffer_pre.st_size == 0) && (stat_buffer_post.st_size == read_amount)) {
SDK_RPRINT(test, "TSfflush", "TestCase1", TC_PASS, "ok");
} else {
SDK_RPRINT(test, "TSfflush", "TestCase1", TC_FAIL, "TSfflush error");
// no need to continue, return
*pstatus = REGRESSION_TEST_FAILED;
if (source_read_file != NULL)
TSfclose(source_read_file);
if (write_file != NULL)
TSfclose(write_file);
return;
}
// TSfread
// open again for reading
cmp_read_file = TSfopen(write_file_name, "r");
if (cmp_read_file == NULL) {
SDK_RPRINT(test, "TSfopen", "TestCase3", TC_FAIL, "can't open file for reading");
// no need to continue, return
*pstatus = REGRESSION_TEST_FAILED;
if (source_read_file != NULL)
TSfclose(source_read_file);
if (write_file != NULL)
TSfclose(write_file);
return;
}
read_amount = (stat_buffer_input.st_size <= (off_t)sizeof(cmp_buffer)) ? (stat_buffer_input.st_size) : (sizeof(cmp_buffer));
// TSfread on read file
read = TSfread(cmp_read_file, cmp_buffer, read_amount);
if (read != read_amount) {
SDK_RPRINT(test, "TSfread", "TestCase1", TC_FAIL, "can't reading");
// no need to continue, return
*pstatus = REGRESSION_TEST_FAILED;
if (source_read_file != NULL)
TSfclose(source_read_file);
if (write_file != NULL)
TSfclose(write_file);
if (cmp_read_file != NULL)
TSfclose(cmp_read_file);
return;
} else
SDK_RPRINT(test, "TSfread", "TestCase1", TC_PASS, "ok");
// compare input_buffer and cmp_buffer buffers
if (memcmp(input_buffer, cmp_buffer, read_amount) != 0) {
SDK_RPRINT(test, "TSfread", "TestCase2", TC_FAIL, "reading error");
// no need to continue, return
*pstatus = REGRESSION_TEST_FAILED;
if (source_read_file != NULL)
TSfclose(source_read_file);
if (write_file != NULL)
TSfclose(write_file);
if (cmp_read_file != NULL)
TSfclose(cmp_read_file);
return;
} else
SDK_RPRINT(test, "TSfread", "TestCase2", TC_PASS, "ok");
// remove the tmp file
if (unlink(write_file_name) != 0) {
SDK_RPRINT(test, "unlink", "std func", TC_FAIL, "can't remove temp file");
}
// TSfclose on read file
TSfclose(source_read_file);
SDK_RPRINT(test, "TSfclose", "TestCase1", TC_PASS, "ok");
// TSfclose on write file
TSfclose(write_file);
SDK_RPRINT(test, "TSfclose", "TestCase2", TC_PASS, "ok");
*pstatus = REGRESSION_TEST_PASSED;
if (cmp_read_file != NULL)
TSfclose(cmp_read_file);
}
/* TSThread */
//////////////////////////////////////////////
// SDK_API_TSThread
//
// Unit Test for API: TSThread
// TSThreadCreate
// TSThreadSelf
//////////////////////////////////////////////
static int thread_err_count = 0;
static RegressionTest *SDK_Thread_test;
static int *SDK_Thread_pstatus;
static void *thread_create_handler(void *arg);
static void *
thread_create_handler(void * /* arg ATS_UNUSED */)
{
TSThread athread;
// Fix me: do more useful work
sleep(10);
athread = TSThreadSelf();
if (athread == 0) {
thread_err_count++;
SDK_RPRINT(SDK_Thread_test, "TSThreadCreate", "TestCase2", TC_FAIL, "can't get thread");
} else {
SDK_RPRINT(SDK_Thread_test, "TSThreadCreate", "TestCase2", TC_PASS, "ok");
}
if (thread_err_count > 0)
*SDK_Thread_pstatus = REGRESSION_TEST_FAILED;
else
*SDK_Thread_pstatus = REGRESSION_TEST_PASSED;
return NULL;
}
// Fix me: Solaris threads/Win2K threads tests
// Argument data passed to thread init functions
// cannot be allocated on the stack.
REGRESSION_TEST(SDK_API_TSThread)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
*pstatus = REGRESSION_TEST_INPROGRESS;
SDK_Thread_test = test;
SDK_Thread_pstatus = pstatus;
TSThread curr_thread = 0;
// TSThread created_thread = 0;
pthread_t curr_tid;
curr_tid = pthread_self();
// TSThreadSelf
curr_thread = TSThreadSelf();
if (curr_thread == 0) {
SDK_RPRINT(test, "TSThreadSelf", "TestCase1", TC_FAIL, "can't get the current thread");
thread_err_count++;
} else {
SDK_RPRINT(test, "TSThreadSelf", "TestCase1", TC_PASS, "ok");
}
// TSThreadCreate
TSThread created_thread = TSThreadCreate(thread_create_handler, (void *)(intptr_t)curr_tid);
if (created_thread == NULL) {
thread_err_count++;
SDK_RPRINT(test, "TSThreadCreate", "TestCase1", TC_FAIL, "can't create thread");
} else {
SDK_RPRINT(test, "TSThreadCreate", "TestCase1", TC_PASS, "ok");
}
}
//////////////////////////////////////////////
// SDK_API_TSThread
//
// Unit Test for API: TSThreadInit
// TSThreadDestroy
//////////////////////////////////////////////
static int thread_init_err_count = 0;
static RegressionTest *SDK_ThreadInit_test;
static int *SDK_ThreadInit_pstatus;
static void *pthread_start_func(void *arg);
static void *
pthread_start_func(void * /* arg ATS_UNUSED */)
{
TSThread temp_thread = 0;
// TSThreadInit
temp_thread = TSThreadInit();
if (!temp_thread) {
SDK_RPRINT(SDK_ThreadInit_test, "TSThreadInit", "TestCase2", TC_FAIL, "can't init thread");
thread_init_err_count++;
} else
SDK_RPRINT(SDK_ThreadInit_test, "TSThreadInit", "TestCase2", TC_PASS, "ok");
// Clean up this thread
if (temp_thread)
TSThreadDestroy(temp_thread);
if (thread_init_err_count > 0)
*SDK_ThreadInit_pstatus = REGRESSION_TEST_FAILED;
else
*SDK_ThreadInit_pstatus = REGRESSION_TEST_PASSED;
return NULL;
}
REGRESSION_TEST(SDK_API_TSThreadInit)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
*pstatus = REGRESSION_TEST_INPROGRESS;
SDK_ThreadInit_test = test;
SDK_ThreadInit_pstatus = pstatus;
pthread_t curr_tid, new_tid;
curr_tid = pthread_self();
int ret;
errno = 0;
ret = pthread_create(&new_tid, NULL, pthread_start_func, (void *)(intptr_t)curr_tid);
if (ret != 0) {
thread_init_err_count++;
SDK_RPRINT(test, "TSThreadInit", "TestCase1", TC_FAIL, "can't create pthread");
} else
SDK_RPRINT(test, "TSThreadInit", "TestCase1", TC_PASS, "ok");
}
/* Action */
//////////////////////////////////////////////
// SDK_API_TSAction
//
// Unit Test for API: TSActionCancel
//////////////////////////////////////////////
static RegressionTest *SDK_ActionCancel_test;
static int *SDK_ActionCancel_pstatus;
int
action_cancel_handler(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
{
if (event == TS_EVENT_IMMEDIATE) { // called from schedule_imm OK
SDK_RPRINT(SDK_ActionCancel_test, "TSActionCancel", "TestCase1", TC_PASS, "ok");
*SDK_ActionCancel_pstatus = REGRESSION_TEST_PASSED;
} else if (event == TS_EVENT_TIMEOUT) { // called from schedule_in Not OK.
SDK_RPRINT(SDK_ActionCancel_test, "TSActionCancel", "TestCase1", TC_FAIL, "bad action");
*SDK_ActionCancel_pstatus = REGRESSION_TEST_FAILED;
} else { // there is sth wrong
SDK_RPRINT(SDK_ActionCancel_test, "TSActionCancel", "TestCase1", TC_FAIL, "bad event");
*SDK_ActionCancel_pstatus = REGRESSION_TEST_FAILED;
}
TSContDestroy(contp);
return 0;
}
REGRESSION_TEST(SDK_API_TSActionCancel)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
*pstatus = REGRESSION_TEST_INPROGRESS;
SDK_ActionCancel_test = test;
SDK_ActionCancel_pstatus = pstatus;
TSMutex cont_mutex = TSMutexCreate();
TSCont contp = TSContCreate(action_cancel_handler, cont_mutex);
TSAction actionp = TSContSchedule(contp, 10000, TS_THREAD_POOL_DEFAULT);
TSMutexLock(cont_mutex);
if (TSActionDone(actionp)) {
*pstatus = REGRESSION_TEST_FAILED;
TSMutexUnlock(cont_mutex);
return;
} else {
TSActionCancel(actionp);
}
TSMutexUnlock(cont_mutex);
TSContSchedule(contp, 0, TS_THREAD_POOL_DEFAULT);
}
//////////////////////////////////////////////
// SDK_API_TSAction
//
// Unit Test for API: TSActionDone
//////////////////////////////////////////////
/* Currently, don't know how to test it because TSAction
is at "done" status only "shortly" after finish
executing action_done_handler. Another possibility is
to use reentrant call. But in both cases it's not
guaranteed to get ActionDone.
*/
/* Continuations */
//////////////////////////////////////////////
// SDK_API_TSCont
//
// Unit Test for API: TSContCreate
// TSContCall
//////////////////////////////////////////////
// this is needed for asynchronous APIs
static RegressionTest *SDK_ContCreate_test;
static int *SDK_ContCreate_pstatus;
int
cont_handler(TSCont /* contp ATS_UNUSED */, TSEvent /* event ATS_UNUSED */, void * /* edata ATS_UNUSED */)
{
SDK_RPRINT(SDK_ContCreate_test, "TSContCreate", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(SDK_ContCreate_test, "TSContCall", "TestCase1", TC_PASS, "ok");
*SDK_ContCreate_pstatus = REGRESSION_TEST_PASSED;
return 0;
}
REGRESSION_TEST(SDK_API_TSContCreate)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
*pstatus = REGRESSION_TEST_INPROGRESS;
// For asynchronous APIs, use static vars to store test and pstatus
SDK_ContCreate_test = test;
SDK_ContCreate_pstatus = pstatus;
TSMutex mutexp = TSMutexCreate();
TSCont contp = TSContCreate(cont_handler, mutexp);
if (TS_SUCCESS == TSMutexLockTry(mutexp)) { // Mutex is grabbed successfully
TSContCall(contp, (TSEvent)0, NULL);
TSMutexUnlock(mutexp);
} else { // mutex has problems
SDK_RPRINT(SDK_ContCreate_test, "TSContCreate", "TestCase1", TC_FAIL, "continuation creation has problems");
SDK_RPRINT(SDK_ContCreate_test, "TSContCall", "TestCase1", TC_FAIL, "continuation has problems");
*pstatus = REGRESSION_TEST_FAILED;
}
TSContDestroy(contp);
}
//////////////////////////////////////////////
// SDK_API_TSCont
//
// Unit Test for API: TSContDataGet
// TSContDataSet
//////////////////////////////////////////////
// this is needed for asynchronous APIs
static RegressionTest *SDK_ContData_test;
static int *SDK_ContData_pstatus;
// this is specific for this test
typedef struct {
int data1;
int data2;
} MyData;
int
cont_data_handler(TSCont contp, TSEvent /* event ATS_UNUSED */, void * /* edata ATS_UNUSED */)
{
MyData *my_data = (MyData *)TSContDataGet(contp);
if (my_data->data1 == 1 && my_data->data2 == 2) {
SDK_RPRINT(SDK_ContData_test, "TSContDataSet", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(SDK_ContData_test, "TSContDataGet", "TestCase1", TC_PASS, "ok");
*SDK_ContData_pstatus = REGRESSION_TEST_PASSED;
} else {
// If we get bad data, it's a failure
SDK_RPRINT(SDK_ContData_test, "TSContDataSet", "TestCase1", TC_FAIL, "bad data");
SDK_RPRINT(SDK_ContData_test, "TSContDataGet", "TestCase1", TC_FAIL, "bad data");
*SDK_ContData_pstatus = REGRESSION_TEST_FAILED;
}
TSfree(my_data);
TSContDestroy(contp);
return 0;
}
REGRESSION_TEST(SDK_API_TSContDataGet)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
*pstatus = REGRESSION_TEST_INPROGRESS;
// For asynchronous APIs, use static vars to store test and pstatus
SDK_ContData_test = test;
SDK_ContData_pstatus = pstatus;
TSCont contp = TSContCreate(cont_data_handler, TSMutexCreate());
MyData *my_data = (MyData *)TSmalloc(sizeof(MyData));
my_data->data1 = 1;
my_data->data2 = 2;
TSContDataSet(contp, (void *)my_data);
TSContSchedule(contp, 0, TS_THREAD_POOL_DEFAULT);
}
//////////////////////////////////////////////
// SDK_API_TSCont
//
// Unit Test for API: TSContMutexGet
//////////////////////////////////////////////
REGRESSION_TEST(SDK_API_TSContMutexGet)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
bool test_passed = false;
*pstatus = REGRESSION_TEST_INPROGRESS;
TSMutex mutexp_input;
TSMutex mutexp_output;
TSCont contp;
mutexp_input = TSMutexCreate();
contp = TSContCreate(cont_handler, mutexp_input);
mutexp_output = TSContMutexGet(contp);
if (mutexp_input == mutexp_output) {
SDK_RPRINT(test, "TSContMutexGet", "TestCase1", TC_PASS, "ok");
test_passed = true;
} else
SDK_RPRINT(test, "TSContMutexGet", "TestCase1", TC_FAIL, "Continutation's mutex corrupted");
// Status of the whole test
*pstatus = ((test_passed == true) ? REGRESSION_TEST_PASSED : REGRESSION_TEST_FAILED);
TSContDestroy(contp);
}
//////////////////////////////////////////////
// SDK_API_TSCont
//
// Unit Test for API: TSContSchedule
//////////////////////////////////////////////
// this is needed for asynchronous APIs
static RegressionTest *SDK_ContSchedule_test;
static int *SDK_ContSchedule_pstatus;
// this is specific for this test
static int tc1_count = 0;
static int tc2_count = 0;
int
cont_schedule_handler(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */)
{
if (event == TS_EVENT_IMMEDIATE) {
// Test Case 1
SDK_RPRINT(SDK_ContSchedule_test, "TSContSchedule", "TestCase1", TC_PASS, "ok");
tc1_count++;
} else if (event == TS_EVENT_TIMEOUT) {
// Test Case 2
SDK_RPRINT(SDK_ContSchedule_test, "TSContSchedule", "TestCase2", TC_PASS, "ok");
tc2_count++;
} else {
// If we receive a bad event, it's a failure
SDK_RPRINT(SDK_ContSchedule_test, "TSContSchedule", "TestCase1|2", TC_FAIL, "received unexpected event number %d", event);
*SDK_ContSchedule_pstatus = REGRESSION_TEST_FAILED;
return 0;
}
// We expect to be called once for TC1 and once for TC2
if ((tc1_count == 1) && (tc2_count == 1)) {
*SDK_ContSchedule_pstatus = REGRESSION_TEST_PASSED;
}
// If TC1 or TC2 executed more than once, something is fishy..
else if (tc1_count + tc2_count >= 2) {
*SDK_ContSchedule_pstatus = REGRESSION_TEST_FAILED;
}
TSContDestroy(contp);
return 0;
}
/* Mutex */
/*
Fix me: test for grabbing the mutex from two
different threads.
*/
//////////////////////////////////////////////
// SDK_API_TSMutex
//
// Unit Test for API: TSMutexCreate
// TSMutexLock
// TSMutexUnLock
//////////////////////////////////////////////
REGRESSION_TEST(SDK_API_TSMutexCreate)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
bool test_passed = false;
*pstatus = REGRESSION_TEST_INPROGRESS;
TSMutex mutexp = TSMutexCreate();
TSMutexLock(mutexp);
/* This is normal because all locking is from the same thread */
TSReturnCode lock = TS_ERROR;
TSMutexLockTry(mutexp);
lock = TSMutexLockTry(mutexp);
if (TS_SUCCESS == lock) {
SDK_RPRINT(test, "TSMutexCreate", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(test, "TSMutexLock", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(test, "TSMutexLockTry", "TestCase1", TC_PASS, "ok");
test_passed = true;
} else {
SDK_RPRINT(test, "TSMutexCreate", "TestCase1", TC_FAIL, "mutex can't be grabbed twice from the same thread");
SDK_RPRINT(test, "TSMutexLock", "TestCase1", TC_FAIL, "mutex can't be grabbed twice from the same thread");
SDK_RPRINT(test, "TSMutexLockTry", "TestCase1", TC_FAIL, "mutex can't be grabbed twice from the same thread");
}
TSMutexUnlock(mutexp);
SDK_RPRINT(test, "TSMutexUnLock", "TestCase1", TC_PASS, "ok");
if (test_passed) {
*pstatus = REGRESSION_TEST_PASSED;
} else {
*pstatus = REGRESSION_TEST_FAILED;
}
}
/* IOBuffer */
//////////////////////////////////////////////
// SDK_API_TSIOBuffer
//
// Unit Test for API: TSIOBufferCreate
// TSIOBufferWaterMarkGet
// TSIOBufferWaterMarkSet
//////////////////////////////////////////////
REGRESSION_TEST(SDK_API_TSIOBufferCreate)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
bool test_passed = false;
*pstatus = REGRESSION_TEST_INPROGRESS;
int64_t watermark = 1000;
TSIOBuffer bufp = TSIOBufferCreate();
TSIOBufferWaterMarkSet(bufp, watermark);
watermark = TSIOBufferWaterMarkGet(bufp);
if (watermark == 1000) {
SDK_RPRINT(test, "TSIOBufferCreate", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(test, "TSIOBufferWaterMarkGet", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(test, "TSIOBufferWaterMarkSet", "TestCase1", TC_PASS, "ok");
test_passed = true;
} else {
SDK_RPRINT(test, "TSIOBufferCreate", "TestCase1", TC_FAIL, "watermark failed");
SDK_RPRINT(test, "TSIOBufferWaterMarkGet", "TestCase1", TC_FAIL, "watermark failed");
SDK_RPRINT(test, "TSIOBufferWaterMarkSet", "TestCase1", TC_FAIL, "watermark failed");
}
TSIOBufferDestroy(bufp);
// Status of the whole test
*pstatus = ((test_passed == true) ? REGRESSION_TEST_PASSED : REGRESSION_TEST_FAILED);
return;
}
//////////////////////////////////////////////
// SDK_API_TSIOBuffer
//
// Unit Test for API: TSIOBufferSizedCreate
// TSIOBufferProduce
// TSIOBufferReaderAlloc
// TSIOBufferReaderAvail
//////////////////////////////////////////////
REGRESSION_TEST(SDK_API_TSIOBufferProduce)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
bool test_passed = false;
*pstatus = REGRESSION_TEST_INPROGRESS;
TSIOBuffer bufp = TSIOBufferSizedCreate(TS_IOBUFFER_SIZE_INDEX_4K); // size is 4096
TSIOBufferReader readerp = TSIOBufferReaderAlloc(bufp);
TSIOBufferProduce(bufp, 10);
int64_t reader_avail = TSIOBufferReaderAvail(readerp);
if (reader_avail == 10) {
SDK_RPRINT(test, "TSIOBufferProduce", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(test, "TSIOBufferReaderAlloc", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(test, "TSIOBufferReaderAvail", "TestCase1", TC_PASS, "ok");
test_passed = true;
} else {
SDK_RPRINT(test, "TSIOBufferProduce", "TestCase1", TC_FAIL, "failed");
SDK_RPRINT(test, "TSIOBufferReaderAlloc", "TestCase1", TC_FAIL, "failed");
SDK_RPRINT(test, "TSIOBufferReaderAvail", "TestCase1", TC_FAIL, "failed");
}
// Status of the whole test
*pstatus = ((test_passed == true) ? REGRESSION_TEST_PASSED : REGRESSION_TEST_FAILED);
return;
}
//////////////////////////////////////////////
// SDK_API_TSIOBuffer
//
// Unit Test for API: TSIOBufferReaderConsume
//////////////////////////////////////////////
REGRESSION_TEST(SDK_API_TSIOBufferReaderConsume)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
bool test_passed = false;
*pstatus = REGRESSION_TEST_INPROGRESS;
TSIOBuffer bufp = TSIOBufferSizedCreate(TS_IOBUFFER_SIZE_INDEX_4K);
TSIOBufferReader readerp = TSIOBufferReaderAlloc(bufp);
TSIOBufferProduce(bufp, 10);
TSIOBufferReaderConsume(readerp, 10);
int64_t reader_avail = TSIOBufferReaderAvail(readerp);
if (reader_avail == 0) {
SDK_RPRINT(test, "TSIOBufferReaderConsume", "TestCase1", TC_PASS, "ok");
test_passed = true;
} else {
SDK_RPRINT(test, "TSIOBufferReaderConsume", "TestCase1", TC_FAIL, "failed");
}
// Status of the whole test
*pstatus = ((test_passed == true) ? REGRESSION_TEST_PASSED : REGRESSION_TEST_FAILED);
return;
}
//////////////////////////////////////////////
// SDK_API_TSIOBuffer
//
// Unit Test for API: TSIOBufferReaderClone
//////////////////////////////////////////////
REGRESSION_TEST(SDK_API_TSIOBufferReaderClone)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
bool test_passed = false;
*pstatus = REGRESSION_TEST_INPROGRESS;
TSIOBuffer bufp = TSIOBufferSizedCreate(TS_IOBUFFER_SIZE_INDEX_4K);
TSIOBufferReader readerp = TSIOBufferReaderAlloc(bufp);
TSIOBufferProduce(bufp, 10);
TSIOBufferReaderConsume(readerp, 5);
TSIOBufferReader readerp2 = TSIOBufferReaderClone(readerp);
int64_t reader_avail = TSIOBufferReaderAvail(readerp2);
if (reader_avail == 5) {
SDK_RPRINT(test, "TSIOBufferReaderClone", "TestCase1", TC_PASS, "ok");
test_passed = true;
} else {
SDK_RPRINT(test, "TSIOBufferReaderClone", "TestCase1", TC_FAIL, "failed");
}
// Status of the whole test
*pstatus = ((test_passed == true) ? REGRESSION_TEST_PASSED : REGRESSION_TEST_FAILED);
return;
}
//////////////////////////////////////////////
// SDK_API_TSIOBuffer
//
// Unit Test for API: TSIOBufferStart
// TSIOBufferReaderStart
//////////////////////////////////////////////
REGRESSION_TEST(SDK_API_TSIOBufferStart)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
bool test_passed = false;
*pstatus = REGRESSION_TEST_INPROGRESS;
TSIOBuffer bufp = TSIOBufferSizedCreate(TS_IOBUFFER_SIZE_INDEX_4K);
TSIOBufferReader readerp = TSIOBufferReaderAlloc(bufp);
if (TSIOBufferStart(bufp) == TSIOBufferReaderStart(readerp)) {
SDK_RPRINT(test, "TSIOBufferStart", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(test, "TSIOBufferReaderStart", "TestCase1", TC_PASS, "ok");
test_passed = true;
} else {
SDK_RPRINT(test, "TSIOBufferStart", "TestCase1", TC_FAIL, "failed");
SDK_RPRINT(test, "TSIOBufferReaderStart", "TestCase1", TC_FAIL, "failed");
}
// Status of the whole test
*pstatus = ((test_passed == true) ? REGRESSION_TEST_PASSED : REGRESSION_TEST_FAILED);
return;
}
//////////////////////////////////////////////
// SDK_API_TSIOBuffer
//
// Unit Test for API: TSIOBufferCopy
// TSIOBufferWrite
// TSIOBufferReaderCopy
//////////////////////////////////////////////
REGRESSION_TEST(SDK_API_TSIOBufferCopy)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
bool test_passed = false;
*pstatus = REGRESSION_TEST_INPROGRESS;
char input_buf[] = "This is the test for TSIOBufferCopy, TSIOBufferWrite, TSIOBufferReaderCopy";
char output_buf[1024];
TSIOBuffer bufp = TSIOBufferSizedCreate(TS_IOBUFFER_SIZE_INDEX_4K);
TSIOBuffer bufp2 = TSIOBufferSizedCreate(TS_IOBUFFER_SIZE_INDEX_4K);
TSIOBufferReader readerp = TSIOBufferReaderAlloc(bufp);
TSIOBufferWrite(bufp, input_buf, (strlen(input_buf) + 1));
TSIOBufferCopy(bufp2, readerp, (strlen(input_buf) + 1), 0);
TSIOBufferReaderCopy(readerp, output_buf, (strlen(input_buf) + 1));
if (strcmp(input_buf, output_buf) == 0) {
SDK_RPRINT(test, "TSIOBufferWrite", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(test, "TSIOBufferCopy", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(test, "TSIOBufferReaderCopy", "TestCase1", TC_PASS, "ok");
test_passed = true;
} else {
SDK_RPRINT(test, "TSIOBufferWrite", "TestCase1", TC_FAIL, "failed");
SDK_RPRINT(test, "TSIOBufferCopy", "TestCase1", TC_FAIL, "failed");
SDK_RPRINT(test, "TSIOBufferReaderCopy", "TestCase1", TC_FAIL, "failed");
}
// Status of the whole test
*pstatus = ((test_passed == true) ? REGRESSION_TEST_PASSED : REGRESSION_TEST_FAILED);
return;
}
//////////////////////////////////////////////
// SDK_API_TSIOBuffer
//
// Unit Test for API: TSIOBuffer
// TSIOBufferWrite
// TSIOBufferReaderCopy
//////////////////////////////////////////////
REGRESSION_TEST(SDK_API_TSIOBufferBlockReadAvail)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
bool test_passed_1 = false;
bool test_passed_2 = false;
*pstatus = REGRESSION_TEST_INPROGRESS;
int i = 10000;
TSIOBuffer bufp = TSIOBufferCreate();
TSIOBufferWrite(bufp, (char *)&i, sizeof(int));
TSIOBufferReader readerp = TSIOBufferReaderAlloc(bufp);
int64_t avail_write, avail_read;
// TODO: This is probably not correct any more.
TSIOBufferBlock blockp = TSIOBufferStart(bufp);
if ((TSIOBufferBlockWriteStart(blockp, &avail_write) - TSIOBufferBlockReadStart(blockp, readerp, &avail_read)) == sizeof(int)) {
SDK_RPRINT(test, "TSIOBufferBlockReadStart", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(test, "TSIOBufferBlockWriteStart", "TestCase1", TC_PASS, "ok");
test_passed_1 = true;
} else {
SDK_RPRINT(test, "TSIOBufferBlockReadStart", "TestCase1", TC_FAIL, "failed");
SDK_RPRINT(test, "TSIOBufferBlockWriteStart", "TestCase1", TC_FAIL, "failed");
}
if ((TSIOBufferBlockReadAvail(blockp, readerp) + TSIOBufferBlockWriteAvail(blockp)) == 4096) {
SDK_RPRINT(test, "TSIOBufferBlockReadAvail", "TestCase1", TC_PASS, "ok");
SDK_RPRINT(test, "TSIOBufferBlockWriteAvail", "TestCase1", TC_PASS, "ok");
test_passed_2 = true;
} else {
SDK_RPRINT(test, "TSIOBufferBlockReadAvail", "TestCase1", TC_FAIL, "failed");
SDK_RPRINT(test, "TSIOBufferBlockWriteAvail", "TestCase1", TC_FAIL, "failed");
}
if (test_passed_1 && test_passed_2) {
*pstatus = REGRESSION_TEST_PASSED;
} else {
*pstatus = REGRESSION_TEST_FAILED;
}
return;
}
//////////////////////////////////////////////////
// SDK_API_TSIOBuffer
//
// Unit Test for API: TSIOBufferBlockNext
//////////////////////////////////////////////////
REGRESSION_TEST(SDK_API_TSIOBufferBlockNext)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
bool test_passed = false;
*pstatus = REGRESSION_TEST_INPROGRESS;
int i = 10000;
TSIOBuffer bufp = TSIOBufferCreate();
TSIOBufferWrite(bufp, (char *)&i, sizeof(int));
TSIOBufferReader readerp = TSIOBufferReaderAlloc(bufp);
TSIOBufferBlock blockp = TSIOBufferReaderStart(readerp);
// TODO: This is probaby not the best of regression tests right now ...
// Note that this assumes block size is > sizeof(int) bytes.
if (TSIOBufferBlockNext(blockp) == NULL) {
SDK_RPRINT(test, "TSIOBufferBlockNext", "TestCase1", TC_PASS, "ok");
test_passed = true;
} else {
SDK_RPRINT(test, "TSIOBufferBlockNext", "TestCase1", TC_FAIL, "fail");
}
if (test_passed) {
*pstatus = REGRESSION_TEST_PASSED;
} else {
*pstatus = REGRESSION_TEST_FAILED;
}
return;
}
REGRESSION_TEST(SDK_API_TSContSchedule)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
*pstatus = REGRESSION_TEST_INPROGRESS;
// For asynchronous APIs, use static vars to store test and pstatus
SDK_ContSchedule_test = test;
SDK_ContSchedule_pstatus = pstatus;
TSCont contp = TSContCreate(cont_schedule_handler, TSMutexCreate());
TSCont contp2 = TSContCreate(cont_schedule_handler, TSMutexCreate());
// Test Case 1: schedule immediate
TSContSchedule(contp, 0, TS_THREAD_POOL_DEFAULT);
// Test Case 2: schedule in 10ms
TSContSchedule(contp2, 10, TS_THREAD_POOL_DEFAULT);
}
//////////////////////////////////////////////////////////////////////////////
// SDK_API_HttpHookAdd
//
// Unit Test for API: TSHttpHookAdd
// TSHttpTxnReenable
// TSHttpTxnClientIPGet
// TSHttpTxnServerIPGet
// TSHttpTxnIncomingAddrGet
// TSHttpTxnClientAddrGet
// TSHttpTxnClientReqGet
// TSHttpTxnClientRespGet
// TSHttpTxnServerReqGet
// TSHttpTxnServerRespGet
//////////////////////////////////////////////////////////////////////////////
#define HTTP_HOOK_TEST_REQUEST_ID 1
typedef struct {
RegressionTest *regtest;
int *pstatus;
SocketServer *os;
ClientTxn *browser;
int hook_mask;
int reenable_mask;
bool test_client_ip_get;
bool test_client_incoming_port_get;
bool test_client_remote_port_get;
bool test_client_req_get;
bool test_client_resp_get;
bool test_server_ip_get;
bool test_server_req_get;
bool test_server_resp_get;
bool test_next_hop_ip_get;
unsigned int magic;
} SocketTest;
// This func is called by us from mytest_handler to test TSHttpTxnClientIPGet
static int
checkHttpTxnClientIPGet(SocketTest *test, void *data)
{
sockaddr const *ptr;
in_addr_t ip;
TSHttpTxn txnp = (TSHttpTxn)data;
in_addr_t actual_ip = htonl(INADDR_LOOPBACK); /* 127.0.0.1 is expected because the client is on the same machine */
ptr = TSHttpTxnClientAddrGet(txnp);
if (ptr == 0 || INADDR_ANY == (ip = ats_ip4_addr_cast(ptr))) {
test->test_client_ip_get = false;
SDK_RPRINT(test->regtest, "TSHttpTxnClientIPGet", "TestCase1", TC_FAIL, "TSHttpTxnClientIPGet returns 0 %s",
ptr ? "address" : "pointer");
return TS_EVENT_CONTINUE;
}
if (ip == actual_ip) {
test->test_client_ip_get = true;
SDK_RPRINT(test->regtest, "TSHttpTxnClientIPGet", "TestCase1", TC_PASS, "ok [%0.8x]", ip);
} else {
test->test_client_ip_get = false;
SDK_RPRINT(test->regtest, "TSHttpTxnClientIPGet", "TestCase1", TC_FAIL, "Value's Mismatch [expected %.8x got %.8x]", actual_ip,
ip);
}
return TS_EVENT_CONTINUE;
}
// This func is called by us from mytest_handler to check for TSHttpTxnNextHopIPGet
static int
checkHttpTxnNextHopIPGet(SocketTest *test, void *data)
{
TSHttpTxn txnp = (TSHttpTxn)data;
in_addr_t actual_ip = htonl(INADDR_LOOPBACK); /* 127.0.0.1 is expected because the client is on the same machine */
sockaddr const *ptr;
in_addr_t nexthopip;
ptr = TSHttpTxnNextHopAddrGet(txnp);
if (ptr == 0 || (nexthopip = ats_ip4_addr_cast(ptr)) == 0) {
test->test_next_hop_ip_get = false;
SDK_RPRINT(test->regtest, "TSHttpTxnNextHopIPGet", "TestCase1", TC_FAIL, "TSHttpTxnNextHopIPGet returns 0 %s",
ptr ? "address" : "pointer");
return TS_EVENT_CONTINUE;
}
if (nexthopip == actual_ip) {
test->test_next_hop_ip_get = true;
SDK_RPRINT(test->regtest, "TSHttpTxnNextHopIPGet", "TestCase1", TC_PASS, "ok");
} else {
test->test_next_hop_ip_get = false;
SDK_RPRINT(test->regtest, "TSHttpTxnNextHopIPGet", "TestCase1", TC_FAIL, "Value's Mismatch [expected %0.8x got %0.8x]",
actual_ip, nexthopip);
}
return TS_EVENT_CONTINUE;
}
// This func is called by us from mytest_handler to test TSHttpTxnServerIPGet
static int
checkHttpTxnServerIPGet(SocketTest *test, void *data)
{
sockaddr const *ptr;
in_addr_t ip;
TSHttpTxn txnp = (TSHttpTxn)data;
in_addr_t actual_ip = htonl(INADDR_LOOPBACK); /* 127.0.0.1 is expected because the client is on the same machine */
ptr = TSHttpTxnServerAddrGet(txnp);
if (0 == ptr || 0 == (ip = ats_ip4_addr_cast(ptr))) {
test->test_server_ip_get = false;
SDK_RPRINT(test->regtest, "TSHttpTxnServerIPGet", "TestCase1", TC_FAIL, "TSHttpTxnServerIPGet returns 0 %s",
ptr ? "address" : "pointer");
return TS_EVENT_CONTINUE;
}
if (ip == actual_ip) {
test->test_server_ip_get = true;
SDK_RPRINT(test->regtest, "TSHttpTxnServerIPGet", "TestCase1", TC_PASS, "ok");
} else {
test->test_server_ip_get = false;
SDK_RPRINT(test->regtest, "TSHttpTxnServerIPGet", "TestCase1", TC_FAIL, "Value's Mismatch");
}
return TS_EVENT_CONTINUE;
}
// This func is called by us from mytest_handler to test TSHttpTxnIncomingAddrGet
static int
checkHttpTxnIncomingAddrGet(SocketTest *test, void *data)
{
uint16_t port;
HttpProxyPort *proxy_port = HttpProxyPort::findHttp(AF_INET);
TSHttpTxn txnp = (TSHttpTxn)data;
sockaddr const *ptr = TSHttpTxnIncomingAddrGet(txnp);
if (0 == proxy_port) {
SDK_RPRINT(test->regtest, "TSHttpTxnIncomingPortGet", "TestCase1", TC_FAIL,
"TSHttpTxnIncomingAddrGet failed to find configured HTTP port.");
test->test_client_incoming_port_get = false;
return TS_EVENT_CONTINUE;
}
if (0 == ptr) {
SDK_RPRINT(test->regtest, "TSHttpTxnIncomingPortGet", "TestCase1", TC_FAIL, "TSHttpTxnIncomingAddrGet returns 0 pointer");
test->test_client_incoming_port_get = false;
return TS_EVENT_CONTINUE;
}
port = ats_ip_port_host_order(ptr);
TSDebug(UTDBG_TAG, "TS HTTP port = %x, Txn incoming client port %x", proxy_port->m_port, port);
if (port == proxy_port->m_port) {
SDK_RPRINT(test->regtest, "TSHttpTxnIncomingAddrGet", "TestCase1", TC_PASS, "ok");
test->test_client_incoming_port_get = true;
} else {
SDK_RPRINT(test->regtest, "TSHttpTxnIncomingAddrGet", "TestCase1", TC_FAIL,
"Value's Mismatch. From Function: %d Expected value: %d", port, proxy_port->m_port);
test->test_client_incoming_port_get = false;
}
return TS_EVENT_CONTINUE;
}
// This func is called by us from mytest_handler to test TSHttpTxnClientAddrGet
static int
checkHttpTxnClientAddrGet(SocketTest *test, void *data)
{
uint16_t port;
uint16_t browser_port;
TSHttpTxn txnp = (TSHttpTxn)data;
sockaddr const *ptr = TSHttpTxnClientAddrGet(txnp);
browser_port = test->browser->local_port;
if (0 == ptr) {
SDK_RPRINT(test->regtest, "TSHttpTxnClientClientAddrGet", "TestCase2", TC_FAIL, "TSHttpTxnClientAddrGet returned 0 pointer.");
test->test_client_remote_port_get = false;
return TS_EVENT_CONTINUE;
}
port = ats_ip_port_host_order(ptr);
TSDebug(UTDBG_TAG, "Browser port = %x, Txn remote port = %x", browser_port, port);
if (port == browser_port) {
SDK_RPRINT(test->regtest, "TSHttpTxnClientAddrGet", "TestCase1", TC_PASS, "ok");
test->test_client_remote_port_get = true;
} else {
SDK_RPRINT(test->regtest, "TSHttpTxnClientAddrGet", "TestCase1", TC_FAIL,
"Value's Mismatch. From Function: %d Expected Value: %d", port, browser_port);
test->test_client_remote_port_get = false;
}
return TS_EVENT_CONTINUE;
}
// This func is called by us from mytest_handler to test TSHttpTxnClientReqGet
static int
checkHttpTxnClientReqGet(SocketTest *test, void *data)
{
TSMBuffer bufp;
TSMLoc mloc;
TSHttpTxn txnp = (TSHttpTxn)data;
if (TSHttpTxnClientReqGet(txnp, &bufp, &mloc) != TS_SUCCESS) {
test->test_client_req_get = false;
SDK_RPRINT(test->regtest, "TSHttpTxnClientReqGet", "TestCase1", TC_FAIL, "Unable to get handle to client request");
return TS_EVENT_CONTINUE;
}
if ((bufp == reinterpret_cast<TSMBuffer>(&((HttpSM *)txnp)->t_state.hdr_info.client_request)) &&
(mloc == reinterpret_cast<TSMLoc>(((HttpSM *)txnp)->t_state.hdr_info.client_request.m_http))) {
test->test_client_req_get = true;
SDK_RPRINT(test->regtest, "TSHttpTxnClientReqGet", "TestCase1", TC_PASS, "ok");
} else {
test->test_client_req_get = false;
SDK_RPRINT(test->regtest, "TSHttpTxnClientReqGet", "TestCase1", TC_FAIL, "Value's Mismatch");
}
return TS_EVENT_CONTINUE;
}
// This func is called by us from mytest_handler to test TSHttpTxnClientRespGet
static int
checkHttpTxnClientRespGet(SocketTest *test, void *data)
{
TSMBuffer bufp;
TSMLoc mloc;
TSHttpTxn txnp = (TSHttpTxn)data;
if (TSHttpTxnClientRespGet(txnp, &bufp, &mloc) != TS_SUCCESS) {
test->test_client_resp_get = false;
SDK_RPRINT(test->regtest, "TSHttpTxnClientRespGet", "TestCase1", TC_FAIL, "Unable to get handle to client response");
return TS_EVENT_CONTINUE;
}
if ((bufp == reinterpret_cast<TSMBuffer>(&((HttpSM *)txnp)->t_state.hdr_info.client_response)) &&
(mloc == reinterpret_cast<TSMLoc>(((HttpSM *)txnp)->t_state.hdr_info.client_response.m_http))) {
test->test_client_resp_get = true;
SDK_RPRINT(test->regtest, "TSHttpTxnClientRespGet", "TestCase1", TC_PASS, "ok");
} else {
test->test_client_resp_get = false;
SDK_RPRINT(test->regtest, "TSHttpTxnClientRespGet", "TestCase1", TC_FAIL, "Value's Mismatch");
}
return TS_EVENT_CONTINUE;
}
// This func is called by us from mytest_handler to test TSHttpTxnServerReqGet
static int
checkHttpTxnServerReqGet(SocketTest *test, void *data)
{
TSMBuffer bufp;
TSMLoc mloc;
TSHttpTxn txnp = (TSHttpTxn)data;
if (TSHttpTxnServerReqGet(txnp, &bufp, &mloc) != TS_SUCCESS) {
test->test_server_req_get = false;
SDK_RPRINT(test->regtest, "TSHttpTxnServerReqGet", "TestCase1", TC_FAIL, "Unable to get handle to server request");
return TS_EVENT_CONTINUE;
}
if ((bufp == reinterpret_cast<TSMBuffer>(&((HttpSM *)txnp)->t_state.hdr_info.server_request)) &&
(mloc == reinterpret_cast<TSMLoc>(((HttpSM *)txnp)->t_state.hdr_info.server_request.m_http))) {
test->test_server_req_get = true;
SDK_RPRINT(test->regtest, "TSHttpTxnServerReqGet", "TestCase1", TC_PASS, "ok");
} else {
test->test_server_req_get = false;
SDK_RPRINT(test->regtest, "TSHttpTxnServerReqGet", "TestCase1", TC_FAIL, "Value's Mismatch");
}
return TS_EVENT_CONTINUE;
}
// This func is called by us from mytest_handler to test TSHttpTxnServerRespGet
static int
checkHttpTxnServerRespGet(SocketTest *test, void *data)
{
TSMBuffer bufp;
TSMLoc mloc;
TSHttpTxn txnp = (TSHttpTxn)data;
if (TSHttpTxnServerRespGet(txnp, &bufp, &mloc) != TS_SUCCESS) {
test->test_server_resp_get = false;
SDK_RPRINT(test->regtest, "TSHttpTxnServerRespGet", "TestCase1", TC_FAIL, "Unable to get handle to server response");
return TS_EVENT_CONTINUE;
}
if ((bufp == reinterpret_cast<TSMBuffer>(&((HttpSM *)txnp)->t_state.hdr_info.server_response)) &&
(mloc == reinterpret_cast<TSMLoc>(((HttpSM *)txnp)->t_state.hdr_info.server_response.m_http))) {
test->test_server_resp_get = true;
SDK_RPRINT(test->regtest, "TSHttpTxnServerRespGet", "TestCase1", TC_PASS, "ok");
} else {
test->test_server_resp_get = false;
SDK_RPRINT(test->regtest, "TSHttpTxnServerRespGet", "TestCase1", TC_FAIL, "Value's Mismatch");
}
return TS_EVENT_CONTINUE;
}
// This func is called both by us when scheduling EVENT_IMMEDIATE
// And by HTTP SM for registered hooks
static int
mytest_handler(TSCont contp, TSEvent event, void *data)
{
SocketTest *test = (SocketTest *)TSContDataGet(contp);
if (test == NULL) {
if ((event == TS_EVENT_IMMEDIATE) || (event == TS_EVENT_TIMEOUT)) {
return 0;
}
TSHttpTxnReenable((TSHttpTxn)data, TS_EVENT_HTTP_CONTINUE);
return 0;
}
TSAssert(test->magic == MAGIC_ALIVE);
TSAssert(test->browser->magic == MAGIC_ALIVE);
switch (event) {
case TS_EVENT_HTTP_TXN_START:
if (test->hook_mask == 0) {
test->hook_mask |= 1;
}
TSHttpTxnReenable((TSHttpTxn)data, TS_EVENT_HTTP_CONTINUE);
test->reenable_mask |= 1;
break;
case TS_EVENT_HTTP_READ_REQUEST_HDR:
if (test->hook_mask == 1) {
test->hook_mask |= 2;
}
TSSkipRemappingSet((TSHttpTxn)data, 1);
checkHttpTxnClientReqGet(test, data);
TSHttpTxnReenable((TSHttpTxn)data, TS_EVENT_HTTP_CONTINUE);
test->reenable_mask |= 2;
break;
case TS_EVENT_HTTP_OS_DNS:
if (test->hook_mask == 7) {
test->hook_mask |= 8;
}
checkHttpTxnIncomingAddrGet(test, data);
checkHttpTxnClientAddrGet(test, data);
checkHttpTxnClientIPGet(test, data);
checkHttpTxnServerIPGet(test, data);
TSHttpTxnReenable((TSHttpTxn)data, TS_EVENT_HTTP_CONTINUE);
test->reenable_mask |= 8;
break;
case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE:
if (test->hook_mask == 3) {
test->hook_mask |= 4;
}
TSHttpTxnReenable((TSHttpTxn)data, TS_EVENT_HTTP_CONTINUE);
test->reenable_mask |= 4;
break;
case TS_EVENT_HTTP_SEND_REQUEST_HDR:
if (test->hook_mask == 15) {
test->hook_mask |= 16;
}
checkHttpTxnServerReqGet(test, data);
checkHttpTxnNextHopIPGet(test, data);
TSHttpTxnReenable((TSHttpTxn)data, TS_EVENT_HTTP_CONTINUE);
test->reenable_mask |= 16;
break;
case TS_EVENT_HTTP_READ_RESPONSE_HDR:
if (test->hook_mask == 31) {
test->hook_mask |= 32;
}
checkHttpTxnServerRespGet(test, data);
TSHttpTxnReenable((TSHttpTxn)data, TS_EVENT_HTTP_CONTINUE);
test->reenable_mask |= 32;
break;
case TS_EVENT_HTTP_SEND_RESPONSE_HDR:
if (test->hook_mask == 63) {
test->hook_mask |= 64;
}
checkHttpTxnClientRespGet(test, data);
TSHttpTxnReenable((TSHttpTxn)data, TS_EVENT_HTTP_CONTINUE);
test->reenable_mask |= 64;
break;
case TS_EVENT_HTTP_TXN_CLOSE:
if (test->hook_mask == 127) {
test->hook_mask |= 128;
}
TSHttpTxnReenable((TSHttpTxn)data, TS_EVENT_HTTP_CONTINUE);
test->reenable_mask |= 128;
break;
case TS_EVENT_IMMEDIATE:
case TS_EVENT_TIMEOUT:
/* Browser still waiting the response ? */
if (test->browser->status == REQUEST_INPROGRESS) {
TSContSchedule(contp, 25, TS_THREAD_POOL_DEFAULT);
}
/* Browser got the response. test is over. clean up */
else {
/* Note: response is available using test->browser->response pointer */
if ((test->browser->status == REQUEST_SUCCESS) && (test->hook_mask == 255)) {
*(test->pstatus) = REGRESSION_TEST_PASSED;
SDK_RPRINT(test->regtest, "TSHttpHookAdd", "TestCase1", TC_PASS, "ok");
} else {
*(test->pstatus) = REGRESSION_TEST_FAILED;
SDK_RPRINT(test->regtest, "TSHttpHookAdd", "TestCase1", TC_FAIL, "Hooks not called or request failure. Hook mask = %d\n %s",
test->hook_mask, test->browser->response);
}
if (test->reenable_mask == 255) {
SDK_RPRINT(test->regtest, "TSHttpTxnReenable", "TestCase1", TC_PASS, "ok");
} else {
*(test->pstatus) = REGRESSION_TEST_FAILED;
SDK_RPRINT(test->regtest, "TSHttpTxnReenable", "TestCase1", TC_FAIL, "Txn not re-enabled properly");
}
if ((test->test_client_ip_get != true) || (test->test_client_incoming_port_get != true) ||
(test->test_client_remote_port_get != true) || (test->test_client_req_get != true) ||
(test->test_client_resp_get != true) || (test->test_server_ip_get != true) || (test->test_server_req_get != true) ||
(test->test_server_resp_get != true) || (test->test_next_hop_ip_get != true)) {
*(test->pstatus) = REGRESSION_TEST_FAILED;
}
// transaction is over. clean up.
synclient_txn_delete(test->browser);
synserver_delete(test->os);
test->magic = MAGIC_DEAD;
TSfree(test);
TSContDataSet(contp, NULL);
}
break;
default:
*(test->pstatus) = REGRESSION_TEST_FAILED;
SDK_RPRINT(test->regtest, "TSHttpHookAdd", "TestCase1", TC_FAIL, "Unexpected event %d", event);
break;
}
return TS_EVENT_IMMEDIATE;
}
EXCLUSIVE_REGRESSION_TEST(SDK_API_HttpHookAdd)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
*pstatus = REGRESSION_TEST_INPROGRESS;
TSCont cont = TSContCreate(mytest_handler, TSMutexCreate());
SocketTest *socktest = (SocketTest *)TSmalloc(sizeof(SocketTest));
socktest->regtest = test;
socktest->pstatus = pstatus;
socktest->hook_mask = 0;
socktest->reenable_mask = 0;
socktest->test_client_ip_get = false;
socktest->test_client_incoming_port_get = false;
socktest->test_client_req_get = false;
socktest->test_client_resp_get = false;
socktest->test_server_ip_get = false;
socktest->test_server_req_get = false;
socktest->test_server_resp_get = false;
socktest->test_next_hop_ip_get = false;
socktest->magic = MAGIC_ALIVE;
TSContDataSet(cont, socktest);
/* Register to HTTP hooks that are called in case of a cache MISS */
TSHttpHookAdd(TS_HTTP_TXN_START_HOOK, cont);
TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, cont);
TSHttpHookAdd(TS_HTTP_OS_DNS_HOOK, cont);
TSHttpHookAdd(TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK, cont);
TSHttpHookAdd(TS_HTTP_SEND_REQUEST_HDR_HOOK, cont);
TSHttpHookAdd(TS_HTTP_READ_RESPONSE_HDR_HOOK, cont);
TSHttpHookAdd(TS_HTTP_SEND_RESPONSE_HDR_HOOK, cont);
TSHttpHookAdd(TS_HTTP_TXN_CLOSE_HOOK, cont);
/* Create a new synthetic server */
socktest->os = synserver_create(SYNSERVER_LISTEN_PORT);
synserver_start(socktest->os);
/* Create a client transaction */
socktest->browser = synclient_txn_create();
char *request = generate_request(HTTP_HOOK_TEST_REQUEST_ID); // this request has a no-cache that prevents caching
synclient_txn_send_request(socktest->browser, request);
TSfree(request);
/* Wait until transaction is done */
if (socktest->browser->status == REQUEST_INPROGRESS) {
TSContSchedule(cont, 25, TS_THREAD_POOL_DEFAULT);
}
return;
}
//////////////////////////////////////////////
// SDK_API_TSUrl
//
// Unit Test for API: TSUrlCreate
// TSUrlSchemeGet
// TSUrlSchemeSet
// TSUrlUserGet
// TSUrlUserSet
// TSUrlPasswordGet
// TSUrlPasswordSet
// TSUrlHostGet
// TSUrlHostSet
// TSUrlPortGet
// TSUrlPortSet
// TSUrlPathGet
// TSUrlPathSet
// TSUrlHttpParamsGet
// TSUrlHttpParamsSet
// TSUrlHttpQueryGet
// TSUrlHttpQuerySet
// TSUrlHttpFragmentGet
// TSUrlHttpFragmentSet
// TSUrlCopy
// TSUrlClone
// TSUrlStringGet
// TSUrlPrint
// TSUrlLengthGet
// TSUrlFtpTypeGet
// TSUrlFtpTypeSet
//////////////////////////////////////////////
char *
test_url_print(TSMBuffer bufp, TSMLoc hdr_loc)
{
TSIOBuffer output_buffer;
TSIOBufferReader reader;
int64_t total_avail;
TSIOBufferBlock block;
const char *block_start;
int64_t block_avail;
char *output_string;
int output_len;
output_buffer = TSIOBufferCreate();
if (!output_buffer) {
TSError("couldn't allocate IOBuffer\n");
}
reader = TSIOBufferReaderAlloc(output_buffer);
/* This will print just MIMEFields and not
the http request line */
TSUrlPrint(bufp, hdr_loc, output_buffer);
/* Find out how the big the complete header is by
seeing the total bytes in the buffer. We need to
look at the buffer rather than the first block to
see the size of the entire header */
total_avail = TSIOBufferReaderAvail(reader);
/* Allocate the string with an extra byte for the string
terminator */
output_string = (char *)TSmalloc(total_avail + 1);
output_len = 0;
/* We need to loop over all the buffer blocks to make
sure we get the complete header since the header can
be in multiple blocks */
block = TSIOBufferReaderStart(reader);
while (block) {
block_start = TSIOBufferBlockReadStart(block, reader, &block_avail);
/* We'll get a block pointer back even if there is no data
left to read so check for this condition and break out of
the loop. A block with no data to read means we've exhausted
buffer of data since if there was more data on a later
block in the chain, this block would have been skipped over */
if (block_avail == 0) {
break;
}
memcpy(output_string + output_len, block_start, block_avail);
output_len += block_avail;
/* Consume the data so that we get to the next block */
TSIOBufferReaderConsume(reader, block_avail);
/* Get the next block now that we've consumed the
data off the last block */
block = TSIOBufferReaderStart(reader);
}
/* Terminate the string */
output_string[output_len] = '\0';
output_len++;
/* Free up the TSIOBuffer that we used to print out the header */
TSIOBufferReaderFree(reader);
TSIOBufferDestroy(output_buffer);
return output_string;
}
REGRESSION_TEST(SDK_API_TSUrl)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
TSMBuffer bufp1 = (TSMBuffer)NULL;
TSMBuffer bufp2 = (TSMBuffer)NULL;
TSMBuffer bufp3 = (TSMBuffer)NULL;
TSMLoc url_loc1;
TSMLoc url_loc2;
TSMLoc url_loc3;
const char *scheme = TS_URL_SCHEME_HTTP;
const char *scheme_get;
const char *user = "yyy";
const char *user_get;
const char *password = "xxx";
const char *password_get;
const char *host = "www.example.com";
const char *host_get;
int port = 2021;
char port_char[10];
int port_get = 80;
const char *path = "about/overview.html";
const char *path_get;
const char *params = "abcdef";
const char *params_get;
const char *query = "name=xxx";
const char *query_get;
const char *fragment = "yyy";
const char *fragment_get;
char *url_expected_string;
char *url_string_from_1 = (char *)NULL;
char *url_string_from_2 = (char *)NULL;
char *url_string_from_3 = (char *)NULL;
char *url_string_from_print = (char *)NULL;
int url_expected_length;
int url_length_from_1;
int url_length_from_2;
int type = 'a';
int type_get;
int tmp_len;
bool test_passed_create = false;
bool test_passed_scheme = false;
bool test_passed_user = false;
bool test_passed_password = false;
bool test_passed_host = false;
bool test_passed_port = false;
bool test_passed_path = false;
bool test_passed_params = false;
bool test_passed_query = false;
bool test_passed_fragment = false;
bool test_passed_copy = false;
bool test_passed_clone = false;
bool test_passed_string1 = false;
bool test_passed_string2 = false;
bool test_passed_print = false;
bool test_passed_length1 = false;
bool test_passed_length2 = false;
bool test_passed_type = false;
int length;
*pstatus = REGRESSION_TEST_INPROGRESS;
// Initialization
memset(port_char, 0, 10);
snprintf(port_char, sizeof(port_char), "%d", port);
// HTTP URL
url_expected_length = strlen(scheme) + strlen("://") + ((user == NULL) ? 0 : strlen(user)) +
((password == NULL) ? ((user == NULL) ? 0 : strlen("@")) : strlen(":") + strlen(password) + strlen("@")) +
strlen(host) + ((port == 80) ? 0 : strlen(port_char) + strlen(":")) + strlen("/") + strlen(path) +
((params == NULL) ? 0 : strlen(";") + strlen(params)) +
((query == NULL) ? 0 : strlen("?") + strlen(query)) +
((fragment == NULL) ? 0 : strlen("#") + strlen(fragment));
size_t len = url_expected_length + 1;
url_expected_string = (char *)TSmalloc(len * sizeof(char));
memset(url_expected_string, 0, url_expected_length + 1);
snprintf(url_expected_string, len, "%s://%s%s%s%s%s%s%s/%s%s%s%s%s%s%s", scheme, ((user == NULL) ? "" : user),
((password == NULL) ? "" : ":"), ((password == NULL) ? "" : password),
(((user == NULL) && (password == NULL)) ? "" : "@"), host, ((port == 80) ? "" : ":"), ((port == 80) ? "" : port_char),
((path == NULL) ? "" : path), ((params == NULL) ? "" : ";"), ((params == NULL) ? "" : params),
((query == NULL) ? "" : "?"), ((query == NULL) ? "" : query), ((fragment == NULL) ? "" : "#"),
((fragment == NULL) ? "" : fragment));
// Set Functions
bufp1 = TSMBufferCreate();
if (TSUrlCreate(bufp1, &url_loc1) != TS_SUCCESS) {
// Cannot proceed with tests.
SDK_RPRINT(test, "TSUrlCreate", "TestCase1", TC_FAIL, "unable to create URL within buffer.");
goto print_results;
}
// Scheme
if (TSUrlSchemeSet(bufp1, url_loc1, scheme, -1) != TS_SUCCESS) {
SDK_RPRINT(test, "TSUrlSchemeSet", "TestCase1", TC_FAIL, "TSUrlSchemeSet Returned TS_ERROR");
} else {
scheme_get = TSUrlSchemeGet(bufp1, url_loc1, &length);
if (strncmp(scheme_get, scheme, length) == 0) {
SDK_RPRINT(test, "TSUrlSchemeSet&Get", "TestCase1", TC_PASS, "ok");
test_passed_scheme = true;
} else {
SDK_RPRINT(test, "TSUrlSchemeSet&Get", "TestCase1", TC_FAIL, "Values don't match");
}
}
// User
if (TSUrlUserSet(bufp1, url_loc1, user, -1) != TS_SUCCESS) {
SDK_RPRINT(test, "TSUrlUserSet", "TestCase1", TC_FAIL, "Returned TS_ERROR");
} else {
user_get = TSUrlUserGet(bufp1, url_loc1, &length);
if (((user_get == NULL) && (user == NULL)) || (strncmp(user_get, user, length) == 0)) {
SDK_RPRINT(test, "TSUrlUserSet&Get", "TestCase1", TC_PASS, "ok");
test_passed_user = true;
} else {
SDK_RPRINT(test, "TSUrlUserSet&Get", "TestCase1", TC_FAIL, "Values don't match");
}
}
// Password
if (TSUrlPasswordSet(bufp1, url_loc1, password, -1) != TS_SUCCESS) {
SDK_RPRINT(test, "TSUrlPasswordSet", "TestCase1", TC_FAIL, "Returned TS_ERROR");
} else {
password_get = TSUrlPasswordGet(bufp1, url_loc1, &length);
if (((password_get == NULL) && (password == NULL)) || (strncmp(password_get, password, length) == 0)) {
SDK_RPRINT(test, "TSUrlPasswordSet&Get", "TestCase1", TC_PASS, "ok");
test_passed_password = true;
} else {
SDK_RPRINT(test, "TSUrlPasswordSet&Get", "TestCase1", TC_FAIL, "Values don't match");
}
}
// Host
if (TSUrlHostSet(bufp1, url_loc1, host, -1) != TS_SUCCESS) {
SDK_RPRINT(test, "TSUrlHostSet", "TestCase1", TC_FAIL, "Returned TS_ERROR");
} else {
host_get = TSUrlHostGet(bufp1, url_loc1, &length);
if (strncmp(host_get, host, length) == 0) {
SDK_RPRINT(test, "TSUrlHostSet&Get", "TestCase1", TC_PASS, "ok");
test_passed_host = true;
} else {
SDK_RPRINT(test, "TSUrlHostSet&Get", "TestCase1", TC_FAIL, "Values don't match");
}
}
// Port
if (TSUrlPortSet(bufp1, url_loc1, port) != TS_SUCCESS) {
SDK_RPRINT(test, "TSUrlPortSet", "TestCase1", TC_FAIL, "Returned TS_ERROR");
} else {
port_get = TSUrlPortGet(bufp1, url_loc1);
if (port_get == port) {
SDK_RPRINT(test, "TSUrlPortSet&Get", "TestCase1", TC_PASS, "ok");
test_passed_port = true;
} else {
SDK_RPRINT(test, "TSUrlPortSet&Get", "TestCase1", TC_FAIL, "Values don't match");
}
}
// Path
if (TSUrlPathSet(bufp1, url_loc1, path, -1) != TS_SUCCESS) {
SDK_RPRINT(test, "TSUrlPathSet", "TestCase1", TC_FAIL, "Returned TS_ERROR");
} else {
path_get = TSUrlPathGet(bufp1, url_loc1, &length);
if (((path == NULL) && (path_get == NULL)) || (strncmp(path, path_get, length) == 0)) {
SDK_RPRINT(test, "TSUrlPathSet&Get", "TestCase1", TC_PASS, "ok");
test_passed_path = true;
} else {
SDK_RPRINT(test, "TSUrlPathSet&Get", "TestCase1", TC_FAIL, "Values don't match");
}
}
// Params
if (TSUrlHttpParamsSet(bufp1, url_loc1, params, -1) != TS_SUCCESS) {
SDK_RPRINT(test, "TSUrlHttpParamsSet", "TestCase1", TC_FAIL, "Returned TS_ERROR");
} else {
params_get = TSUrlHttpParamsGet(bufp1, url_loc1, &length);
if (((params == NULL) && (params_get == NULL)) || (strncmp(params, params_get, length) == 0)) {
SDK_RPRINT(test, "TSUrlHttpParamsSet&Get", "TestCase1", TC_PASS, "ok");
test_passed_params = true;
} else {
SDK_RPRINT(test, "TSUrlHttpParamsSet&Get", "TestCase1", TC_FAIL, "Values don't match");
}
}
// Query
if (TSUrlHttpQuerySet(bufp1, url_loc1, query, -1) != TS_SUCCESS) {
SDK_RPRINT(test, "TSUrlHttpQuerySet", "TestCase1", TC_FAIL, "Returned TS_ERROR");
} else {
query_get = TSUrlHttpQueryGet(bufp1, url_loc1, &length);
if (((query == NULL) && (query_get == NULL)) || (strncmp(query, query_get, length) == 0)) {
SDK_RPRINT(test, "TSUrlHttpQuerySet&Get", "TestCase1", TC_PASS, "ok");
test_passed_query = true;
} else {
SDK_RPRINT(test, "TSUrlHttpQuerySet&Get", "TestCase1", TC_FAIL, "Values don't match");
}
}
// Fragments
if (TSUrlHttpFragmentSet(bufp1, url_loc1, fragment, -1) != TS_SUCCESS) {
SDK_RPRINT(test, "TSUrlHttpFragmentSet", "TestCase1", TC_FAIL, "Returned TS_ERROR");
} else {
fragment_get = TSUrlHttpFragmentGet(bufp1, url_loc1, &length);
if (((fragment == NULL) && (fragment_get == NULL)) || (strncmp(fragment, fragment_get, length) == 0)) {
SDK_RPRINT(test, "TSUrlHttpFragmentSet&Get", "TestCase1", TC_PASS, "ok");
test_passed_fragment = true;
} else {
SDK_RPRINT(test, "TSUrlHttpFragmentSet&Get", "TestCase1", TC_FAIL, "Values don't match");
}
}
// Length
url_length_from_1 = TSUrlLengthGet(bufp1, url_loc1);
if (url_length_from_1 == url_expected_length) {
SDK_RPRINT(test, "TSUrlLengthGet", "TestCase1", TC_PASS, "ok");
test_passed_length1 = true;
} else {
SDK_RPRINT(test, "TSUrlLengthGet", "TestCase1", TC_FAIL, "Values don't match");
}
// String
url_string_from_1 = TSUrlStringGet(bufp1, url_loc1, &tmp_len);
if (strcmp(url_string_from_1, url_expected_string) == 0) {
SDK_RPRINT(test, "TSUrlStringGet", "TestCase1", TC_PASS, "ok");
test_passed_string1 = true;
} else {
SDK_RPRINT(test, "TSUrlStringGet", "TestCase1", TC_FAIL, "Values don't match");
}
// Copy
bufp2 = TSMBufferCreate();
if (TSUrlCreate(bufp2, &url_loc2) != TS_SUCCESS) {
// Cannot proceed with tests.
SDK_RPRINT(test, "TSUrlCreate", "TestCase2", TC_FAIL, "unable to create URL within buffer for TSUrlCopy.");
goto print_results;
}
if (TSUrlCopy(bufp2, url_loc2, bufp1, url_loc1) == TS_ERROR) {
SDK_RPRINT(test, "TSUrlCopy", "TestCase1", TC_FAIL, "Returned TS_ERROR");
} else {
// Length Test Case 2
url_length_from_2 = TSUrlLengthGet(bufp2, url_loc2);
if (url_length_from_2 == url_expected_length) {
SDK_RPRINT(test, "TSUrlLengthGet", "TestCase2", TC_PASS, "ok");
test_passed_length2 = true;
} else {
SDK_RPRINT(test, "TSUrlCopy", "TestCase1", TC_FAIL, "Values don't match");
}
// String Test Case 2
url_string_from_2 = TSUrlStringGet(bufp2, url_loc2, &tmp_len);
if (strcmp(url_string_from_2, url_expected_string) == 0) {
SDK_RPRINT(test, "TSUrlStringGet", "TestCase2", TC_PASS, "ok");
test_passed_string2 = true;
} else {
SDK_RPRINT(test, "TSUrlStringGet", "TestCase2", TC_FAIL, "Values don't match");
}
// Copy Test Case
if (strcmp(url_string_from_1, url_string_from_2) == 0) {
SDK_RPRINT(test, "TSUrlCopy", "TestCase1", TC_PASS, "ok");
test_passed_copy = true;
} else {
SDK_RPRINT(test, "TSUrlCopy", "TestCase1", TC_FAIL, "Values Don't Match");
}
}
// Clone
bufp3 = TSMBufferCreate();
if (TSUrlClone(bufp3, bufp1, url_loc1, &url_loc3) != TS_SUCCESS) {
SDK_RPRINT(test, "TSUrlClone", "TestCase1", TC_FAIL, "Returned TS_ERROR");
} else {
// String Test Case 2
url_string_from_3 = TSUrlStringGet(bufp3, url_loc3, &tmp_len);
// Copy Test Case
if (strcmp(url_string_from_1, url_string_from_3) == 0) {
SDK_RPRINT(test, "TSUrlClone", "TestCase1", TC_PASS, "ok");
test_passed_clone = true;
} else {
SDK_RPRINT(test, "TSUrlClone", "TestCase1", TC_FAIL, "Values Don't Match");
}
}
// UrlPrint
url_string_from_print = test_url_print(bufp1, url_loc1);
if (url_string_from_print == NULL) {
SDK_RPRINT(test, "TSUrlPrint", "TestCase1", TC_FAIL, "TSUrlPrint doesn't return TS_SUCCESS");
} else {
if (strcmp(url_string_from_print, url_expected_string) == 0) {
SDK_RPRINT(test, "TSUrlPrint", "TestCase1", TC_PASS, "ok");
test_passed_print = true;
} else {
SDK_RPRINT(test, "TSUrlPrint", "TestCase1", TC_FAIL, "TSUrlPrint doesn't return TS_SUCCESS");
}
TSfree(url_string_from_print);
}
if (TSUrlFtpTypeSet(bufp1, url_loc1, type) != TS_SUCCESS) {
SDK_RPRINT(test, "TSUrlFtpTypeSet", "TestCase1", TC_FAIL, "TSUrlFtpTypeSet Returned TS_ERROR");
} else {
type_get = TSUrlFtpTypeGet(bufp1, url_loc1);
if (type_get == type) {
SDK_RPRINT(test, "TSUrlFtpTypeSet&Get", "TestCase1", TC_PASS, "ok");
test_passed_type = true;
} else {
SDK_RPRINT(test, "TSUrlFtpTypeSet&Get", "TestCase1", TC_FAIL, "Values don't match");
}
}
SDK_RPRINT(test, "TSUrlCreate", "TestCase1&2", TC_PASS, "ok");
TSHandleMLocRelease(bufp1, TS_NULL_MLOC, url_loc1);
TSHandleMLocRelease(bufp2, TS_NULL_MLOC, url_loc2);
TSHandleMLocRelease(bufp3, TS_NULL_MLOC, url_loc3);
test_passed_create = true;
print_results:
TSfree(url_expected_string);
if (url_string_from_1 != NULL) {
TSfree(url_string_from_1);
}
if (url_string_from_2 != NULL) {
TSfree(url_string_from_2);
}
if (url_string_from_3 != NULL) {
TSfree(url_string_from_3);
}
if (bufp1 != NULL) {
TSMBufferDestroy(bufp1);
}
if (bufp2 != NULL) {
TSMBufferDestroy(bufp2);
}
if (bufp3 != NULL) {
TSMBufferDestroy(bufp3);
}
if ((test_passed_create == false) || (test_passed_scheme == false) || (test_passed_user == false) ||
(test_passed_password == false) || (test_passed_host == false) || (test_passed_port == false) ||
(test_passed_path == false) || (test_passed_params == false) || (test_passed_query == false) ||
(test_passed_fragment == false) || (test_passed_copy == false) || (test_passed_clone == false) ||
(test_passed_string1 == false) || (test_passed_string2 == false) || (test_passed_print == false) ||
(test_passed_length1 == false) || (test_passed_length2 == false) || (test_passed_type == false)) {
/*** Debugging the test itself....
(test_passed_create == false)?printf("test_passed_create is false\n"):printf("");
(test_passed_destroy == false)?printf("test_passed_destroy is false\n"):printf("");
(test_passed_user == false)?printf("test_passed_user is false\n"):printf("");
(test_passed_password == false)?printf("test_passed_password is false\n"):printf("");
(test_passed_host == false)?printf("test_passed_host is false\n"):printf("");
(test_passed_port == false)?printf("test_passed_port is false\n"):printf("");
(test_passed_path == false)?printf("test_passed_path is false\n"):printf("");
(test_passed_params == false)?printf("test_passed_params is false\n"):printf("");
(test_passed_query == false)?printf("test_passed_query is false\n"):printf("");
(test_passed_fragment == false)?printf("test_passed_fragment is false\n"):printf("");
(test_passed_copy == false)?printf("test_passed_copy is false\n"):printf("");
(test_passed_string1 == false)?printf("test_passed_string1 is false\n"):printf("");
(test_passed_string2 == false)?printf("test_passed_string2 is false\n"):printf("");
(test_passed_length1 == false)?printf("test_passed_length1 is false\n"):printf("");
(test_passed_length2 == false)?printf("test_passed_length2 is false\n"):printf("");
(test_passed_type == false)?printf("test_passed_type is false\n"):printf("");
.....***********/
*pstatus = REGRESSION_TEST_FAILED;
} else {
*pstatus = REGRESSION_TEST_PASSED;
}
}
//////////////////////////////////////////////
// SDK_API_TSHttpHdr
//
// Unit Test for API: TSHttpHdrCreate
// TSHttpHdrCopy
// TSHttpHdrClone
// TSHttpHdrDestroy
// TSHttpHdrLengthGet
// TSHttpHdrMethodGet
// TSHttpHdrMethodSet
// TSHttpHdrPrint
// TSHttpHdrReasonGet
// TSHttpHdrReasonLookup
// TSHttpHdrReasonSet
// TSHttpHdrStatusGet
// TSHttpHdrStatusSet
// TSHttpHdrTypeGet
// TSHttpHdrUrlGet
// TSHttpHdrUrlSet
//////////////////////////////////////////////
/**
* If you change value of any constant in this function then reflect that change in variable expected_iobuf.
*/
REGRESSION_TEST(SDK_API_TSHttpHdr)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
TSMBuffer bufp1 = (TSMBuffer)NULL;
TSMBuffer bufp2 = (TSMBuffer)NULL;
TSMBuffer bufp3 = (TSMBuffer)NULL;
TSMBuffer bufp4 = (TSMBuffer)NULL;
TSMLoc hdr_loc1 = (TSMLoc)NULL;
TSMLoc hdr_loc2 = (TSMLoc)NULL;
TSMLoc hdr_loc3 = (TSMLoc)NULL;
TSMLoc hdr_loc4 = (TSMLoc)NULL;
TSHttpType hdr1type;
TSHttpType hdr2type;
const char *methodGet;
TSMLoc url_loc;
TSMLoc url_loc_Get;
const char *url_host = "www.example.com";
int url_port = 2345;
const char *url_path = "abcd/efg/hij.htm";
const char *response_reason = "aefa";
const char *response_reason_get;
TSHttpStatus status_get;
int version_major = 2;
int version_minor = 1;
int version_get;
/* TSHttpType type1; unused: lv */
/* TSHttpType type2; unused: lv */
const char *method1;
const char *method2;
int length1;
int length2;
TSMLoc url_loc1;
TSMLoc url_loc2;
/* int version1; unused: lv */
/* int version2; unused: lv */
int length;
const char *expected_iobuf = "GET http://www.example.com:2345/abcd/efg/hij.htm HTTP/2.1\r\n\r\n";
int actual_length;
int expected_length;
bool test_passed_Http_Hdr_Create = false;
bool test_passed_Http_Hdr_Type = false;
bool test_passed_Http_Hdr_Method = false;
bool test_passed_Http_Hdr_Url = false;
bool test_passed_Http_Hdr_Status = false;
bool test_passed_Http_Hdr_Reason = false;
bool test_passed_Http_Hdr_Reason_Lookup = false;
bool test_passed_Http_Hdr_Version = false;
bool test_passed_Http_Hdr_Copy = false;
bool test_passed_Http_Hdr_Clone = false;
bool test_passed_Http_Hdr_Length = false;
bool test_passed_Http_Hdr_Print = false;
bool test_passed_Http_Hdr_Destroy = false;
bool try_print_function = true;
bool test_buffer_created = true;
*pstatus = REGRESSION_TEST_INPROGRESS;
bufp1 = TSMBufferCreate();
bufp2 = TSMBufferCreate();
bufp3 = TSMBufferCreate();
bufp4 = TSMBufferCreate();
// Create
if (test_buffer_created == true) {
hdr_loc1 = TSHttpHdrCreate(bufp1);
hdr_loc2 = TSHttpHdrCreate(bufp2);
hdr_loc3 = TSHttpHdrCreate(bufp3);
SDK_RPRINT(test, "TSHttpHdrCreate", "TestCase1&2&3", TC_PASS, "ok");
test_passed_Http_Hdr_Create = true;
} else {
SDK_RPRINT(test, "TSHttpHdrCreate", "All Test Cases", TC_FAIL, "Cannot run test as unable to allocate MBuffers");
}
// Type
if (test_passed_Http_Hdr_Create == true) {
if ((TSHttpHdrTypeSet(bufp1, hdr_loc1, TS_HTTP_TYPE_REQUEST) == TS_ERROR) ||
(TSHttpHdrTypeSet(bufp2, hdr_loc2, TS_HTTP_TYPE_RESPONSE) == TS_ERROR)) {
SDK_RPRINT(test, "TSHttpHdrTypeSet", "TestCase1|2", TC_FAIL, "TSHttpHdrTypeSet returns TS_ERROR");
} else {
hdr1type = TSHttpHdrTypeGet(bufp1, hdr_loc1);
hdr2type = TSHttpHdrTypeGet(bufp2, hdr_loc2);
if ((hdr1type == TS_HTTP_TYPE_REQUEST) && (hdr2type == TS_HTTP_TYPE_RESPONSE)) {
SDK_RPRINT(test, "TSHttpHdrTypeSet&Get", "TestCase1&2", TC_PASS, "ok");
test_passed_Http_Hdr_Type = true;
} else {
SDK_RPRINT(test, "TSHttpHdrTypeSet&Get", "TestCase1&2", TC_FAIL, "Values mismatch");
}
}
} else {
SDK_RPRINT(test, "TSHttpHdrTypeSet&Get", "All Test Case", TC_FAIL, "Cannot run test as Header Creation Test failed");
}
// Method
if (test_passed_Http_Hdr_Type == true) {
if (TSHttpHdrMethodSet(bufp1, hdr_loc1, TS_HTTP_METHOD_GET, -1) == TS_ERROR) {
SDK_RPRINT(test, "TSHttpHdrMethodSet&Get", "TestCase1", TC_FAIL, "TSHttpHdrMethodSet returns TS_ERROR");
} else {
methodGet = TSHttpHdrMethodGet(bufp1, hdr_loc1, &length);
if ((strncmp(methodGet, TS_HTTP_METHOD_GET, length) == 0) && (length == (int)strlen(TS_HTTP_METHOD_GET))) {
SDK_RPRINT(test, "TSHttpHdrMethodSet&Get", "TestCase1", TC_PASS, "ok");
test_passed_Http_Hdr_Method = true;
} else {
SDK_RPRINT(test, "TSHttpHdrMethodSet&Get", "TestCase1", TC_FAIL, "Value's mismatch");
}
}
} else {
SDK_RPRINT(test, "TSHttpHdrMethodSet&Get", "All Test Case", TC_FAIL, "Cannot run test as Header's Type cannot be set");
}
// Url
if (test_passed_Http_Hdr_Type == true) {
if (TSUrlCreate(bufp1, &url_loc) != TS_SUCCESS) {
SDK_RPRINT(test, "TSHttpHdrUrlSet&Get", "TestCase1", TC_FAIL, "Cannot run test as TSUrlCreate returns TS_ERROR");
} else {
if (TSHttpHdrUrlSet(bufp1, hdr_loc1, url_loc) == TS_ERROR) {
SDK_RPRINT(test, "TSHttpHdrUrlSet&Get", "TestCase1", TC_FAIL, "TSHttpHdrUrlSet returns TS_ERROR");
} else {
if (TSHttpHdrUrlGet(bufp1, hdr_loc1, &url_loc_Get) != TS_SUCCESS) {
SDK_RPRINT(test, "TSHttpHdrUrlSet&Get", "TestCase1", TC_FAIL, "TSHttpHdrUrlGet retuns TS_ERROR");
} else {
if (url_loc == url_loc_Get) {
SDK_RPRINT(test, "TSHttpHdrUrlSet&Get", "TestCase1", TC_PASS, "ok");
test_passed_Http_Hdr_Url = true;
} else {
SDK_RPRINT(test, "TSHttpHdrUrlSet&Get", "TestCase1", TC_FAIL, "Value's mismatch");
}
if (TSHandleMLocRelease(bufp1, hdr_loc1, url_loc_Get) == TS_ERROR) {
SDK_RPRINT(test, "TSHandleMLocRelease", "", TC_FAIL, "Unable to release handle to URL");
}
}
}
// Fill up the URL for Copy Test Case.
if (TSUrlSchemeSet(bufp1, url_loc, TS_URL_SCHEME_HTTP, -1) == TS_ERROR) {
SDK_RPRINT(test, "TSUrlSchemeSet", "", TC_FAIL, "Unable to set scheme in URL in the HTTP Header");
try_print_function = false;
}
if (TSUrlHostSet(bufp1, url_loc, url_host, -1) == TS_ERROR) {
SDK_RPRINT(test, "TSUrlHostSet", "", TC_FAIL, "Unable to set host in URL in the HTTP Header");
try_print_function = false;
}
if (TSUrlPortSet(bufp1, url_loc, url_port) == TS_ERROR) {
SDK_RPRINT(test, "TSUrlPortSet", "", TC_FAIL, "Unable to set port in URL in the HTTP Header");
try_print_function = false;
}
if (TSUrlPathSet(bufp1, url_loc, url_path, -1) == TS_ERROR) {
SDK_RPRINT(test, "TSUrlPathSet", "", TC_FAIL, "Unable to set path in URL in the HTTP Header");
try_print_function = false;
}
if (TSHandleMLocRelease(bufp1, hdr_loc1, url_loc) == TS_ERROR) {
SDK_RPRINT(test, "TSHandleMLocRelease", "", TC_FAIL, "Unable to release handle to URL");
}
}
} else {
SDK_RPRINT(test, "TSHttpHdrUrlSet&Get", "All Test Case", TC_FAIL, "Cannot run test as Header's Type cannot be set");
}
// Reason
if (test_passed_Http_Hdr_Type == true) {
if (TSHttpHdrReasonSet(bufp2, hdr_loc2, response_reason, -1) == TS_ERROR) {
SDK_RPRINT(test, "TSHttpHdrReasonSet&Get", "TestCase1", TC_FAIL, "TSHttpHdrReasonSet returns TS_ERROR");
} else {
response_reason_get = TSHttpHdrReasonGet(bufp2, hdr_loc2, &length);
if ((strncmp(response_reason_get, response_reason, length) == 0) && (length == (int)strlen(response_reason))) {
SDK_RPRINT(test, "TSHttpHdrReasonSet&Get", "TestCase1", TC_PASS, "ok");
test_passed_Http_Hdr_Reason = true;
} else {
SDK_RPRINT(test, "TSHttpHdrReasonSet&Get", "TestCase1", TC_FAIL, "Value's mismatch");
}
}
} else {
SDK_RPRINT(test, "TSHttpHdrReasonSet&Get", "All Test Case", TC_FAIL, "Cannot run test as Header's Type cannot be set");
}
// Status
if (test_passed_Http_Hdr_Type == true) {
if (TSHttpHdrStatusSet(bufp2, hdr_loc2, TS_HTTP_STATUS_OK) == TS_ERROR) {
SDK_RPRINT(test, "TSHttpHdrStatusSet&Get", "TestCase1", TC_FAIL, "TSHttpHdrStatusSet returns TS_ERROR");
} else {
status_get = TSHttpHdrStatusGet(bufp2, hdr_loc2);
if (status_get == TS_HTTP_STATUS_OK) {
SDK_RPRINT(test, "TSHttpHdrStatusSet&Get", "TestCase1", TC_PASS, "ok");
test_passed_Http_Hdr_Status = true;
} else {
SDK_RPRINT(test, "TSHttpHdrStatusSet&Get", "TestCase1", TC_FAIL, "Value's mismatch");
}
}
} else {
SDK_RPRINT(test, "TSHttpHdrStatusSet&Get", "All Test Case", TC_FAIL, "Cannot run test as Header's Type cannot be set");
}
// Version
if (test_passed_Http_Hdr_Type == true) {
if (TSHttpHdrVersionSet(bufp1, hdr_loc1, TS_HTTP_VERSION(version_major, version_minor)) == TS_ERROR) {
SDK_RPRINT(test, "TSHttpHdrVersionSet&Get", "TestCase1", TC_FAIL, "TSHttpHdrVersionSet returns TS_ERROR");
} else {
version_get = TSHttpHdrVersionGet(bufp1, hdr_loc1);
if ((version_major == TS_HTTP_MAJOR(version_get)) && (version_minor == TS_HTTP_MINOR(version_get))) {
SDK_RPRINT(test, "TSHttpHdrVersionSet&Get", "TestCase1", TC_PASS, "ok");
test_passed_Http_Hdr_Version = true;
} else {
SDK_RPRINT(test, "TSHttpHdrVersionSet&Get", "TestCase1", TC_FAIL, "Value's mismatch");
}
}
} else {
SDK_RPRINT(test, "TSHttpHdrVersionSet&Get", "All Test Case", TC_FAIL, "Cannot run test as Header's Type cannot be set");
}
if (test_passed_Http_Hdr_Version == true) {
if (TSHttpHdrVersionSet(bufp2, hdr_loc2, TS_HTTP_VERSION(version_major, version_minor)) == TS_ERROR) {
SDK_RPRINT(test, "TSHttpHdrVersionSet&Get", "TestCase2", TC_FAIL, "TSHttpHdrVersionSet returns TS_ERROR");
test_passed_Http_Hdr_Version = false;
} else {
version_get = TSHttpHdrVersionGet(bufp2, hdr_loc2);
if ((version_major == TS_HTTP_MAJOR(version_get)) && (version_minor == TS_HTTP_MINOR(version_get))) {
SDK_RPRINT(test, "TSHttpHdrVersionSet&Get", "TestCase2", TC_PASS, "ok");
} else {
SDK_RPRINT(test, "TSHttpHdrVersionSet&Get", "TestCase2", TC_FAIL, "Value's mismatch");
test_passed_Http_Hdr_Version = false;
}
}
}
// Reason Lookup
if (strcmp("None", TSHttpHdrReasonLookup(TS_HTTP_STATUS_NONE)) != 0) {
SDK_RPRINT(test, "TSHttpHdrReasonLookup", "TestCase1", TC_FAIL, "TSHttpHdrReasonLookup returns Value's mismatch");
} else {
SDK_RPRINT(test, "TSHttpHdrReasonLookup", "TestCase1", TC_PASS, "ok");
test_passed_Http_Hdr_Reason_Lookup = true;
}
if (strcmp("OK", TSHttpHdrReasonLookup(TS_HTTP_STATUS_OK)) != 0) {
SDK_RPRINT(test, "TSHttpHdrReasonLookup", "TestCase2", TC_FAIL, "TSHttpHdrReasonLookup returns Value's mismatch");
if (test_passed_Http_Hdr_Reason_Lookup == true) {
test_passed_Http_Hdr_Reason_Lookup = false;
}
} else {
SDK_RPRINT(test, "TSHttpHdrReasonLookup", "TestCase2", TC_PASS, "ok");
}
if (strcmp("Continue", TSHttpHdrReasonLookup(TS_HTTP_STATUS_CONTINUE)) != 0) {
SDK_RPRINT(test, "TSHttpHdrReasonLookup", "TestCase3", TC_FAIL, "TSHttpHdrReasonLookup returns Value's mismatch");
if (test_passed_Http_Hdr_Reason_Lookup == true) {
test_passed_Http_Hdr_Reason_Lookup = false;
}
} else {
SDK_RPRINT(test, "TSHttpHdrReasonLookup", "TestCase3", TC_PASS, "ok");
}
if (strcmp("Not Modified", TSHttpHdrReasonLookup(TS_HTTP_STATUS_NOT_MODIFIED)) != 0) {
SDK_RPRINT(test, "TSHttpHdrReasonLookup", "TestCase2", TC_FAIL, "TSHttpHdrReasonLookup returns Value's mismatch");
if (test_passed_Http_Hdr_Reason_Lookup == true) {
test_passed_Http_Hdr_Reason_Lookup = false;
}
} else {
SDK_RPRINT(test, "TSHttpHdrReasonLookup", "TestCase4", TC_PASS, "ok");
}
// Copy
if (test_passed_Http_Hdr_Create == true) {
if (TSHttpHdrCopy(bufp3, hdr_loc3, bufp1, hdr_loc1) == TS_ERROR) {
SDK_RPRINT(test, "TSHttpHdrCopy", "TestCase1", TC_FAIL, "TSHttpHdrCopy returns TS_ERROR");
} else {
bool flag = true;
// Check the type
if (flag == true) {
TSHttpType type1 = TSHttpHdrTypeGet(bufp1, hdr_loc1);
TSHttpType type2 = TSHttpHdrTypeGet(bufp3, hdr_loc3);
if (type1 != type2) {
SDK_RPRINT(test, "TSHttpHdrCopy", "TestCase1", TC_FAIL, "Type mismatch in both headers");
flag = false;
}
}
// Check the Version
if (flag == true) {
int version1 = TSHttpHdrVersionGet(bufp1, hdr_loc1);
int version2 = TSHttpHdrVersionGet(bufp3, hdr_loc3);
if (version1 != version2) {
SDK_RPRINT(test, "TSHttpHdrCopy", "TestCase1", TC_FAIL, "Version mismatch in both headers");
flag = false;
}
}
// Check the Method
if (flag == true) {
method1 = TSHttpHdrMethodGet(bufp1, hdr_loc1, &length1);
method2 = TSHttpHdrMethodGet(bufp3, hdr_loc3, &length2);
if ((length1 != length2) || (strncmp(method1, method2, length1) != 0)) {
SDK_RPRINT(test, "TSHttpHdrCopy", "TestCase1", TC_FAIL, "Method mismatch in both headers");
flag = false;
}
}
// Check the URL
if (flag == true) {
if ((TSHttpHdrUrlGet(bufp1, hdr_loc1, &url_loc1) != TS_SUCCESS) ||
(TSHttpHdrUrlGet(bufp3, hdr_loc3, &url_loc2) != TS_SUCCESS)) {
SDK_RPRINT(test, "TSHttpHdrCopy", "TestCase1", TC_FAIL, "TSHttpVersionGet returns TS_ERROR");
} else {
const char *scheme1;
const char *scheme2;
const char *host1;
const char *host2;
int port1;
int port2;
const char *path1;
const char *path2;
// URL Scheme
scheme1 = TSUrlSchemeGet(bufp1, url_loc1, &length1);
scheme2 = TSUrlSchemeGet(bufp3, url_loc2, &length2);
if ((length1 != length2) || (strncmp(scheme1, scheme2, length1) != 0)) {
SDK_RPRINT(test, "TSHttpHdrCopy", "TestCase1", TC_FAIL, "Url Scheme has different values in both headers");
flag = false;
}
// URL Host
if (flag == true) {
host1 = TSUrlHostGet(bufp1, url_loc1, &length1);
host2 = TSUrlHostGet(bufp3, url_loc2, &length2);
if ((length1 != length2) || (strncmp(host1, host2, length1) != 0)) {
SDK_RPRINT(test, "TSHttpHdrCopy", "TestCase1", TC_FAIL, "Url Host has different values in both headers");
flag = false;
}
}
// URL Port
if (flag == true) {
port1 = TSUrlPortGet(bufp1, url_loc1);
port2 = TSUrlPortGet(bufp3, url_loc2);
if (port1 != port2) {
SDK_RPRINT(test, "TSHttpHdrCopy", "TestCase1", TC_FAIL, "Url Port has different values in both headers");
flag = false;
}
}
// URL Path
if (flag == true) {
path1 = TSUrlPathGet(bufp1, url_loc1, &length1);
path2 = TSUrlPathGet(bufp3, url_loc2, &length2);
if ((path1 != NULL) && (path2 != NULL)) {
if ((length1 != length2) || (strncmp(path1, path2, length1) != 0)) {
SDK_RPRINT(test, "TSHttpHdrCopy", "TestCase1", TC_FAIL, "Url Path has different values in both headers");
flag = false;
}
} else {
if (path1 != path2) {
SDK_RPRINT(test, "TSHttpHdrCopy", "TestCase1", TC_FAIL, "Url Host has different values in both headers");
flag = false;
}
}
if ((TSHandleMLocRelease(bufp1, hdr_loc1, url_loc1) == TS_ERROR) ||
(TSHandleMLocRelease(bufp3, hdr_loc3, url_loc2) == TS_ERROR)) {
SDK_RPRINT(test, "TSHandleMLocRelease", "", TC_FAIL, "Unable to release Handle acquired by TSHttpHdrUrlGet");
}
}
if (flag == true) {
SDK_RPRINT(test, "TSHttpHdrCopy", "TestCase1", TC_PASS, "ok");
test_passed_Http_Hdr_Copy = true;
}
}
}
}
} else {
SDK_RPRINT(test, "TSHttpHdrCopy", "All Test Cases", TC_PASS, "Cannot run test as TSHttpHdrCreate has failed");
}
// Clone
if (test_passed_Http_Hdr_Create == true) {
if (TSHttpHdrClone(bufp4, bufp1, hdr_loc1, &hdr_loc4) != TS_SUCCESS) {
SDK_RPRINT(test, "TSHttpHdrClone", "TestCase1", TC_FAIL, "TSHttpHdrClone returns TS_ERROR");
} else {
bool flag = true;
// Check the type
if (flag == true) {
TSHttpType type1 = TSHttpHdrTypeGet(bufp1, hdr_loc1);
TSHttpType type2 = TSHttpHdrTypeGet(bufp4, hdr_loc4);
if (type1 != type2) {
SDK_RPRINT(test, "TSHttpHdrClone", "TestCase1", TC_FAIL, "Type mismatch in both headers");
flag = false;
}
}
// Check the Version
if (flag == true) {
int version1 = TSHttpHdrVersionGet(bufp1, hdr_loc1);
int version2 = TSHttpHdrVersionGet(bufp4, hdr_loc4);
if (version1 != version2) {
SDK_RPRINT(test, "TSHttpHdrClone", "TestCase1", TC_FAIL, "Version mismatch in both headers");
flag = false;
}
}
// Check the Method
if (flag == true) {
method1 = TSHttpHdrMethodGet(bufp1, hdr_loc1, &length1);
method2 = TSHttpHdrMethodGet(bufp4, hdr_loc4, &length2);
if ((length1 != length2) || (strncmp(method1, method2, length1) != 0)) {
SDK_RPRINT(test, "TSHttpHdrClone", "TestCase1", TC_FAIL, "Method mismatch in both headers");
flag = false;
}
}
// Check the URL
if (flag == true) {
if ((TSHttpHdrUrlGet(bufp1, hdr_loc1, &url_loc1) != TS_SUCCESS) ||
(TSHttpHdrUrlGet(bufp4, hdr_loc4, &url_loc2) != TS_SUCCESS)) {
SDK_RPRINT(test, "TSHttpHdrClone", "TestCase1", TC_FAIL, "TSHttpVersionGet returns TS_ERROR");
} else {
const char *scheme1;
const char *scheme2;
const char *host1;
const char *host2;
int port1;
int port2;
const char *path1;
const char *path2;
// URL Scheme
scheme1 = TSUrlSchemeGet(bufp1, url_loc1, &length1);
scheme2 = TSUrlSchemeGet(bufp4, url_loc2, &length2);
if ((length1 != length2) || (strncmp(scheme1, scheme2, length1) != 0)) {
SDK_RPRINT(test, "TSHttpHdrClone", "TestCase1", TC_FAIL, "Url Scheme has different values in both headers");
flag = false;
}
// URL Host
if (flag == true) {
host1 = TSUrlHostGet(bufp1, url_loc1, &length1);
host2 = TSUrlHostGet(bufp4, url_loc2, &length2);
if ((length1 != length2) || (strncmp(host1, host2, length1) != 0)) {
SDK_RPRINT(test, "TSHttpHdrClone", "TestCase1", TC_FAIL, "Url Host has different values in both headers");
flag = false;
}
}
// URL Port
if (flag == true) {
port1 = TSUrlPortGet(bufp1, url_loc1);
port2 = TSUrlPortGet(bufp4, url_loc2);
if (port1 != port2) {
SDK_RPRINT(test, "TSHttpHdrClone", "TestCase1", TC_FAIL, "Url Port has different values in both headers");
flag = false;
}
}
// URL Path
if (flag == true) {
path1 = TSUrlPathGet(bufp1, url_loc1, &length1);
path2 = TSUrlPathGet(bufp4, url_loc2, &length2);
if ((path1 != NULL) && (path2 != NULL)) {
if ((length1 != length2) || (strncmp(path1, path2, length1) != 0)) {
SDK_RPRINT(test, "TSHttpHdrCopy", "TestCase1", TC_FAIL, "Url Path has different values in both headers");
flag = false;
}
} else {
if (path1 != path2) {
SDK_RPRINT(test, "TSHttpHdrCopy", "TestCase1", TC_FAIL, "Url Host has different values in both headers");
flag = false;
}
}
if ((TSHandleMLocRelease(bufp1, hdr_loc1, url_loc1) == TS_ERROR) ||
(TSHandleMLocRelease(bufp4, hdr_loc4, url_loc2) == TS_ERROR)) {
SDK_RPRINT(test, "TSHandleMLocRelease", "", TC_FAIL, "Unable to release Handle acquired by TSHttpHdrUrlGet");
}
}
if (flag == true) {
SDK_RPRINT(test, "TSHttpHdrClone", "TestCase1", TC_PASS, "ok");
test_passed_Http_Hdr_Clone = true;
}
}
}
}
} else {
SDK_RPRINT(test, "TSHttpHdrClone", "All Test Cases", TC_PASS, "Cannot run test as TSHttpHdrCreate has failed");
}
// LengthGet
if (test_passed_Http_Hdr_Create == true) {
actual_length = TSHttpHdrLengthGet(bufp1, hdr_loc1);
TSIOBuffer iobuf = TSIOBufferCreate();
TSHttpHdrPrint(bufp1, hdr_loc1, iobuf);
TSIOBufferReader iobufreader = TSIOBufferReaderAlloc(iobuf);
expected_length = TSIOBufferReaderAvail(iobufreader);
if (actual_length == expected_length) {
SDK_RPRINT(test, "TSHttpHdrLengthGet", "TestCase1", TC_PASS, "ok");
test_passed_Http_Hdr_Length = true;
} else {
SDK_RPRINT(test, "TSHttpHdrLengthGet", "TestCase1", TC_FAIL, "Incorrect value returned.");
}
// Print.
if ((test_passed_Http_Hdr_Method == true) && (test_passed_Http_Hdr_Url == true) && (test_passed_Http_Hdr_Version == true) &&
(test_passed_Http_Hdr_Length == true) && (try_print_function == true)) {
char *actual_iobuf = NULL;
actual_iobuf = (char *)TSmalloc((actual_length + 1) * sizeof(char));
if (actual_iobuf == NULL) {
SDK_RPRINT(test, "TSHttpHdrPrint", "TestCase1", TC_FAIL, "Unable to allocate memory");
} else {
TSIOBufferBlock iobufblock;
int64_t bytes_read;
memset(actual_iobuf, 0, (actual_length + 1) * sizeof(char));
bytes_read = 0;
iobufblock = TSIOBufferReaderStart(iobufreader);
while (iobufblock != NULL) {
const char *block_start;
int64_t block_size;
block_start = TSIOBufferBlockReadStart(iobufblock, iobufreader, &block_size);
if (block_size <= 0)
break;
memcpy(actual_iobuf + bytes_read, block_start, block_size);
bytes_read += block_size;
TSIOBufferReaderConsume(iobufreader, block_size);
iobufblock = TSIOBufferReaderStart(iobufreader);
}
if (strcmp(actual_iobuf, expected_iobuf) == 0) {
SDK_RPRINT(test, "TSHttpHdrPrint", "TestCase1", TC_PASS, "ok");
test_passed_Http_Hdr_Print = true;
} else {
SDK_RPRINT(test, "TSHttpHdrPrint", "TestCase1", TC_FAIL, "Value's mismatch");
}
TSfree(actual_iobuf);
TSIOBufferReaderFree(iobufreader);
TSIOBufferDestroy(iobuf);
}
} else {
SDK_RPRINT(test, "TSHttpHdrPrint", "TestCase1", TC_FAIL, "Unable to run test for TSHttpHdrPrint");
}
} else {
SDK_RPRINT(test, "TSHttpHdrLengthGet", "All Test Cases", TC_PASS, "Cannot run test as TSHttpHdrCreate has failed");
}
// Destroy
if (test_passed_Http_Hdr_Create == true) {
TSHttpHdrDestroy(bufp1, hdr_loc1);
TSHttpHdrDestroy(bufp2, hdr_loc2);
TSHttpHdrDestroy(bufp3, hdr_loc3);
TSHttpHdrDestroy(bufp4, hdr_loc4);
if ((TSHandleMLocRelease(bufp1, TS_NULL_MLOC, hdr_loc1) == TS_ERROR) ||
(TSHandleMLocRelease(bufp2, TS_NULL_MLOC, hdr_loc2) == TS_ERROR) ||
(TSHandleMLocRelease(bufp3, TS_NULL_MLOC, hdr_loc3) == TS_ERROR) ||
(TSHandleMLocRelease(bufp4, TS_NULL_MLOC, hdr_loc4) == TS_ERROR)) {
SDK_RPRINT(test, "TSHandleMLocRelease", "TestCase1|2|3|4", TC_FAIL, "Unable to release the handle to headers");
}
SDK_RPRINT(test, "TSHttpHdrDestroy", "TestCase1&2&3&4", TC_PASS, "ok");
test_passed_Http_Hdr_Destroy = true;
} else {
SDK_RPRINT(test, "TSHttpHdrDestroy", "All Test Cases", TC_FAIL, "Cannot run test as header was not created");
}
if (bufp1) {
if (TSMBufferDestroy(bufp1) == TS_ERROR) {
SDK_RPRINT(test, "TSMBufferDestroy", "TestCase1", TC_FAIL, "Unable to destroy MBuffer");
}
}
if (bufp2) {
if (TSMBufferDestroy(bufp2) == TS_ERROR) {
SDK_RPRINT(test, "TSMBufferDestroy", "TestCase2", TC_FAIL, "Unable to destroy MBuffer");
}
}
if (bufp3) {
if (TSMBufferDestroy(bufp3) == TS_ERROR) {
SDK_RPRINT(test, "TSMBufferDestroy", "TestCase3", TC_FAIL, "Unable to destroy MBuffer");
}
}
if (bufp4) {
if (TSMBufferDestroy(bufp4) == TS_ERROR) {
SDK_RPRINT(test, "TSMBufferDestroy", "TestCase4", TC_FAIL, "Unable to destroy MBuffer");
}
}
if ((test_passed_Http_Hdr_Create == true) && (test_passed_Http_Hdr_Type == true) && (test_passed_Http_Hdr_Method == true) &&
(test_passed_Http_Hdr_Url == true) && (test_passed_Http_Hdr_Status == true) && (test_passed_Http_Hdr_Reason == true) &&
(test_passed_Http_Hdr_Reason_Lookup == true) && (test_passed_Http_Hdr_Version == true) &&
(test_passed_Http_Hdr_Copy == true) && (test_passed_Http_Hdr_Clone == true) && (test_passed_Http_Hdr_Length == true) &&
(test_passed_Http_Hdr_Print == true) && (test_passed_Http_Hdr_Destroy == true)) {
*pstatus = REGRESSION_TEST_PASSED;
} else {
*pstatus = REGRESSION_TEST_FAILED;
}
return;
}
//////////////////////////////////////////////
// SDK_API_TSMimeHdrField
//
// Unit Test for API: TSMBufferCreate
// TSMBufferDestroy
// TSMimeHdrCreate
// TSMimeHdrDestroy
// TSMimeHdrFieldCreate
// TSMimeHdrFieldDestroy
// TSMimeHdrFieldFind
// TSMimeHdrFieldGet
// TSMimeHdrFieldAppend
// TSMimeHdrFieldNameGet
// TSMimeHdrFieldNameSet
// TSMimeHdrFieldNext
// TSMimeHdrFieldsClear
// TSMimeHdrFieldsCount
// TSMimeHdrFieldValueAppend
// TSMimeHdrFieldValueDelete
// TSMimeHdrFieldValueStringGet
// TSMimeHdrFieldValueDateGet
// TSMimeHdrFieldValueIntGet
// TSMimeHdrFieldValueUintGet
// TSMimeHdrFieldValueStringInsert
// TSMimeHdrFieldValueDateInsert
// TSMimeHdrFieldValueIntInsert
// TSMimeHdrFieldValueUintInsert
// TSMimeHdrFieldValuesClear
// TSMimeHdrFieldValuesCount
// TSMimeHdrFieldValueStringSet
// TSMimeHdrFieldValueDateSet
// TSMimeHdrFieldValueIntSet
// TSMimeHdrFieldValueUintSet
// TSMimeHdrLengthGet
// TSMimeHdrPrint
//////////////////////////////////////////////
TSReturnCode
compare_field_names(RegressionTest * /* test ATS_UNUSED */, TSMBuffer bufp1, TSMLoc mime_loc1, TSMLoc field_loc1, TSMBuffer bufp2,
TSMLoc mime_loc2, TSMLoc field_loc2)
{
const char *name1;
const char *name2;
int length1;
int length2;
name1 = TSMimeHdrFieldNameGet(bufp1, mime_loc1, field_loc1, &length1);
name2 = TSMimeHdrFieldNameGet(bufp2, mime_loc2, field_loc2, &length2);
if ((length1 == length2) && (strncmp(name1, name2, length1) == 0)) {
return TS_SUCCESS;
} else {
return TS_ERROR;
}
}
REGRESSION_TEST(SDK_API_TSMimeHdrField)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus)
{
TSMBuffer bufp1 = (TSMBuffer)NULL;
TSMLoc mime_loc1 = (TSMLoc)NULL;
TSMLoc field_loc11 = (TSMLoc)NULL;
TSMLoc field_loc12 = (TSMLoc)NULL;
TSMLoc field_loc13 = (TSMLoc)NULL;
TSMLoc field_loc14 = (TSMLoc)NULL;
TSMLoc field_loc15 = (TSMLoc)NULL;
const char *field1Name = "field1";
const char *field2Name = "field2";
const char *field3Name = "field3";
const char *field4Name = "field4";
const char *field5Name = "field5";
const char *field1NameGet;
const char *field2NameGet;
const char *field3NameGet;
const char *field4NameGet;
const char *field5NameGet;
int field1NameGetLength;
int field2NameGetLength;
int field3NameGetLength;</