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; }
/* One can define env.var. 'service'_CONN_HOST to reroute dispatching * information to particular dispatching host (instead of default). */ int main(int argc, const char* argv[]) { static const char kParameter[] = "test_parameter"; const char* service = argc > 1 ? argv[1] : "bounce"; SConnNetInfo* net_info; const SSERV_Info* info; const char* value; int n_found = 0; SERV_ITER iter; CORE_SetLOGFormatFlags(fLOG_None | fLOG_Level | fLOG_OmitNoteLevel | fLOG_DateTime); CORE_SetLOGFILE(stderr, 0/*false*/); if (argc > 2) { if (strcasecmp(argv[2],"heap") == 0 || strcasecmp(argv[2],"all") == 0){ HEAP_Options(eOff, eDefault); CORE_LOG(eLOG_Note, "Using slow heap access (w/checks)"); } if (strcasecmp(argv[2],"lbsm") == 0 || strcasecmp(argv[2],"all") == 0){ #ifdef NCBI_OS_MSWIN if (strcasecmp(argv[2],"lbsm") == 0) { CORE_LOG(eLOG_Warning, "Option \"lbsm\" has no useful effect on MS-Windows"); } #else LBSMD_FastHeapAccess(eOn); CORE_LOG(eLOG_Note, "Using live (faster) LBSM heap access"); #endif /*NCBI_OS_MSWIN*/ } if (strcasecmp(argv[2],"lbsm") != 0 && strcasecmp(argv[2],"heap") != 0 && strcasecmp(argv[2],"all") != 0) CORE_LOGF(eLOG_Fatal, ("Unknown option `%s'", argv[2])); } value = LBSMD_GetHostParameter(SERV_LOCALHOST, kParameter); CORE_LOGF(eLOG_Note, ("Querying host parameter `%s': %s%s%s", kParameter, "`" + !value, value ? value : "Not found", "'" + !value)); if (value) free((void*) value); CORE_LOGF(eLOG_Note, ("Looking for service `%s'", service)); net_info = ConnNetInfo_Create(service); CORE_LOG(eLOG_Trace, "Opening service mapper"); iter = SERV_OpenP(service, (fSERV_All & ~fSERV_Firewall) | (strpbrk(service, "?*") ? 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); if (iter) { HOST_INFO hinfo; CORE_LOGF(eLOG_Trace,("%s service mapper has been successfully opened", SERV_MapperName(iter))); while ((info = SERV_GetNextInfoEx(iter, &hinfo)) != 0) { char* info_str = SERV_WriteInfo(info); CORE_LOGF(eLOG_Note, ("Server #%d `%s' = %s", ++n_found, SERV_CurrentName(iter), info_str)); if (hinfo) { static const char kTimeFormat[] = "%m/%d/%y %H:%M:%S"; time_t t; char buf[80]; double array[5]; SHINFO_Params params; const char* e = HINFO_Environment(hinfo); const char* a = HINFO_AffinityArgument(hinfo); const char* v = HINFO_AffinityArgvalue(hinfo); CORE_LOG(eLOG_Note, " Host info available:"); CORE_LOGF(eLOG_Note, (" Number of CPUs: %d", HINFO_CpuCount(hinfo))); CORE_LOGF(eLOG_Note, (" Number of CPU units: %d @ %.0fMHz", HINFO_CpuUnits(hinfo), HINFO_CpuClock(hinfo))); CORE_LOGF(eLOG_Note, (" Number of tasks: %d", HINFO_TaskCount(hinfo))); if (HINFO_MachineParams(hinfo, ¶ms)) { CORE_LOGF(eLOG_Note, (" Arch: %d", params.arch)); CORE_LOGF(eLOG_Note, (" OSType: %d", params.ostype)); t = (time_t) params.bootup; strftime(buf, sizeof(buf), kTimeFormat, localtime(&t)); CORE_LOGF(eLOG_Note, (" Kernel: %hu.%hu.%hu @ %s", params.kernel.major, params.kernel.minor, params.kernel.patch, buf)); CORE_LOGF(eLOG_Note, (" Bits: %hu", params.bits)); CORE_LOGF(eLOG_Note, (" Page size: %lu", (unsigned long) params.pgsize)); t = (time_t) params.start; strftime(buf, sizeof(buf), kTimeFormat, localtime(&t)); CORE_LOGF(eLOG_Note, (" LBSMD: %hu.%hu.%hu @ %s", params.daemon.major, params.daemon.minor, params.daemon.patch, buf)); } else CORE_LOG (eLOG_Note, " Machine params: unavailable"); if (HINFO_Memusage(hinfo, array)) { CORE_LOGF(eLOG_Note, (" Total RAM: %.2fMB", array[0])); CORE_LOGF(eLOG_Note, (" Cache RAM: %.2fMB", array[1])); CORE_LOGF(eLOG_Note, (" Free RAM: %.2fMB", array[2])); CORE_LOGF(eLOG_Note, (" Total Swap: %.2fMB", array[3])); CORE_LOGF(eLOG_Note, (" Free Swap: %.2fMB", array[4])); } else CORE_LOG (eLOG_Note, " Memory usage: unavailable"); if (HINFO_LoadAverage(hinfo, array)) { CORE_LOGF(eLOG_Note, (" Load averages: %f, %f (BLAST)", array[0], array[1])); } else CORE_LOG (eLOG_Note, " Load averages: unavailable"); if (a) { assert(*a); CORE_LOGF(eLOG_Note, (" Affinity argument: %s", a)); } if (a && v) CORE_LOGF(eLOG_Note, (" Affinity value: %s%s%s", *v ? "" : "\"", v, *v ? "" : "\"")); CORE_LOGF(eLOG_Note, (" Host environment: %s%s%s", e? "\"": "", e? e: "NULL", e? "\"": "")); free(hinfo); } free(info_str); } CORE_LOG(eLOG_Trace, "Resetting service mapper"); SERV_Reset(iter); CORE_LOG(eLOG_Trace, "Service mapper has been reset"); if (n_found && !(info = SERV_GetNextInfo(iter))) CORE_LOG(eLOG_Fatal, "Service not found after reset"); CORE_LOG(eLOG_Trace, "Closing service mapper"); SERV_Close(iter); } if (n_found != 0) CORE_LOGF(eLOG_Note, ("%d server(s) found", n_found)); else CORE_LOG(eLOG_Fatal, "Requested service not found"); #if 0 {{ SConnNetInfo* net_info; net_info = ConnNetInfo_Create(service); iter = SERV_Open(service, fSERV_Http, SERV_LOCALHOST, net_info); ConnNetInfo_Destroy(net_info); }} if (iter != 0) { while ((info = SERV_GetNextInfo(iter)) != 0) { char* info_str = SERV_WriteInfo(info); CORE_LOGF(eLOG_Note, ("Service `%s' = %s", service, info_str)); free(info_str); n_found++; } SERV_Close(iter); } #endif CORE_LOG(eLOG_Note, "TEST completed successfully"); CORE_SetLOG(0); return 0; }