static void s_Walk(HEAP heap, const char* which) { unsigned int i = 0; SHEAP_Block* blk = 0; TNCBI_Size total = 0; CORE_LOGF(eLOG_Note, ("Walking %s%sheap", which && *which ? which : "", &" "[!which || !*which])); while ((blk = HEAP_Walk(heap, blk)) != 0) { const char* flag = (int) blk->flag < 0 ? ", last" : ""; TNCBI_Size size = blk->size; if ((short) blk->flag) { TNCBI_Size data_size = size - sizeof(*blk); CORE_LOGF(eLOG_Note, ("Used%s @%u, size %u, data size %u", flag, HEAP_ADDR(blk, heap), size, data_size)); assert(data_size); } else { unsigned int* ptr = (unsigned int*) blk; CORE_LOGF(eLOG_Note, ("Free%s @%u, size %u, <-%u, %u->", flag, HEAP_ADDR(blk, heap), size, ptr[2], ptr[3])); } total += size; i++; } CORE_LOGF(eLOG_Note, ("%d block%s total; total size %u", i, &"s"[i == 1], total)); }
static HEAP s_Shmem_Attach(int which) { void* shmem = 0; /*dummy init for compiler not to complain*/ int shmid; HEAP heap; #ifdef LBSM_DEBUG CORE_LOGF(eLOG_Trace, ("LBSM shmem[%d] attaching", which + 1)); #endif /*LBSM_DEBUG*/ if ((shmid = shmget(k_ShmemKey[which], 0, 0)) >= 0 && (shmid == s_Shmid[which] || ((shmem = shmat(shmid, 0, SHM_RDONLY)) && shmem != (void*)(-1)))) { if (shmid != s_Shmid[which]) { struct shmid_ds shm_ds; #ifdef LBSM_DEBUG CORE_LOGF(eLOG_Trace, ("LBSM shmem[%d] attached", which + 1)); #endif /*LBSM_DEBUG*/ s_Shmid[which] = shmid; if (s_Shmem[which]) shmdt(s_Shmem[which]); s_Shmem[which] = shmem; s_ShmemSize[which] = (shmctl(shmid, IPC_STAT, &shm_ds) < 0 ? 0 : shm_ds.shm_segsz); } heap = (s_ShmemSize[which] ? HEAP_AttachFast(s_Shmem[which], s_ShmemSize[which], which+1) : HEAP_Attach (s_Shmem[which], which+1)); } else heap = 0; return heap; }
static unsigned int TEST_gethostbyname(const char* name) { char buf[256]; unsigned int host; CORE_LOG(eLOG_Note, "------------"); host = SOCK_gethostbyname(name); CORE_LOGF(eLOG_Note, ("SOCK_gethostbyname(\"%s\"): 0x%08X [%s]", name, (unsigned int) SOCK_NetToHostLong(host), s_ntoa(host))); if ( host ) { name = SOCK_gethostbyaddr(host, buf, sizeof(buf)); if ( name ) { assert(name == buf); assert(0 < strlen(buf) && strlen(buf) < sizeof(buf)); CORE_LOGF(eLOG_Note, ("SOCK_gethostbyaddr(0x%08X [%s]): \"%s\"", (unsigned int) SOCK_NetToHostLong(host), s_ntoa(host), name)); } else { CORE_LOGF(eLOG_Note, ("SOCK_gethostbyaddr(0x%08X [%s]): <not found>", (unsigned int) SOCK_NetToHostLong(host), s_ntoa(host))); } } return host; }
static int/*bool*/ TEST_gethostbyaddr(unsigned int host) { const char* name; char buf[1024]; CORE_LOG(eLOG_Note, "------------"); name = SOCK_gethostbyaddr(host, buf, sizeof(buf)); if ( name ) { assert(name == buf); assert(0 < strlen(buf) && strlen(buf) < sizeof(buf)); CORE_LOGF(eLOG_Note, ("SOCK_gethostbyaddr(0x%08X [%s]): \"%s\"", (unsigned int) SOCK_NetToHostLong(host), s_ntoa(host), name)); } else { CORE_LOGF(eLOG_Note, ("SOCK_gethostbyaddr(0x%08X [%s]): <not found>", (unsigned int) SOCK_NetToHostLong(host), s_ntoa(host))); return 0/*false*/; } host = SOCK_gethostbyname(name); CORE_LOGF(eLOG_Note, ("SOCK_gethostbyname(\"%s\"): 0x%08X [%s]", name, (unsigned int) SOCK_NetToHostLong(host), s_ntoa(host))); return 1/*true*/; }
/*ARGSUSED*/ static const SLBSM_Sysinfo* s_GetSysinfo(const HOST_INFO hinfo, int/*bool*/ warn) { const SLBSM_Sysinfo* si = (const SLBSM_Sysinfo*)((const char*) hinfo + sizeof(*hinfo)); assert(hinfo); #if defined(_DEBUG) && !defined(NDEBUG) && defined(NETDAEMONS_VERSION_INT) if (si->data.version < NETDAEMONS_VERSION_INT && warn) { static int s_Warn = 0; if (s_Warn < 20) { char addr[64]; if (SOCK_ntoa(hinfo->addr, addr, sizeof(addr)) != 0) strncpy0(addr, "unknown", sizeof(addr) - 1); CORE_LOGF(s_Warn++ < 5 ? eLOG_Warning : eLOG_Trace, ("HINFO may be incorrect for obsolete daemon on %s" " (detected=%hu.%hu.%hu, expected=%s+)", addr, NETDAEMONS_MAJOR_OF(si->data.version), NETDAEMONS_MINOR_OF(si->data.version), NETDAEMONS_PATCH_OF(si->data.version), NETDAEMONS_VERSION_STR)); } } #endif /*_DEBUG && !NDEBUG && NETDAEMONS_VERSION_INT*/ return si; }
const char* LBSMD_GetConfig(void) { const char* s = 0; HEAP heap; if (LBSM_LBSMD(0) > 0 && errno == EAGAIN) { if ((heap = s_GetHeapCopy(time(0))) != 0) { if ((s = LBSM_GetConfig(heap)) != 0) s = strdup(s); #ifdef LBSM_DEBUG CORE_LOGF(eLOG_Trace, ("LBSM heap[%p, %p, %d] released", heap, HEAP_Base(heap), HEAP_Serial(heap))); #endif /*LBSM_DEBUG*/ CORE_LOCK_WRITE; HEAP_Detach(heap); CORE_UNLOCK; } } if (!s_FastHeapAccess) { /* As a documented side effect, clean up cached copy of LBSM heap */ s_Fini(); } return s; }
static int/*bool*/ s_Shmem_RUnlock(int which) { #ifdef LBSM_DEBUG CORE_LOGF(eLOG_Trace, ("LBSM R-lock[%d] release", which + 1)); #endif /*LBSM_DEBUG*/ /* Decrement number of accessors, [2] */ return s_Shmem_Unlock(which, 2) == 0; }
static void TEST__server(const char* sport) { int i; unsigned short nport; LSOCK lsock; EIO_Status status; /* Create listening socket */ if (sscanf(sport, "%hu%n", &nport, &i) < 1 || sport[i]) { nport = 0; i = 0; } status = LSOCK_CreateEx(nport, N_RECONNECT * 10, &lsock, fSOCK_LogOn); if (status == eIO_Success && !nport && sport[i]) { FILE* fp; nport = LSOCK_GetPort(lsock, eNH_HostByteOrder); if (nport && (fp = fopen(sport, "w")) != 0) { if (fprintf(fp, "%hu", nport) < 1 || fflush(fp) != 0) status = eIO_Unknown; fclose(fp); } else status = eIO_Unknown; } CORE_LOGF(eLOG_Note, ("TEST__server(port = %hu)", nport)); assert(status == eIO_Success); /* Accept connections from clients and run test sessions */ for (;;) { char full[80]; char addr[80]; char port[10]; SOCK sock; status = LSOCK_Accept(lsock, NULL, &sock); assert(status == eIO_Success); assert(SOCK_GetPeerAddressString (sock, full,sizeof(full))); assert(SOCK_GetPeerAddressStringEx(sock, addr,sizeof(addr),eSAF_IP)); assert(SOCK_GetPeerAddressStringEx(sock, port,sizeof(port),eSAF_Port)); assert(strcmp(full, strcat(strcat(addr, ":"), port)) == 0); /* Test the simplest randezvous(plain request-reply) * The two peer functions are: * "TEST__[client|server]_1(SOCK sock)" */ TEST__server_1(sock); status = LSOCK_Accept(lsock, NULL, &sock); assert(status == eIO_Success); /* Test a more complex case * The two peer functions are: * "TEST__[client|server]_2(SOCK sock)" */ TEST__server_2(sock, lsock); } }
HEAP LBSM_Shmem_Attach(void) { int fallback = 0; /*FIXME: to become a parameter*/ int which; HEAP heap; #ifdef LBSM_DEBUG CORE_LOG(eLOG_Trace, "LBSM ATTACHING%s", fallback ? " (fallback)" : ""); #endif /*LBSM_DEBUG*/ if ((which = s_Shmem_RLock(!fallback)) < 0) { CORE_LOG_ERRNO_X(10, eLOG_Warning, errno, "Cannot lock LBSM shmem to attach"); return 0; } #ifdef LBSM_DEBUG CORE_LOGF(eLOG_Trace, ("LBSM R-lock[%d] acquired", which + 1)); #endif /*LBSM_DEBUG*/ if (!(heap = s_Shmem_Attach(which))) { int/*bool*/ attached = s_Shmem[which] != 0 ? 1/*true*/ : 0/*false*/; s_Shmem_RUnlock(which); CORE_LOGF_ERRNO_X(11, eLOG_Error, errno, ("Cannot %s LBSM shmem[%d]", attached ? "access" : "attach", which + 1)); } #ifdef LBSM_DEBUG else { CORE_LOGF(eLOG_Trace, ("LBSM heap[%p, %p, %d] attached", heap, HEAP_Base(heap), which + 1)); assert(HEAP_Serial(heap) == which + 1); } #endif /*LBSM_DEBUG*/ if (s_Shmem[which = !which]) { #ifdef LBSM_DEBUG CORE_LOGF(eLOG_Trace, ("LBSM shmem[%d] detached", which + 1)); #endif /*LBSM_DEBUG*/ shmdt(s_Shmem[which]); s_Shmem[which] = 0; s_Shmid[which] = -1; } else assert(s_Shmid[which] < 0); s_ShmemSize[which] = 0; return heap; }
static int log_match_diffs(int idx_exp, int idx_got) { if (strcmp(s_hits_exp[idx_exp].type, s_hits_got[idx_got].type) != 0) { CORE_LOGF(eLOG_Note, ( " type: expected: %-20s got: %-20s", *s_hits_exp[idx_exp].type ? s_hits_exp[idx_exp].type : "(nothing)", *s_hits_got[idx_got].type ? s_hits_got[idx_got].type : "(nothing)")); } if (strcmp(s_hits_exp[idx_exp].host, s_hits_got[idx_got].host) != 0) { CORE_LOGF(eLOG_Note, ( " host: expected: %-20s got: %-20s", *s_hits_exp[idx_exp].host ? s_hits_exp[idx_exp].host : "(nothing)", *s_hits_got[idx_got].host ? s_hits_got[idx_got].host : "(nothing)")); } if (s_hits_exp[idx_exp].port != s_hits_got[idx_got].port) { CORE_LOGF(eLOG_Note, ( " port: expected: %-20hu got: %-20hu", s_hits_exp[idx_exp].port, s_hits_got[idx_got].port)); } if (strcmp(s_hits_exp[idx_exp].xtra, s_hits_got[idx_got].xtra) != 0) { CORE_LOGF(eLOG_Note, ( " xtra: expected: %-20s got: %-20s", *s_hits_exp[idx_exp].xtra ? s_hits_exp[idx_exp].xtra : "(nothing)", *s_hits_got[idx_got].xtra ? s_hits_got[idx_got].xtra : "(nothing)")); } if (strcmp(s_hits_exp[idx_exp].loc, s_hits_got[idx_got].loc) != 0) { CORE_LOGF(eLOG_Note, ( " loc: expected: %-20s got: %-20s", *s_hits_exp[idx_exp].loc ? s_hits_exp[idx_exp].loc : "(nothing)", *s_hits_got[idx_got].loc ? s_hits_got[idx_got].loc : "(nothing)")); } if (strcmp(s_hits_exp[idx_exp].priv, s_hits_got[idx_got].priv) != 0) { CORE_LOGF(eLOG_Note, ( " priv: expected: %-20s got: %-20s", *s_hits_exp[idx_exp].priv ? s_hits_exp[idx_exp].priv : "(nothing)", *s_hits_got[idx_got].priv ? s_hits_got[idx_got].priv : "(nothing)")); } if (strcmp(s_hits_exp[idx_exp].stfl, s_hits_got[idx_got].stfl) != 0) { CORE_LOGF(eLOG_Note, ( " stfl: expected: %-20s got: %-20s", *s_hits_exp[idx_exp].stfl ? s_hits_exp[idx_exp].stfl : "(nothing)", *s_hits_got[idx_got].stfl ? s_hits_got[idx_got].stfl : "(nothing)")); } return 1; }
static int/*bool*/ TEST_isip(const char* ip) { int retval = SOCK_isip(ip); CORE_LOG(eLOG_Note, "------------"); CORE_LOGF(eLOG_Note, ("SOCK_isip(\"%s\"): %s", ip, retval ? "True" : "False")); return retval; }
static int/*bool*/ s_Shmem_WUnlock(int which) { /* Decrement number of accessors [2]; should become 0 after that */ int retval1 = s_Shmem_Unlock(which, 2); /* Open read semaphore [1] */ int retval2 = s_Shmem_Unlock(which, 1); #ifdef LBSM_DEBUG CORE_LOGF(eLOG_Trace, ("LBSM W-lock[%d] release", which + 1)); #endif /*LBSM_DEBUG*/ return retval1 == 0 && retval2 == 0; }
static void TEST__server(unsigned short port) { LSOCK lsock; EIO_Status status; CORE_LOGF(eLOG_Note, ("TEST__server(port = %hu)", port)); /* Create listening socket */ status = LSOCK_CreateEx(port, N_RECONNECT * 10, &lsock, fSOCK_LogOn); assert(status == eIO_Success); /* Accept connections from clients and run test sessions */ for (;;) { char full[80]; char addr[80]; char port[10]; SOCK sock; status = LSOCK_Accept(lsock, NULL, &sock); assert(status == eIO_Success); assert(SOCK_GetPeerAddressString (sock, full,sizeof(full))); assert(SOCK_GetPeerAddressStringEx(sock, addr,sizeof(addr),eSAF_IP)); assert(SOCK_GetPeerAddressStringEx(sock, port,sizeof(port),eSAF_Port)); assert(strcmp(full, strcat(strcat(addr, ":"), port)) == 0); /* Test the simplest randezvous(plain request-reply) * The two peer functions are: * "TEST__[client|server]_1(SOCK sock)" */ TEST__server_1(sock); status = LSOCK_Accept(lsock, NULL, &sock); assert(status == eIO_Success); /* Test a more complex case * The two peer functions are: * "TEST__[client|server]_2(SOCK sock)" */ #ifdef DO_RECONNECT TEST__server_2(sock, lsock); #else TEST__server_2(sock, 0); #endif #ifdef TEST_SRV1_ONCE /* Close listening socket */ assert(LSOCK_Close(lsock) == eIO_Success); /* Finish after the first session */ break; #endif } /* for */ }
static void s_Close(SERV_ITER iter) { if (iter->data) { #ifdef LBSM_DEBUG CORE_LOGF(eLOG_Trace, ("LBSM heap[%p, %p, %d] for \"%s\" deleted", iter->data, HEAP_Base((HEAP) iter->data), HEAP_Serial((HEAP) iter->data), iter->name)); #endif /*LBSM_DEBUG*/ CORE_LOCK_WRITE; HEAP_Detach((HEAP) iter->data); CORE_UNLOCK; iter->data = 0; } if (!s_FastHeapAccess) LBSM_UnLBSMD(-1); }
static void s_Fini(void) { if (s_Heap) { CORE_LOCK_WRITE; if (s_Heap) { #ifdef LBSM_DEBUG CORE_LOGF(eLOG_Trace, ("Cached LBSM heap[%p, %p, %d] destroyed", s_Heap, HEAP_Base(s_Heap), HEAP_Serial(s_Heap))); #endif /*LBSM_DEBUG*/ HEAP_Destroy(s_Heap); s_Heap = 0; } CORE_UNLOCK; } LBSM_UnLBSMD(-1); }
static int/*tri-state-bool, inverted*/ s_Shmem_TryWLock(int which) { int semnum = (which << 1) | 1; int/*bool*/ no_undo = 0; struct sembuf rwlock[2]; int i = 0; for (;;) { rwlock[0].sem_num = semnum; rwlock[0].sem_op = 0; /* precondition: [1] == 0 */ rwlock[0].sem_flg = 0; rwlock[1].sem_num = semnum; rwlock[1].sem_op = 1; /* postcondition: [1] == 1 */ rwlock[1].sem_flg = no_undo ? 0 : SEM_UNDO; if (semop(s_Muxid, rwlock, sizeof(rwlock)/sizeof(rwlock[0])) >= 0) { /* No new read accesses are allowed after this point */ s_NoUndo[semnum - 1] = no_undo; /* Look at [2] first, then continue with it */ if (s_Shmem_Lock(which, 2, 0/*wait*/) != 0) return 1/*partially locked*/; return 0/*okay*/; } if (i) break; i = errno; if (i == ENOSPC) { CORE_LOGF_X(8, eLOG_Warning, ("LBSM PreW-locking[%d] w/o undo", which + 1)); no_undo = 1; continue; } if (i == EINTR) continue; if (i != ENOMEM) break; #ifdef LBSM_DEBUG CORE_LOGF(eLOG_Trace, ("LBSM PreW-lock[%d] wait(ENOMEM)", which + 1)); #endif/*LBSM_DEBUG*/ sleep(1); } return -1/*not locked*/; }
/* For 'which' block: check specified [sem] first, then continue with [2]++ */ static int/*syscall*/ s_Shmem_Lock(int which, int sem, int no_wait) { int semnum = (which << 1) + sem; int accsem = (which << 1) + 2; int/*bool*/ no_undo = 0; struct sembuf lock[2]; int i = 0; for (;;) { lock[0].sem_num = semnum; lock[0].sem_op = 0; /* precondition: [sem] == 0 */ lock[0].sem_flg = no_wait ? IPC_NOWAIT : 0; lock[1].sem_num = accsem; lock[1].sem_op = 1; /* postcondition: [2]++ */ lock[1].sem_flg = no_undo ? 0 : SEM_UNDO; if (semop(s_Muxid, lock, sizeof(lock)/sizeof(lock[0])) >= 0) { s_NoUndo[accsem - 1] = no_undo; return 0; } if (i) break; i = errno; if (i == ENOSPC) { CORE_LOGF_X(7, eLOG_Warning, ("LBSM %c-locking[%d] w/o undo", "RW"[sem > 1], which + 1)); no_undo = 1; continue; } if (i == EINTR) continue; if (no_wait || i != ENOMEM) break; #ifdef LBSM_DEBUG CORE_LOGF(eLOG_Trace, ("LBSM %c-locking[%d] wait(ENOMEM)", "RW"[sem > 1], which + 1)); #endif /*LBSM_DEBUG*/ sleep(1); } return -1; }
void LBSM_Shmem_Detach(HEAP heap) { int which; if (!heap) return; which = HEAP_Serial(heap); #ifdef LBSM_DEBUG CORE_LOGF(eLOG_Trace, ("LBSM shmem[%d] detaching", which)); #endif /*LBSM_DEBUG*/ if (which != 1 && which != 2) { CORE_LOGF_X(12, eLOG_Error, ("Bad block number (%d) for LBSM shmem to unlock", which)); } else s_Shmem_RUnlock(which - 1); HEAP_Detach(heap); #ifdef LBSM_DEBUG CORE_LOG(eLOG_Trace, "LBSM DETACHED"); #endif /*LBSM_DEBUG*/ }
/* Skeletons for the socket i/o test: * TEST__client(...) * TEST__server(...) * establish and close connection; call test i/o functions like * TEST__[client|server]_[1|2|...] (...) */ static void TEST__client(const char* server_host, unsigned short server_port, const STimeout* timeout) { SOCK sock; EIO_Status status; char tmo[80]; if ( timeout ) sprintf(tmo, "%u.%06u", timeout->sec, timeout->usec); else strcpy(tmo, "INFINITE"); CORE_LOGF(eLOG_Note, ("TEST__client(host = \"%s\", port = %hu, timeout = %s", server_host, server_port, tmo)); /* Connect to server */ status = SOCK_Create(server_host, server_port, timeout, &sock); assert(status == eIO_Success); verify(SOCK_SetTimeout(sock, eIO_ReadWrite, timeout) == eIO_Success); verify(SOCK_SetTimeout(sock, eIO_Close, timeout) == eIO_Success); /* Test the simplest randezvous(plain request-reply) * The two peer functions are: * "TEST__[client|server]_1(SOCK sock)" */ TEST__client_1(sock); /* Test a more complex case * The two peer functions are: * "TEST__[client|server]_2(SOCK sock)" */ TEST__client_2(sock); /* Close connection and exit */ status = SOCK_Close(sock); assert(status == eIO_Success || status == eIO_Closed); CORE_LOG(eLOG_Note, "TEST completed successfully"); }
/* Daemon use: undaemon > 0; Client use: undaemon == 0 => return LBSMD PID * undaemon < 0 => fast return */ pid_t LBSM_UnLBSMD(int/*bool*/ undaemon) { static union semun dummy; pid_t pid = 0; int which; if (s_Muxid >= 0) { if (undaemon <= 0) { if (!undaemon) { if ((which = s_Shmem_RLock(1)) >= 0) { int shmid = shmget(k_ShmemKey[which], 0, 0); struct shmid_ds shm_ds; if (shmid > 0 && shmctl(shmid, IPC_STAT, &shm_ds) == 0) pid = shm_ds.shm_cpid; s_Shmem_RUnlock(which); } } CORE_LOCK_WRITE; for (which = 0; which < 2; which++) { if (s_Shmem[which]) { #ifdef LBSM_DEBUG CORE_LOGF(eLOG_Trace, ("LBSM shmem[%d] detached",which+1)); #endif /*LBSM_DEBUG*/ shmdt(s_Shmem[which]); s_Shmem[which] = 0; s_Shmid[which] = -1; } else assert(s_Shmid[which] < 0); s_ShmemSize[which] = 0; } CORE_UNLOCK; } else { semctl(s_Muxid, 0, IPC_RMID, dummy); s_Muxid = -1; } } return pid; }
static void TEST__server_2(SOCK sock, LSOCK lsock) { EIO_Status status; size_t n_io, n_io_done; char buf[TEST_BUFSIZE]; STimeout r_to, w_to, rc_to; size_t i; CORE_LOG(eLOG_Note, "TEST__server_2(TS2)"); r_to.sec = 0; r_to.usec = 0; w_to = r_to; rc_to.sec = 30; rc_to.usec = 123456; /* goto */ l_reconnect: /* reconnection loopback */ SOCK_SetDataLogging(sock, eOn); status = SOCK_SetTimeout(sock, eIO_Read, &r_to); assert(status == eIO_Success); status = SOCK_SetTimeout(sock, eIO_Write, &w_to); assert(status == eIO_Success); for (i = 0; ; i++) { char* x_buf; /* read data from socket */ n_io = sizeof(buf); status = SOCK_Read(sock, buf, n_io, &n_io_done, eIO_ReadPlain); switch ( status ) { case eIO_Success: CORE_LOGF(eLOG_Note, ("TS2::read:" " [%lu], status=%7s, n_io=%5lu, n_io_done=%5lu", (unsigned long)i, IO_StatusStr(status), (unsigned long)n_io, (unsigned long)n_io_done)); assert(n_io_done > 0); break; case eIO_Closed: CORE_LOG(eLOG_Note, "TS2::read: connection closed"); assert(SOCK_Status(sock, eIO_Read) == eIO_Closed); /* close connection */ status = SOCK_Close(sock); assert(status == eIO_Success || status == eIO_Closed); /* reconnect */ if ( !lsock ) return; CORE_LOG(eLOG_Note, "TS2::reconnect"); if ((status = LSOCK_Accept(lsock, &rc_to, &sock)) != eIO_Success) return; assert(SOCK_Status(sock, eIO_Read) == eIO_Success); /* !!! */ goto l_reconnect; case eIO_Timeout: CORE_LOGF(eLOG_Note, ("TS2::read:" " [%lu] timeout expired: %5u sec, %6u usec", (unsigned long)i, r_to.sec, r_to.usec)); assert(n_io_done == 0); s_DoubleTimeout(&r_to); status = SOCK_SetTimeout(sock, eIO_Read, &r_to); assert(status == eIO_Success); assert(SOCK_Status(sock, eIO_Read) == eIO_Timeout); break; default: CORE_LOGF(eLOG_Fatal, ("TS2::read: status = %d", (int) status)); } /* switch */ /* write(just the same) data back to client */ n_io = n_io_done; x_buf = buf; while ( n_io ) { status = SOCK_Write(sock, buf, n_io, &n_io_done, eIO_WritePersist); switch ( status ) { case eIO_Success: CORE_LOGF(eLOG_Note, ("TS2::write:" " [%lu], status=%7s, n_io=%5lu, n_io_done=%5lu", (unsigned long)i, IO_StatusStr(status), (unsigned long)n_io, (unsigned long)n_io_done)); assert(n_io_done > 0); break; case eIO_Closed: CORE_LOG(eLOG_Fatal, "TS2::write: connection closed"); return; case eIO_Timeout: CORE_LOGF(eLOG_Note, ("TS2::write:" " [%lu] timeout expired: %5u sec, %6u usec", (unsigned long)i, w_to.sec, w_to.usec)); assert(n_io_done == 0); s_DoubleTimeout(&w_to); status = SOCK_SetTimeout(sock, eIO_Write, &w_to); assert(status == eIO_Success); break; default: CORE_LOGF(eLOG_Fatal, ("TS2::write: status = %d", (int) status)); } /* switch */ n_io -= n_io_done; x_buf += n_io_done; } } }
int main(int argc, char** argv) { /* Prepare to connect: parse and check cmd.-line args, etc. */ const char* host = argc > 1 ? argv[1] : ""; unsigned short port = argc > 2 ? atoi(argv[2]) : CONN_PORT_HTTP; const char* path = argc > 3 ? argv[3] : ""; const char* args = argc > 4 ? argv[4] : ""; const char* inp_file = argc > 5 ? argv[5] : ""; const char* user_header = argc > 6 ? argv[6] : ""; size_t content_length; STimeout timeout; SOCK sock; EIO_Status status; char buffer[10000]; CORE_SetLOGFormatFlags(fLOG_None | fLOG_Level | fLOG_OmitNoteLevel | fLOG_DateTime); CORE_SetLOGFILE(stderr, 0/*false*/); SOCK_SetupSSL(NcbiSetupTls); fprintf(stderr, "Running...\n" " Executable: '%s'\n" " URL host: '%s'\n" " URL port: %hu\n" " URL path: '%s'\n" " URL args: '%s'\n" " Input data file: '%s'\n" " User header: '%s'\n" "Response(if any) from the hit URL goes to standard output.\n\n", argv[0], host, port, path, args, inp_file, user_header); if ( argc < 4 ) { fprintf(stderr, "Usage: %s host port path args inp_file [user_header]\n", argv[0]); CORE_LOG(eLOG_Fatal, "Two few arguments"); return 1; } {{ FILE *fp = fopen(inp_file, "rb"); long offset; if ( !fp ) { CORE_LOGF(eLOG_Fatal, ("Non-existent file '%s'", inp_file)); return 2; } if ( fseek(fp, 0, SEEK_END) != 0 || (offset = ftell(fp)) < 0 ) { CORE_LOGF(eLOG_Fatal, ("Cannot obtain size of file '%s'", inp_file)); return 2; } fclose(fp); content_length = (size_t) offset; }} timeout.sec = 10; timeout.usec = 0; /* Connect */ sock = URL_Connect(host, port, path, args, /*NCBI_FAKE_WARNING*/ eReqMethod_Any, content_length, &timeout, &timeout, user_header, 1/*true*/, port == CONN_PORT_HTTPS ? fSOCK_LogDefault | fSOCK_Secure : fSOCK_LogDefault); if ( !sock ) return 3; {{ /* Pump data from the input file to socket */ FILE* fp = fopen(inp_file, "rb"); if ( !fp ) { CORE_LOGF(eLOG_Fatal, ("Cannot open file '%s' for reading", inp_file)); return 4; } for (;;) { size_t n_written; size_t n_read = fread(buffer, 1, sizeof(buffer), fp); if ( n_read <= 0 ) { if ( content_length ) { CORE_LOGF(eLOG_Fatal, ("Cannot read last %lu bytes from file '%s'", (unsigned long) content_length, inp_file)); return 5; } break; } assert(content_length >= n_read); content_length -= n_read; status = SOCK_Write(sock, buffer, n_read, &n_written, eIO_WritePersist); if ( status != eIO_Success ) { CORE_LOGF(eLOG_Fatal, ("Error writing to socket: %s", IO_StatusStr(status))); return 6; } } fclose(fp); }} /* Read reply from socket, write it to STDOUT */ {{ size_t n_read; for (;;) { status = SOCK_Read(sock, buffer, sizeof(buffer), &n_read, eIO_ReadPlain); if (status != eIO_Success) break; fwrite(buffer, 1, n_read, stdout); } if ( status != eIO_Closed ) { CORE_LOGF(eLOG_Error, ("Read error after %ld byte(s) from socket: %s", (long) content_length, IO_StatusStr(status))); } fprintf(stdout, "\n"); }} /* Success: close the socket, cleanup, and exit */ SOCK_Close(sock); CORE_LOG(eLOG_Note, "TEST completed successfully"); CORE_SetLOG(0); return 0; }
int main(int argc, const char *argv[]) { const char *retmsg = ""; const char *svc = ""; const char *test_nums = ""; int retval = 1; int live = 0; int i; for (i=1; i < argc; ++i) { if (strcmp(argv[i], "-f") == 0 && i < argc-1) { ++i; s_json_file = argv[i]; } else if (strcmp(argv[i], "-l") == 0) { live = 1; } else if (strcmp(argv[i], "-n") == 0 && i < argc-1) { ++i; test_nums = argv[i]; retmsg = "Not all tests run."; } else if (strcmp(argv[i], "-s") == 0 && i < argc-1) { ++i; svc = argv[i]; retmsg = "Run for a given service instead of standard tests."; } else if (strcmp(argv[i], "-u") == 0 && i < argc-1) { ++i; s_user_header = argv[i]; retmsg = "User header overridden."; } else { fprintf(stderr, "USAGE: %s [OPTIONS...]\n", argv[0]); fprintf(stderr, " [-h] help\n" " [-f ARG] test file\n" " [-l] live test data (default is mock data)\n" " [-n ARG] comma-separated test selections (eg 1,2,5)\n" " [-s ARG] service\n" " [-u ARG] user header\n"); goto out; } } CORE_SetLOGFormatFlags(fLOG_None | fLOG_Level | fLOG_OmitNoteLevel); CORE_SetLOGFILE(stderr, 0/*false*/); if (*svc) { test_service(live, svc); } else { if ( ! run_tests(live, test_nums) && ! *retmsg) retmsg = "Not all tests passed."; } out: CORE_LOG(eLOG_Note, ""); if (strcmp(retmsg, "") == 0) { /* The only successful condition is a run of all tests. */ CORE_LOG(eLOG_Note, "SUCCESS - All tests passed."); retval = 0; } else { CORE_LOGF(eLOG_Note, ("FAIL - %s", retmsg)); } CORE_SetLOG(0); return retval; }
/* mostly error-handling-free for the moment :-/ */ static int run_tests(int live, const char *test_nums) { x_JSON_Value *root_value = NULL; x_JSON_Object *root_obj; x_JSON_Array *test_arr; const char *test_num = test_nums; size_t n_tests = 0, n_pass = 0, n_fail = 0, n_skip = 0; size_t n_comm_unset, n_comm_set; int all_enabled = 0; CORE_LOG(eLOG_Note, "============================================================"); CORE_LOGF(eLOG_Note, ("Test file: %s", s_json_file)); root_value = x_json_parse_file(s_json_file); root_obj = x_json_value_get_object(root_value); if (x_json_object_has_value_of_type(root_obj, "all_enabled", JSONNumber) && (int)x_json_object_get_number(root_obj, "all_enabled") != 0) { all_enabled = 1; } test_arr = x_json_object_get_array(root_obj, "tests"); n_tests = x_json_array_get_count(test_arr); assert(n_tests == x_json_array_get_count(test_arr)); size_t it; for (it = 0; it < n_tests; ++it) { x_JSON_Object *test_obj; x_JSON_Array *hit_arr; const char *svc, *hdr; int err = 0; test_obj = x_json_array_get_object(test_arr, it); s_results[it].name = x_json_object_get_string(test_obj, "alias"); /* Skip tests not in user-supplied test numbers list. */ if (test_nums && *test_nums) { size_t next_test; if ( ! test_num) break; if (sscanf(test_num, FMT_SIZE_T, &next_test) == 1) { if (it+1 != next_test) { s_results[it].result = "-"; continue; } else { test_num = strchr(test_num, ','); if (test_num && *test_num) test_num++; } } else { CORE_LOGF(eLOG_Error, ("Invalid test numbers list: %s", test_num)); return 0; } } CORE_LOG(eLOG_Note, "============================================================"); /* Skip disabled tests. */ if ( ! all_enabled) { if (x_json_object_has_value_of_type(test_obj, "disabled", JSONNumber)) { if ((int)x_json_object_get_number(test_obj, "disabled") == 1) { ++n_skip; CORE_LOGF(eLOG_Note, ("Skipping test " FMT_SIZE_T ": %s", it+1, x_json_object_get_string(test_obj, "alias"))); s_results[it].result = "skip"; continue; } } } CORE_LOGF(eLOG_Note, ("Running test " FMT_SIZE_T ": %s", it+1, s_results[it].name)); svc = x_json_object_get_string(test_obj, "service"); if (x_json_object_has_value_of_type(test_obj, "http_user_header", JSONString)) hdr = x_json_object_get_string(test_obj, "http_user_header"); else hdr = ""; if (x_json_object_has_value_of_type(test_obj, "expect_error", JSONString)) { if (strcmp(x_json_object_get_string(test_obj, "expect_error"), "yes") == 0) { err = 1; } } if (x_json_object_has_value_of_type(test_obj, "url", JSONString)) CORE_LOGF(eLOG_Note, (" url: %s", x_json_object_get_string(test_obj, "url"))); CORE_LOGF(eLOG_Note, (" service: %s", svc)); CORE_LOGF(eLOG_Note, (" header: %s", *hdr ? hdr : "(none)")); CORE_LOGF(eLOG_Note, (" expected error: %s", err ? "yes" : "no")); /* Redo common unset/set - they could have been changed by a prior test. */ if (x_json_object_dothas_value_of_type(root_obj, "common.env_unset", JSONArray)) { x_JSON_Array *comm_unset_arr; comm_unset_arr = x_json_object_dotget_array(root_obj, "common.env_unset"); n_comm_unset = x_json_array_get_count(comm_unset_arr); for (size_t it2 = 0; it2 < n_comm_unset; ++it2) { const char *name = x_json_array_get_string( comm_unset_arr, it2); CORE_LOGF(eLOG_Note, (" Unsetting common var: %s", name)); unsetenv(name); assert(getenv(name) == NULL); } } if (x_json_object_dothas_value_of_type(root_obj, "common.env_set", JSONArray)) { x_JSON_Array *comm_set_arr; comm_set_arr = x_json_object_dotget_array(root_obj, "common.env_set"); n_comm_set = x_json_array_get_count(comm_set_arr); for (size_t it2 = 0; it2 < n_comm_set; ++it2) { x_JSON_Object *env_obj = x_json_array_get_object(comm_set_arr, it2); const char *name = x_json_object_get_name(env_obj, 0); const char *val = x_json_value_get_string( x_json_object_get_value_at(env_obj, 0)); CORE_LOGF(eLOG_Note, (" Setting common var: %s=%s", name, val)); setenv(name, val, 1); assert(strcmp(val, getenv(name)) == 0); } } /* Per-test unset/set */ if (x_json_object_has_value_of_type(test_obj, "env_unset", JSONArray)) { x_JSON_Array *unset_arr; size_t n_unset; unset_arr = x_json_object_get_array(test_obj, "env_unset"); n_unset = x_json_array_get_count(unset_arr); CORE_LOGF(eLOG_Note, ( " Unset per-test environment variables: " FMT_SIZE_T, n_unset)); if (n_unset) { for (size_t it2 = 0; it2 < n_unset; ++it2) { const char *name = x_json_array_get_string(unset_arr, it2); CORE_LOGF(eLOG_Note, (" %s", name)); unsetenv(name); assert(getenv(name) == NULL); } } } if (x_json_object_has_value_of_type(test_obj, "env_set", JSONArray)) { x_JSON_Array *set_arr; size_t n_set; set_arr = x_json_object_get_array(test_obj, "env_set"); n_set = x_json_array_get_count(set_arr); CORE_LOGF(eLOG_Note, ( " Set per-test environment variables: " FMT_SIZE_T, n_set)); if (n_set) { for (size_t it2 = 0; it2 < n_set; ++it2) { x_JSON_Object *env_obj = x_json_array_get_object(set_arr, it2); const char *name = x_json_object_get_name(env_obj, 0); const char *val = x_json_value_get_string( x_json_object_get_value_at(env_obj, 0)); CORE_LOGF(eLOG_Note, (" %s=%s", name, val)); setenv(name, val, 1); assert(strcmp(val, getenv(name)) == 0); } } } hit_arr = x_json_object_get_array(test_obj, "expect_hits"); s_n_hits_exp = (int)x_json_array_get_count(hit_arr); assert(s_n_hits_exp < MAX_HITS); CORE_LOGF(eLOG_Note, (" Expected hits: %d", s_n_hits_exp)); int it2; for (it2 = 0; it2 < s_n_hits_exp; ++it2) { x_JSON_Object *hit_obj = x_json_array_get_object(hit_arr, it2); const char *type = "HTTP", *loc = "no", *priv = "no"; const char *xtra = "", *stfl = "no"; unsigned short port = 0; if (x_json_object_has_value_of_type(hit_obj, "type", JSONString)) type = x_json_object_get_string(hit_obj, "type"); if (x_json_object_has_value_of_type(hit_obj, "xtra", JSONString)) xtra = x_json_object_get_string(hit_obj, "xtra"); if (x_json_object_has_value_of_type(hit_obj, "loc", JSONString)) loc = x_json_object_get_string(hit_obj, "loc" ); if (x_json_object_has_value_of_type(hit_obj, "priv", JSONString)) priv = x_json_object_get_string(hit_obj, "priv"); if (x_json_object_has_value_of_type(hit_obj, "stfl", JSONString)) stfl = x_json_object_get_string(hit_obj, "stfl"); assert(strlen(type) <= LEN_TYPE); assert(strlen(xtra) <= LEN_XTRA); assert(strlen(loc ) <= LEN_LOC ); assert(strlen(priv) <= LEN_PRIV); assert(strlen(stfl) <= LEN_STFL); strcpy(s_hits_exp[it2].type, type); strcpy(s_hits_exp[it2].xtra, xtra); strcpy(s_hits_exp[it2].loc , loc ); strcpy(s_hits_exp[it2].priv, priv); strcpy(s_hits_exp[it2].stfl, stfl); assert(x_json_object_has_value_of_type(hit_obj, "host", JSONString)); assert(strlen(x_json_object_get_string(hit_obj, "host")) <= LEN_HOST); strcpy(s_hits_exp[it2].host, x_json_object_get_string(hit_obj, "host")); assert(strcmp(s_hits_exp[it2].loc , "no" ) == 0 || strcmp(s_hits_exp[it2].loc , "yes") == 0); assert(strcmp(s_hits_exp[it2].priv, "no" ) == 0 || strcmp(s_hits_exp[it2].priv, "yes") == 0); assert(strcmp(s_hits_exp[it2].stfl, "no" ) == 0 || strcmp(s_hits_exp[it2].stfl, "yes") == 0); assert(x_json_object_has_value_of_type(hit_obj, "port", JSONNumber)); port = (unsigned short)x_json_object_get_number(hit_obj, "port"); assert(port > 0); s_hits_exp[it2].port = port; s_hits_exp[it2].match = 0; CORE_LOGF(eLOG_Note, ( " Expected server %d: %s %s:%hu L=%s P=%s S=%s %s", it2, s_hits_exp[it2].type, s_hits_exp[it2].host, s_hits_exp[it2].port, s_hits_exp[it2].loc, s_hits_exp[it2].priv, s_hits_exp[it2].stfl, s_hits_exp[it2].xtra)); } const char *mock_body = NULL; if (x_json_object_has_value_of_type(test_obj, "mock_body", JSONString)) { mock_body = x_json_object_get_string(test_obj, "mock_body"); if (mock_body && *mock_body) CORE_LOG(eLOG_Note, " Mock HTTP body found."); else CORE_LOG(eLOG_Note, " Empty mock HTTP body found."); } int repop = 0, reset = 0; if (x_json_object_has_value_of_type( test_obj, "iter-repop", JSONString) && strcmp(x_json_object_get_string( test_obj, "iter-repop"), "yes") == 0) { repop = 1; } if (x_json_object_has_value_of_type( test_obj, "iter-reset", JSONString) && strcmp(x_json_object_get_string( test_obj, "iter-reset"), "yes") == 0) { reset = 1; } /* Run the test */ if (run_a_test(it, live, svc, hdr, 1, err, mock_body, repop, reset)) { ++n_pass; s_results[it].result = "ok"; } else { ++n_fail; s_results[it].result = "FAIL"; } } CORE_LOG (eLOG_Note, "============================================================"); CORE_LOGF(eLOG_Note, (FMT_SIZE_T " tests: " FMT_SIZE_T " passed, " FMT_SIZE_T " failed, " FMT_SIZE_T " skipped", n_tests, n_pass, n_fail, n_skip)); CORE_LOG (eLOG_Note, "============================================================"); CORE_LOG (eLOG_Note, "Test Source Result Description"); CORE_LOG (eLOG_Note, "---- ------ ------ ----------------------------------------------"); for (it = 0; it < n_tests; ++it) { if ( ! s_results[it].result || ! *s_results[it].result || *s_results[it].result == '-') { continue; } char tests_buf[6]; if (it+1 > 9999) strcpy (tests_buf, "####"); else sprintf(tests_buf, FMT_SIZE_T, it+1); CORE_LOGF(eLOG_Note, ("%4s %6s %6s %s", tests_buf, s_results[it].live ? "live" : "mock", s_results[it].result, s_results[it].name)); } if (root_value) x_json_value_free(root_value); return (n_tests > 0 && n_pass == n_tests - n_skip) ? 1 : 0; }
int main(int argc, const char* argv[]) { const char* service = argc > 1 && *argv[1] ? argv[1] : "bounce"; static char obuf[8192 + 2]; SConnNetInfo* net_info; CONNECTOR connector; EIO_Status status; char ibuf[1024]; CONN conn; size_t n; setlocale(LC_ALL, ""); g_NCBI_ConnectRandomSeed = (int) time(0) ^ NCBI_CONNECT_SRAND_ADDEND; srand(g_NCBI_ConnectRandomSeed); CORE_SetLOGFormatFlags(fLOG_None | fLOG_Level | fLOG_OmitNoteLevel | fLOG_DateTime); CORE_SetLOGFILE(stderr, 0/*false*/); net_info = ConnNetInfo_Create(service); ConnNetInfo_AppendArg(net_info, "testarg", "val"); ConnNetInfo_AppendArg(net_info, "service", "none"); ConnNetInfo_AppendArg(net_info, "platform", "none"); ConnNetInfo_AppendArg(net_info, "address", "2010"); ConnNetInfo_Log(net_info, eLOG_Note, CORE_GetLOG()); connector = SERVICE_CreateConnectorEx(service, fSERV_Any, net_info, 0); if (!connector) CORE_LOG(eLOG_Fatal, "Failed to create service connector"); if (CONN_Create(connector, &conn) != eIO_Success) CORE_LOG(eLOG_Fatal, "Failed to create connection"); if (argc > 2) { strncpy0(obuf, argv[2], sizeof(obuf) - 2); obuf[n = strlen(obuf)] = '\n'; obuf[++n] = '\0'; if (CONN_Write(conn, obuf, strlen(obuf), &n, eIO_WritePersist) != eIO_Success) { CONN_Close(conn); CORE_LOG(eLOG_Fatal, "Cannot write to connection"); } assert(n == strlen(obuf)); } else { for (n = 0; n < 10; n++) { size_t m; for (m = 0; m < sizeof(obuf) - 2; m++) obuf[m] = "0123456789\n"[rand() % 11]; obuf[m++] = '\n'; obuf[m] = '\0'; if (CONN_Write(conn, obuf, strlen(obuf), &m, eIO_WritePersist) != eIO_Success) { if (!n) { CONN_Close(conn); CORE_LOG(eLOG_Fatal, "Cannot write to connection"); } else break; } assert(m == strlen(obuf)); } } for (;;) { if (CONN_Wait(conn, eIO_Read, net_info->timeout) != eIO_Success) { CONN_Close(conn); CORE_LOG(eLOG_Fatal, "Failed to wait for reading"); } status = CONN_Read(conn, ibuf, sizeof(ibuf), &n, eIO_ReadPersist); if (n) { char* descr = CONN_Description(conn); CORE_DATAF(eLOG_Note, ibuf, n, ("%lu bytes read from service (%s%s%s):", (unsigned long) n, CONN_GetType(conn), descr ? ", " : "", descr ? descr : "")); if (descr) free(descr); } if (status != eIO_Success) { if (status != eIO_Closed) CORE_LOGF(n ? eLOG_Error : eLOG_Fatal, ("Read error: %s", IO_StatusStr(status))); break; } } ConnNetInfo_Destroy(net_info); CONN_Close(conn); #if 0 CORE_LOG(eLOG_Note, "Trying ID1 service"); net_info = ConnNetInfo_Create(service); connector = SERVICE_CreateConnectorEx("ID1", fSERV_Any, net_info); ConnNetInfo_Destroy(net_info); if (!connector) CORE_LOG(eLOG_Fatal, "Service ID1 not available"); if (CONN_Create(connector, &conn) != eIO_Success) CORE_LOG(eLOG_Fatal, "Failed to create connection"); if (CONN_Write(conn, "\xA4\x80\x02\x01\x02\x00", 7, &n, eIO_WritePersist) != eIO_Success) { CONN_Close(conn); CORE_LOG(eLOG_Fatal, "Cannot write to service ID1"); } assert(n == 7); if (CONN_Read(conn, ibuf, sizeof(ibuf), &n, eIO_ReadPlain) != eIO_Success){ CONN_Close(conn); CORE_LOG(eLOG_Fatal, "Cannot read from service ID1"); } CORE_LOGF(eLOG_Note, ("%d bytes read from service ID1", n)); CONN_Close(conn); #endif CORE_LOG(eLOG_Note, "TEST completed successfully"); CORE_SetLOG(0); return 0/*okay*/; }
/* Main function * Parse command-line options, initialize and cleanup API internals; * run client or server test */ extern int main(int argc, const char* argv[]) { /* Setup log stream */ CORE_SetLOGFormatFlags(fLOG_None | fLOG_Level | fLOG_OmitNoteLevel | fLOG_DateTime); CORE_SetLOGFILE(stderr, 0/*false*/); /* Parse cmd.-line args and decide whether it's a client or a server */ switch ( argc ) { case 1: /*** Try to set various fake MT safety locks ***/ CORE_SetLOCK( MT_LOCK_Create(0, TEST_LockHandler, TEST_LockCleanup) ); CORE_SetLOCK(0); CORE_SetLOCK(0); CORE_SetLOCK( MT_LOCK_Create(&TEST_LockUserData, TEST_LockHandler, TEST_LockCleanup) ); SOCK_SetDataLoggingAPI(eOn); assert(SOCK_InitializeAPI() == eIO_Success); SOCK_SetDataLoggingAPI(eOff); {{ char local_host[64]; assert(SOCK_gethostname(local_host, sizeof(local_host)) == 0); CORE_LOGF(eLOG_Note, ("Running NCBISOCK test on host \"%s\"", local_host)); }} TEST_gethostby(); TEST_SOCK_isip(); assert(SOCK_ShutdownAPI() == eIO_Success); CORE_SetLOCK(0); break; case 2: { /*** SERVER ***/ TEST__server(argv[1]); assert(SOCK_ShutdownAPI() == eIO_Success); CORE_SetLOG(0); return 0; } case 3: case 4: { /*** CLIENT ***/ const char* host; unsigned short port; STimeout* tmo; STimeout x_tmo; /* host */ host = argv[1]; /* port */ if (sscanf(argv[2], "%hu", &port) != 1) break; /* timeout */ if (argc == 4) { double v; char* e = (char*) argv[3]; if (!*e || (v = NCBI_simple_atof(e, &e)) < 0.0 || errno || *e) break; x_tmo.sec = (unsigned int) v; x_tmo.usec = (unsigned int)((v - x_tmo.sec) * 1000000.0); tmo = &x_tmo; } else tmo = 0/*infinite*/; TEST__client(host, port, tmo); assert(SOCK_ShutdownAPI() == eIO_Success); CORE_SetLOG(0); return 0; } } /* switch */ /* USAGE */ fprintf(stderr, "\nClient/Server USAGE:\n" "Client: %s <host> <port> [timeout]\n" "Server: %s <port>\n\n", argv[0], argv[0]); CORE_SetLOG(0); return argc == 1 ? 0 : 1; }
int main(int argc, const char* argv[]) { SHEAP_Block* blk; int r, j, i, n; HEAP heap; char* c; /* CORE_SetLOGFormatFlags(fLOG_None | fLOG_Level | fLOG_OmitNoteLevel); */ CORE_SetLOGFILE(stderr, 0/*false*/); if (argc > 1) g_NCBI_ConnectRandomSeed = atoi(argv[1]); else g_NCBI_ConnectRandomSeed = (int) time(0) ^ NCBI_CONNECT_SRAND_ADDEND; CORE_LOGF(eLOG_Note, ("Using seed %d", g_NCBI_ConnectRandomSeed)); HEAP_Options(eOff/*slow*/, eOn/*newalk*/); srand(g_NCBI_ConnectRandomSeed); for (j = 1; j <= 3; j++) { CORE_LOGF(eLOG_Note, ("Creating heap %d", j)); if (!(heap = HEAP_Create(0, 0, 4096, s_Expand, 0))) CORE_LOG(eLOG_Error, "Cannot create heap"); for (n = 0; n < 1000 && (rand() & 0xFFFF) != 0x1234; n++) { r = rand() & 7; if (r == 1 || r == 3) { int/*bool*/ fast = rand() & 1; i = rand() & 0xFF; if (i) { CORE_LOGF(eLOG_Note, ("Allocating%s data size %d", fast ? " fast" : "", i)); blk = fast ? HEAP_AllocFast(heap, i) : HEAP_Alloc(heap, i); if (blk) { CORE_LOGF(eLOG_Note, ("Done @%u, size %u", HEAP_ADDR(blk, heap), blk->size)); } else CORE_LOG(eLOG_Error, "Allocation failed"); c = (char*) blk + sizeof(*blk); while (i--) *c++ = rand(); s_Walk(heap, 0); } else { assert(!(fast ? HEAP_AllocFast(heap, i) : HEAP_Alloc(heap, i))); } } else if (r == 2 || r == 4) { blk = 0; do { if (!(blk = HEAP_Walk(heap, blk))) break; } while (rand() & 7); if (blk && (short) blk->flag) { unsigned size = blk->size; unsigned data_size = size - sizeof(*blk); CORE_LOGF(eLOG_Note, ("Freeing @%u, size %u, data size %u", HEAP_ADDR(blk, heap), size, data_size)); assert(data_size); HEAP_Free(heap, blk); CORE_LOG(eLOG_Note, "Done"); s_Walk(heap, 0); } } else if (r == 5) { const SHEAP_Block* prev = 0; unsigned ok = 0; blk = 0; for (;;) { if (!(blk = HEAP_Walk(heap, blk))) break; if ((short) blk->flag && (rand() & 7)) { char buf[32]; unsigned size = blk->size; int/*bool*/ fast = rand() & 1; unsigned data_size = size - sizeof(*blk); if (!fast || !prev) *buf = '\0'; else sprintf(buf, ", prev @%u", HEAP_ADDR(prev, heap)); CORE_LOGF(eLOG_Note, ("Freeing%s%s @%u%s in walk," " size %u, data size %u", fast ? " fast" : "", ok ? " more" : "", HEAP_ADDR(blk,heap), buf, size, data_size)); assert(data_size); if (fast) HEAP_FreeFast(heap, blk, prev); else HEAP_Free(heap, blk); CORE_LOG(eLOG_Note, "Done"); s_Walk(heap, 0); ok = 1; if (prev && !((short) prev->flag)) continue; } prev = blk; } if (!ok) s_Walk(heap, "the"); else CORE_LOG(eLOG_Note, "Done with freeing while walking"); } else if (r == 6 || r == 7) { HEAP newheap; if (r == 6) { int/*bool*/ fast = rand() & 1; if (fast) { CORE_LOG(eLOG_Note, "Attaching heap fast"); newheap = HEAP_AttachFast(HEAP_Base(heap), HEAP_Size(heap), 0); } else { CORE_LOG(eLOG_Note, "Attaching heap"); newheap = HEAP_Attach(HEAP_Base(heap), 0); } } else { CORE_LOG(eLOG_Note, "Copying heap"); newheap = HEAP_Copy(heap, 0, 0); } if (!newheap) { CORE_LOGF(eLOG_Error, ("%s failed", r == 6 ? "Attach" : "Copy")); } else s_Walk(newheap, r == 6 ? "attached" : "copied"); HEAP_Detach(newheap); } else { TNCBI_Size size = HEAP_Size(heap); HEAP newheap; CORE_LOG(eLOG_Note, "Trimming heap"); newheap = HEAP_Trim(heap); CORE_LOGF(eLOG_Note, ("Heap %strimmed: %u -> %u", newheap ? "" : "NOT ", size, HEAP_Size(newheap))); if (newheap) { heap = newheap; s_Walk(heap, "trimmed"); } } } HEAP_Destroy(heap); CORE_LOGF(eLOG_Note, ("Heap %d done", j)); } CORE_LOG(eLOG_Note, "Test completed"); CORE_SetLOG(0); return 0; }
static void TEST__client_2(SOCK sock) { #define W_FIELD 10 #define N_FIELD 1000 #define N_REPEAT 10 #define N_RECONNECT 3 EIO_Status status; size_t n_io, n_io_done, i; char buf[W_FIELD * N_FIELD + 1]; CORE_LOGF(eLOG_Note, ("TEST__client_2(TC2) @:%hu", SOCK_GetLocalPort(sock, eNH_HostByteOrder))); /* fill out a buffer to send to server */ memset(buf, 0, sizeof(buf)); for (i = 0; i < N_FIELD; i++) { sprintf(buf + i * W_FIELD, "%10lu", (unsigned long)i); } /* send the buffer to server, then get it back */ for (i = 0; i < N_REPEAT; i++) { char buf1[sizeof(buf)]; STimeout w_to, r_to; int/*bool*/ w_timeout_on = (int)(i%2); /* if to start from */ int/*bool*/ r_timeout_on = (int)(i%2); /* zero or inf. timeout */ char* x_buf; /* set timeout */ w_to.sec = 0; w_to.usec = 0; status = SOCK_SetTimeout(sock, eIO_Write, w_timeout_on ? &w_to : 0); assert(status == eIO_Success); /* reconnect */ if ((i % N_RECONNECT) == 0) { size_t j = i / N_RECONNECT; do { SOCK_SetDataLogging(sock, eOn); status = SOCK_Reconnect(sock, 0, 0, 0); SOCK_SetDataLogging(sock, eDefault); CORE_LOGF(eLOG_Note, ("TC2::reconnect @:%hu: i=%lu, j=%lu, status=%s", SOCK_GetLocalPort(sock, eNH_HostByteOrder), (unsigned long) i, (unsigned long) j, IO_StatusStr(status))); assert(status == eIO_Success); assert(SOCK_Status(sock, eIO_Read) == eIO_Success); assert(SOCK_Status(sock, eIO_Write) == eIO_Success); /* give a break to let server reset the listening socket */ X_SLEEP(1); } while ( j-- ); } /* send */ x_buf = buf; n_io = sizeof(buf); do { X_SLEEP(1); status = SOCK_Write(sock, x_buf, n_io, &n_io_done, eIO_WritePersist); if (status == eIO_Closed) CORE_LOG(eLOG_Fatal, "TC2::write: connection closed"); CORE_LOGF(eLOG_Note, ("TC2::write:" " i=%d, status=%7s, n_io=%5lu, n_io_done=%5lu" " timeout(%d): %5u.%06us", (int) i, IO_StatusStr(status), (unsigned long) n_io, (unsigned long) n_io_done, (int) w_timeout_on, w_to.sec, w_to.usec)); if ( !w_timeout_on ) { assert(status == eIO_Success && n_io_done == n_io); } else { const STimeout* x_to; assert(status == eIO_Success || status == eIO_Timeout); x_to = SOCK_GetTimeout(sock, eIO_Write); assert(w_to.sec == x_to->sec && w_to.usec == x_to->usec); } n_io -= n_io_done; x_buf += n_io_done; if (status == eIO_Timeout) s_DoubleTimeout(&w_to); status = SOCK_SetTimeout(sock, eIO_Write, &w_to); assert(status == eIO_Success); w_timeout_on = 1/*true*/; } while ( n_io ); /* get back the just sent data */ r_to.sec = 0; r_to.usec = 0; status = SOCK_SetTimeout(sock, eIO_Read, r_timeout_on ? &r_to : 0); assert(status == eIO_Success); x_buf = buf1; n_io = sizeof(buf1); do { if (i%2 == 0) { /* peek a little piece twice and compare */ char xx_buf1[128], xx_buf2[128]; size_t xx_io_done1, xx_io_done2; if (SOCK_Read(sock, xx_buf1, sizeof(xx_buf1), &xx_io_done1, eIO_ReadPeek) == eIO_Success && SOCK_Read(sock, xx_buf2, xx_io_done1, &xx_io_done2, eIO_ReadPeek) == eIO_Success) { assert(xx_io_done1 >= xx_io_done2); assert(memcmp(xx_buf1, xx_buf2, xx_io_done2) == 0); } } status = SOCK_Read(sock, x_buf, n_io, &n_io_done, eIO_ReadPlain); if (status == eIO_Closed) { assert(SOCK_Status(sock, eIO_Read) == eIO_Closed); CORE_LOG(eLOG_Fatal, "TC2::read: connection closed"); } CORE_LOGF(eLOG_Note, ("TC2::read: " " i=%d, status=%7s, n_io=%5lu, n_io_done=%5lu" " timeout(%d): %5u.%06us", (int) i, IO_StatusStr(status), (unsigned long) n_io, (unsigned long) n_io_done, (int) r_timeout_on, r_to.sec, r_to.usec)); if ( !r_timeout_on ) { assert(status == eIO_Success && n_io_done > 0); } else { const STimeout* x_to; assert(status == eIO_Success || status == eIO_Timeout); x_to = SOCK_GetTimeout(sock, eIO_Read); assert(r_to.sec == x_to->sec && r_to.usec == x_to->usec); } n_io -= n_io_done; x_buf += n_io_done; if (status == eIO_Timeout) s_DoubleTimeout(&r_to); status = SOCK_SetTimeout(sock, eIO_Read, &r_to); assert(status == eIO_Success); r_timeout_on = 1/*true*/; } while ( n_io ); assert(memcmp(buf, buf1, sizeof(buf)) == 0); } }
int main(int argc, const char* argv[]) { const char custom_body[] = "Subject: Custom sized body\n" "\n" "Custom sized body\n" "0123456789\n"; /* these 11 chars to ignore */ const char* body[] = { "This is a simple test", "This is a test with\n.", 0, ".", "\n.\n", ".\n", "", "a\nb\nc\nd\n.", "a\r\n\rb\r\nc\r\nd\r\n.", ".\na" }; const char* subject[] = { 0, "CORE_SendMail Test", "", }; const char* to[] = { "lavr", "lavr@pavo", " \"Anton Lavrentiev\" <lavr@pavo> , lavr, <lavr> ", }; size_t i, j, k, n, m; const char* mx_host; SSendMailInfo info; const char* retval; STimeout mx_tmo; char* huge_body; short mx_port; char val[32]; FILE* fp; g_NCBI_ConnectRandomSeed = (int) time(0) ^ NCBI_CONNECT_SRAND_ADDEND; srand(g_NCBI_ConnectRandomSeed); CORE_SetLOGFormatFlags(fLOG_None | fLOG_Level | fLOG_OmitNoteLevel | fLOG_DateTime); CORE_SetLOGFILE(stderr, 0/*false*/); ConnNetInfo_GetValue(0, REG_CONN_DEBUG_PRINTOUT, val, sizeof(val), DEF_CONN_DEBUG_PRINTOUT); if (ConnNetInfo_Boolean(val) || (*val && (strcasecmp(val, "all") == 0 || strcasecmp(val, "some") == 0 || strcasecmp(val, "data") == 0))) { SOCK_SetDataLoggingAPI(eOn); } strcpy(val, "@"); SendMailInfo_InitEx(&info, val, eCORE_UsernameCurrent); CORE_LOGF(eLOG_Note, ("@ - <%s>", info.from)); strcpy(info.from, "user0"); SendMailInfo_InitEx(&info, info.from, eCORE_UsernameCurrent); CORE_LOGF(eLOG_Note, ("user0 - <%s>", info.from)); strcpy(info.from, "user1@"); SendMailInfo_InitEx(&info, info.from, eCORE_UsernameCurrent); CORE_LOGF(eLOG_Note, ("user1@ - <%s>", info.from)); strcpy(val, "@host2.net"); SendMailInfo_InitEx(&info, val, eCORE_UsernameLogin); CORE_LOGF(eLOG_Note, ("@host2.net - <%s>", info.from)); strcpy(val, "*****@*****.**"); SendMailInfo_InitEx(&info, val, eCORE_UsernameReal); CORE_LOGF(eLOG_Note, ("[email protected] - <%s>", info.from)); strcpy(info.from, "*****@*****.**"); SendMailInfo_InitEx(&info, info.from, eCORE_UsernameReal); CORE_LOGF(eLOG_Note, ("[email protected] - <%s>", info.from)); SendMailInfo_InitEx(&info, 0, eCORE_UsernameReal); CORE_LOGF(eLOG_Note, ("NULL - <%s>", info.from)); if ((huge_body = malloc(TEST_HUGE_BODY_SIZE)) != 0) { strcpy(huge_body, "user5@"); for (i = 0; i < TEST_HUGE_BODY_SIZE - 6; i++) huge_body[i + 6] = "abcdefghijklmnopqrstuvwxyz."[rand() % 27]; huge_body[TEST_HUGE_BODY_SIZE - 1] = '\0'; SendMailInfo_InitEx(&info, huge_body, eCORE_UsernameCurrent); CORE_LOGF(eLOG_Note, ("HUGE user5@host - <%s>", info.from)); SendMailInfo_InitEx(&info, huge_body + 5, eCORE_UsernameLogin); CORE_LOGF(eLOG_Note, ("HUGE @host - <%s>", info.from)); huge_body[4] = '6'; huge_body[5] = '_'; for (i = 6; i < sizeof(info.from) + 1; i++) { if (huge_body[i] == '.') huge_body[i] = '_'; } huge_body[sizeof(info.from) + 1] = '@'; SendMailInfo_InitEx(&info, huge_body, eCORE_UsernameReal); CORE_LOGF(eLOG_Note, ("HUGE user6 - <%s>", info.from)); huge_body[4] = '7'; huge_body[sizeof(info.from) - 10] = '@'; SendMailInfo_InitEx(&info, huge_body, eCORE_UsernameReal); CORE_LOGF(eLOG_Note, ("LONG user7 - <%s>", info.from)); memcpy(huge_body + sizeof(info.from) - 10, "user8", 5); huge_body[sizeof(info.from) << 1] = '\0'; SendMailInfo_InitEx(&info, huge_body + sizeof(info.from) - 10, eCORE_UsernameReal); CORE_LOGF(eLOG_Note, ("LONG user8 - <%s>", info.from)); SendMailInfo_InitEx(&info, huge_body + sizeof(info.from) + 1, eCORE_UsernameReal); CORE_LOGF(eLOG_Note, ("LONG @host - <%s>", info.from)); free(huge_body); } if (argc > 1) { CORE_LOG(eLOG_Note, "Special test requested"); if ((fp = fopen(argv[1], "rb")) != 0 && fseek(fp, 0, SEEK_END) == 0 && (m = ftell(fp)) != (size_t)(-1) && fseek(fp, 0, SEEK_SET) == 0 && (huge_body = (char*) malloc(m + 1)) != 0 && fread(huge_body, m, 1, fp) == 1) { huge_body[m] = '\0'; CORE_LOGF(eLOG_Note, ("Sending file (%lu bytes)", (unsigned long) m)); retval = CORE_SendMail("lavr", "File", huge_body); if (retval) { CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval)); } else { CORE_LOG(eLOG_Note, "Test passed"); } } else CORE_LOG_ERRNO(eLOG_Error, errno, "Test failed"); return 0; } #if 1 CORE_LOG(eLOG_Note, "Phase 1 of 2: Testing CORE_SendMail"); n = (sizeof(to)/sizeof(to[0]))* (sizeof(subject)/sizeof(subject[0]))* (sizeof(body)/sizeof(body[0])); m = 0; for (i = 0; i < sizeof(to)/sizeof(to[0]); i++) { for (j = 0; j < sizeof(subject)/sizeof(subject[0]); j++) for (k = 0; k < sizeof(body)/sizeof(body[0]); k++) { CORE_LOGF(eLOG_Note, ("Test %u of %u", (unsigned)(++m), (unsigned)n)); retval = CORE_SendMail(to[i], subject[j], body[k]); if (retval != 0) CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval)); } } #else CORE_LOG(eLOG_Note, "Phase 1 of 2: Skipping CORE_SendMail tests"); #endif CORE_LOG(eLOG_Note, "Phase 2 of 2: Testing CORE_SendMailEx"); SendMailInfo_Init(&info); mx_host = info.mx_host; mx_port = info.mx_port; mx_tmo = info.mx_timeout; info.mx_host = "localhost"; CORE_LOG(eLOG_Note, "Testing bad port"); info.mx_port = 10/*BAD*/; retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "Bad port", &info); if (!retval) CORE_LOG(eLOG_Fatal, "Test failed"); CORE_LOGF(eLOG_Note, ("Test passed: %s", retval)); CORE_LOG(eLOG_Note, "Testing bad protocol"); info.mx_port = CONN_PORT_FTP; retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "Protocol", &info); if (!retval) CORE_LOG(eLOG_Fatal, "Test failed"); CORE_LOGF(eLOG_Note, ("Test passed: %s", retval)); CORE_LOG(eLOG_Note, "Testing timeout"); info.mx_host = "www.ncbi.nlm.nih.gov"; info.mx_timeout.sec = 5; info.mx_port = CONN_PORT_HTTP; retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "Timeout", &info); if (!retval) CORE_LOG(eLOG_Error, "Test failed"); else CORE_LOGF(eLOG_Note, ("Test passed: %s", retval)); info.mx_port = mx_port; info.mx_timeout = mx_tmo; CORE_LOG(eLOG_Note, "Testing bad host"); info.mx_host = "abrakadabra"; retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "Bad host", &info); if (!retval) CORE_LOG(eLOG_Fatal, "Test failed"); CORE_LOGF(eLOG_Note, ("Test passed: %s", retval)); info.mx_host = "localhost"; CORE_LOG(eLOG_Note, "Testing cc"); info.cc = "vakatov"; retval = CORE_SendMailEx("", "CORE_SendMailEx", "CC", &info); if (retval) CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval)); CORE_LOG(eLOG_Note, "Test passed"); CORE_LOG(eLOG_Note, "Testing bcc"); info.cc = 0; info.bcc = "vakatov"; retval = CORE_SendMailEx(0, "CORE_SendMailEx", "Bcc", &info); if (retval) CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval)); CORE_LOG(eLOG_Note, "Test passed"); CORE_LOG(eLOG_Note, "Testing huge body"); info.cc = 0; info.bcc = 0; if (!(huge_body = (char*) malloc(TEST_HUGE_BODY_SIZE))) CORE_LOG(eLOG_Fatal, "Test failed: Cannot allocate memory"); for (i = 0; i < TEST_HUGE_BODY_SIZE - 1; i++) huge_body[i] = "0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZ ."[rand() % 39]; huge_body[i] = 0; retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", huge_body, &info); if (retval) CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval)); if (!(fp = fopen("test_ncbi_sendmail.out", "w")) || fwrite(huge_body, TEST_HUGE_BODY_SIZE - 1, 1, fp) != 1) { CORE_LOG(eLOG_Error, "Test failed: Cannot store huge body to file"); } else { fclose(fp); CORE_LOG(eLOG_Note, "Success: Check test_ncbi_sendmail.out"); } free(huge_body); CORE_LOG(eLOG_Note, "Testing custom headers"); info.header = "Organization: NCBI/NLM/NIH\nReference: abcdefghijk"; retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "Custom header",&info); if (retval) CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval)); CORE_LOG(eLOG_Note, "Test passed"); CORE_LOG(eLOG_Note, "Testing no recipients"); retval = CORE_SendMailEx(0, "CORE_SendMailEx", "No recipients", &info); if (!retval) CORE_LOG(eLOG_Fatal, "Test failed"); CORE_LOGF(eLOG_Note, ("Test passed: %s", retval)); CORE_LOG(eLOG_Note, "Testing AS-IS message"); info.mx_options = fSendMail_NoMxHeader; retval = CORE_SendMailEx("lavr", "BAD SUBJECT SHOULD NOT APPEAR BUT IGNORED", "From: yourself\n" "To: yourself\n" "Subject: AS-IS message\n" "\n" "AS-IS", &info); if (retval) CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval)); CORE_LOG(eLOG_Note, "Test passed"); CORE_LOG(eLOG_Note, "Testing AS-IS custom sized message"); info.body_size = strlen(custom_body) - 11/*to ignore*/; retval = CORE_SendMailEx("<lavr@pavo>", "BAD SUBJECT SHOULD NOT APPEAR BUT IGNORED", custom_body, &info); if (retval) CORE_LOGF(eLOG_Fatal, ("Test failed: %s", retval)); CORE_LOG(eLOG_Note, "Test passed"); info.body_size = 0; info.mx_options = 0; info.mx_host = mx_host; CORE_LOG(eLOG_Note, "Testing bad from"); strcpy(info.from, "blahblah@blahblah"); retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "Bad from",&info); if (!retval) CORE_LOG(eLOG_Error, "Test failed"); else CORE_LOGF(eLOG_Note, ("Test passed: %s", retval)); SendMailInfo_Init(&info); CORE_LOG(eLOG_Note, "Testing drop no FQDN option"); info.mx_options |= fSendMail_StripNonFQDNHost; retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "No FQDN", &info); if (retval) CORE_LOGF(eLOG_Error, ("Test failed: %s", retval)); else CORE_LOG(eLOG_Note, "Test passed"); CORE_LOG(eLOG_Note, "Testing bad magic"); info.magic_cookie = 0; retval = CORE_SendMailEx("lavr", "CORE_SendMailEx", "Bad Magic", &info); if (!retval) CORE_LOG(eLOG_Fatal, "Test failed"); CORE_LOGF(eLOG_Note, ("Test passed: %s", retval)); CORE_LOG(eLOG_Note, "TEST completed successfully"); CORE_SetLOG(0); return 0; }
static int run_a_test(size_t test_idx, int live, const char *svc, const char *hdr, int check_for_match, int exp_err, const char *mock_body_in, int repop, int reset) { const SSERV_Info *info = NULL; SConnNetInfo *net_info; SERV_ITER iter; const char *mock_body = NULL; char *mock_body_adj = NULL; int n_matches_perfect = 0, n_matches_near = 0; int success = 0, errors = 0; int retval = -1; s_n_hits_got = 0; /* Adjust mock data for current time, if necessary. */ adjust_mock_times(mock_body_in, &mock_body_adj); mock_body = mock_body_adj ? mock_body_adj : mock_body_in; /* Select the HTTP data source (live or mock). */ s_results[test_idx].live = live; if ( ! s_results[test_idx].live && ( ! mock_body || ! *mock_body)) { CORE_TRACE("Mock HTTP data source unavailable."); s_results[test_idx].live = 1; } if (s_results[test_idx].live) { CORE_TRACE("Using a live HTTP data source."); SERV_NAMERD_SetConnectorSource(NULL); /* use live HTTP */ } else { CORE_TRACE("Using a mock HTTP data source."); if ( ! SERV_NAMERD_SetConnectorSource(mock_body)) { CORE_LOG(eLOG_Error, "Unable to create mock HTTP data source."); retval = 1; goto out; } } /* Set up the server iterator. */ net_info = ConnNetInfo_Create(svc); if (*hdr) ConnNetInfo_SetUserHeader(net_info, hdr); iter = SERV_OpenP(svc, fSERV_All | (strpbrk(svc, "?*") ? fSERV_Promiscuous : 0), SERV_LOCALHOST, 0/*port*/, 0.0/*preference*/, net_info, 0/*skip*/, 0/*n_skip*/, 0/*external*/, 0/*arg*/, 0/*val*/); ConnNetInfo_Destroy(net_info); /* Fetch the server hits from namerd. */ if (iter) { for (; s_n_hits_got < MAX_HITS && (info = SERV_GetNextInfo(iter)); ++s_n_hits_got) { if (info->type & fSERV_Http) { CORE_LOGF(eLOG_Note, (" HTTP extra (path): %s", SERV_HTTP_PATH(&info->u.http))); } strcpy(s_hits_got[s_n_hits_got].type, SERV_TypeStr(info->type)); strcpy(s_hits_got[s_n_hits_got].xtra, (info->type & fSERV_Http) ? SERV_HTTP_PATH(&info->u.http) : ""); strcpy(s_hits_got[s_n_hits_got].loc , (info->site & fSERV_Local ) ? "yes" : "no"); strcpy(s_hits_got[s_n_hits_got].priv, (info->site & fSERV_Private ) ? "yes" : "no"); strcpy(s_hits_got[s_n_hits_got].stfl, (info->mode & fSERV_Stateful) ? "yes" : "no"); SOCK_ntoa(info->host, s_hits_got[s_n_hits_got].host, LEN_HOST); s_hits_got[s_n_hits_got].port = info->port; s_hits_got[s_n_hits_got].match = 0; char *info_str; info_str = SERV_WriteInfo(info); CORE_LOGF(eLOG_Note, (" Found server %d: %s", s_n_hits_got, info_str ? info_str : "?")); if (info_str) free(info_str); } /* Make sure endpoint data can be repopulated and reset. */ if (repop && s_n_hits_got) { /* repopulate */ CORE_LOG(eLOG_Trace, "Repopulating the service mapper."); if ( ! info && ! SERV_GetNextInfo(iter)) { CORE_LOG(eLOG_Error, "Unable to repopulate endpoint data."); errors = 1; } } if (reset && s_n_hits_got) { /* reset */ CORE_LOG(eLOG_Trace, "Resetting the service mapper."); SERV_Reset(iter); if ( ! SERV_GetNextInfo(iter)) { CORE_LOG(eLOG_Error, "No services found after reset."); errors = 1; } } SERV_Close(iter); } else { errors = 1; } /* Search for matches unless this is a standalone run. */ if (check_for_match) { /* Search for perfect matches first (order is unknown). */ int it_exp, it_got; for (it_got=0; it_got < s_n_hits_got; ++it_got) { for (it_exp=0; it_exp < s_n_hits_exp; ++it_exp) { if (s_hits_exp[it_exp].match) continue; /*if (check_match(fMatch_Default, it_exp, it_got)) {*/ if (check_match(fMatch_All, it_exp, it_got)) { CORE_LOGF(eLOG_Note, ( " Found server %d perfectly matched expected server " "%d.", it_got, it_exp)); s_hits_exp[it_exp].match = 1; s_hits_got[it_got].match = 1; ++n_matches_perfect; break; } } } /* If not all found, search again but exclude host:port from match. */ for (it_got=0; it_got < s_n_hits_got; ++it_got) { if (s_hits_got[it_got].match) continue; for (it_exp=0; it_exp < s_n_hits_exp; ++it_exp) { if (s_hits_exp[it_exp].match) continue; if (check_match(fMatch_NoHostPort, it_exp, it_got)) { CORE_LOGF(eLOG_Note, ( " Found server %d nearly matched expected server %d.", it_got, it_exp)); s_hits_exp[it_exp].match = 1; s_hits_got[it_got].match = 1; ++n_matches_near; log_match_diffs(it_exp, it_got); break; } } } /* List any non-matching servers. */ for (it_exp=0; it_exp < s_n_hits_exp; ++it_exp) { if ( ! s_hits_exp[it_exp].match) CORE_LOGF(eLOG_Note, ( " Expected server %d didn't match any found servers.", it_exp)); } for (it_got=0; it_got < s_n_hits_got; ++it_got) { if ( ! s_hits_got[it_got].match) CORE_LOGF(eLOG_Note, ( " Found server %d didn't match any expected servers.", it_got)); } CORE_LOGF(n_matches_perfect + n_matches_near == s_n_hits_got ? eLOG_Note : eLOG_Error, ("Expected %d servers; found %d (%d perfect matches, %d near " "matches, and %d non-matches).", s_n_hits_exp, s_n_hits_got, n_matches_perfect, n_matches_near, s_n_hits_got - n_matches_perfect - n_matches_near)); if (!errors && s_n_hits_got == s_n_hits_exp && s_n_hits_got == n_matches_perfect + n_matches_near) { success = 1; } retval = (success != exp_err ? 1 : 0); CORE_LOGF(eLOG_Note, ("Test result: %s.", retval ? (success ? "PASS" : "PASS (with expected error)") : (success ? "FAIL (success when error expected)" : "FAIL"))); } out: if (mock_body_adj) free(mock_body_adj); return retval == -1 ? (success != exp_err ? 1 : 0) : retval; }