/** @file A brief file description @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. */ /***************************************************************************** * Filename: APITestCliRemote.cc * Purpose: An interactive cli to test remote mgmt API; UNIT TEST for mgmtAPI * Created: lant * ***************************************************************************/ /*************************************************************************** * Possible Commands: *************************************************************************** * Control Operations: * ------------------- * state: returns ON (proxy is on) or OFF (proxy is off) * start: - turns Proxy on, the tsArgs is optional; * it can either be "hostdb" or "all", * eg. start, start:hostdb, start:all * stop: turns Proxy off * restart: restarts Traffic Manager (Traffic Cop must be running) * * File operations: * --------------- * read_file: reads hosting.config file * proxy.config.xxx (a records.config variable): returns value of that record * records: tests get/set/get a record of each different type * (int, float, counter, string) * err_recs: stress test record get/set functions by purposely entering * invalid record names and/or values * get_mlt: tests TSRecordGetMlt * set_mlt: tests TSRecordSetMlt * * read_url: tests TSReadFromUrl works by retrieving two valid urls * test_url: tests robustness of TSReadFromUrl using invalid urls * * Event Operations: * ---------------- * active_events: lists the names of all currently active events * MGMT_ALARM_xxx (event_name specified in CoreAPIShared.h or Alarms.h): * resolves the specified event * register: registers a generic callback (=eventCallbackFn) which * prints out the event name whenever an event is signalled * unregister: unregisters the generic callback function eventCallbackFn * * Diags * ---- * diags - uses STATUS, NOTE, FATAL, ERROR diags * * Statistics * ---------- * set_stats - sets dummy values for selected group of NODE, PROCESS * records * print_stats - prints the values for the same selected group of records * reset_stats - resets all statistics to default values */ #include "tscore/ink_config.h" #include "tscore/ink_defs.h" #include "tscore/ink_memory.h" #include #include #include #include #include "tscore/ink_string.h" #include "mgmtapi.h" // refer to test_records() function #define TEST_STRING 1 #define TEST_FLOAT 1 #define TEST_INT 1 #define TEST_COUNTER 1 #define TEST_REC_SET 1 #define TEST_REC_GET 0 #define TEST_REC_GET_2 0 #define SET_INT 0 /*************************************************************************** * Printing Helper Functions ***************************************************************************/ /* ------------------------------------------------------------------------ * print_err * ------------------------------------------------------------------------ * used to print the error description associated with the TSMgmtError err */ void print_err(const char *module, TSMgmtError err) { char *err_msg; err_msg = TSGetErrorMessage(err); printf("(%s) ERROR: %s\n", module, err_msg); if (err_msg) { TSfree(err_msg); } } /*------------------------------------------------------------- * print_string_list *-------------------------------------------------------------*/ void print_string_list(TSStringList list) { int i, count, buf_pos = 0; char buf[1000]; if (!list) { return; } count = TSStringListLen(list); for (i = 0; i < count; i++) { char *str = TSStringListDequeue(list); snprintf(buf + buf_pos, sizeof(buf) - buf_pos, "%s,", str); buf_pos = strlen(buf); TSStringListEnqueue(list, str); } printf("%s \n", buf); } /*------------------------------------------------------------- * print_int_list *-------------------------------------------------------------*/ void print_int_list(TSIntList list) { int i, count, buf_pos = 0; char buf[1000]; count = TSIntListLen(list); for (i = 0; i < count; i++) { int *elem = TSIntListDequeue(list); snprintf(buf + buf_pos, sizeof(buf) - buf_pos, "%d:", *elem); buf_pos = strlen(buf); TSIntListEnqueue(list, elem); } printf("Int List: %s \n", buf); } /*************************************************************************** * Control Testing ***************************************************************************/ void print_proxy_state() { TSProxyStateT state = TSProxyStateGet(); switch (state) { case TS_PROXY_ON: printf("Proxy State = ON\n"); break; case TS_PROXY_OFF: printf("Proxy State = OFF\n"); break; default: printf("ERROR: Proxy State Undefined!\n"); break; } } // starts Traffic Server (turns proxy on) void start_TS(char *tsArgs) { TSMgmtError ret; TSCacheClearT clear = TS_CACHE_CLEAR_NONE; char *args; strtok(tsArgs, ":"); args = strtok(nullptr, ":"); if (args) { if (strcmp(args, "all\n") == 0) { clear = TS_CACHE_CLEAR_CACHE; } else if (strcmp(args, "hostdb\n") == 0) { clear = TS_CACHE_CLEAR_HOSTDB; } } else { clear = TS_CACHE_CLEAR_NONE; } printf("STARTING PROXY with cache: %d\n", clear); if ((ret = TSProxyStateSet(TS_PROXY_ON, clear)) != TS_ERR_OKAY) { printf("[TSProxyStateSet] turn on FAILED\n"); } print_err("start_TS", ret); } // stops Traffic Server (turns proxy off) void stop_TS() { TSMgmtError ret; printf("STOPPING PROXY\n"); if ((ret = TSProxyStateSet(TS_PROXY_OFF, TS_CACHE_CLEAR_NONE)) != TS_ERR_OKAY) { printf("[TSProxyStateSet] turn off FAILED\n"); } print_err("stop_TS", ret); } // restarts Traffic Manager (Traffic Cop must be running) void restart() { TSMgmtError ret; printf("RESTART\n"); if ((ret = TSRestart(true)) != TS_ERR_OKAY) { printf("[TSRestart] FAILED\n"); } print_err("restart", ret); } // rereads all the configuration files void reconfigure() { TSMgmtError ret; printf("RECONFIGURE\n"); if ((ret = TSReconfigure()) != TS_ERR_OKAY) { printf("[TSReconfigure] FAILED\n"); } print_err("reconfigure", ret); } /* ------------------------------------------------------------------------ * test_action_need * ------------------------------------------------------------------------ * tests if correct action need is returned when requested record is set */ void test_action_need() { TSActionNeedT action; // RU_NULL record TSRecordSetString("proxy.config.proxy_name", "proxy_dorky", &action); printf("[TSRecordSetString] proxy.config.proxy_name \n\tAction Should: [%d]\n\tAction is : [%d]\n", TS_ACTION_UNDEFINED, action); } /* Bouncer the traffic_server process(es) */ void bounce() { TSMgmtError ret; printf("BOUNCER\n"); if ((ret = TSBounce(true)) != TS_ERR_OKAY) { printf("[TSBounce] FAILED\n"); } print_err("bounce", ret); } /*************************************************************************** * Record Testing ***************************************************************************/ /* ------------------------------------------------------------------------ * test_error_records * ------------------------------------------------------------------------ * stress test error handling by purposely being dumb; send requests to * get invalid record names */ void test_error_records() { TSInt port1, new_port = 8080; TSActionNeedT action; TSMgmtError ret; TSCounter ctr1; printf("\n"); // test get integer fprintf(stderr, "Test invalid record names\n"); ret = TSRecordGetInt("proy.config.cop.core_signal", &port1); if (ret != TS_ERR_OKAY) { print_err("TSRecordGetInt", ret); } else { printf("[TSRecordGetInt] proxy.config.cop.core_signal=%" PRId64 " \n", port1); } // test set integer ret = TSRecordSetInt("proy.config.cop.core_signal", new_port, &action); print_err("TSRecordSetInt", ret); printf("\n"); if (TSRecordGetCounter("proxy.press.socks.connections_successful", &ctr1) != TS_ERR_OKAY) { printf("TSRecordGetCounter FAILED!\n"); } else { printf("[TSRecordGetCounter]proxy.process.socks.connections_successful=%" PRId64 " \n", ctr1); } } /* ------------------------------------------------------------------------ * test_records * ------------------------------------------------------------------------ * stress test record functionality by getting and setting different * records types; use the #defines defined above to determine which * type of tests you'd like turned on/off */ void test_records() { TSActionNeedT action; char *rec_value; char new_str[] = "new_record_value"; TSInt port1, port2, new_port = 52432; TSCounter ctr1, ctr2, new_ctr = 6666; TSMgmtError err; /********************* START TEST SECTION *****************/ printf("\n\n"); #if SET_INT // test set integer if (TSRecordSetInt("proxy.config.cop.core_signal", new_port, &action) != TS_ERR_OKAY) printf("TSRecordSetInt FAILED!\n"); else printf("[TSRecordSetInt] proxy.config.cop.core_signal=%" PRId64 " \n", new_port); #endif #if TEST_REC_GET TSRecordEle *rec_ele; // retrieve a string value record using generic RecordGet rec_ele = TSRecordEleCreate(); if (TSRecordGet("proxy.config.http.cache.vary_default_other", rec_ele) != TS_ERR_OKAY) printf("TSRecordGet FAILED!\n"); else printf("[TSRecordGet] proxy.config.http.cache.vary_default_other=%s\n", rec_ele->string_val); TSRecordEleDestroy(rec_ele); printf("\n\n"); #endif #if TEST_REC_GET_2 // retrieve a string value record using generic RecordGet rec_ele = TSRecordEleCreate(); if (TSRecordGet("proxy.config.proxy_name", rec_ele) != TS_ERR_OKAY) printf("TSRecordGet FAILED!\n"); else printf("[TSRecordGet] proxy.config.proxy_name=%s\n", rec_ele->string_val); TSRecordEleDestroy(rec_ele); printf("\n\n"); #endif #if TEST_STRING // retrieve an string value record using GetString err = TSRecordGetString("proxy.config.proxy_name", &rec_value); if (err != TS_ERR_OKAY) { print_err("TSRecordGetString", err); } else { printf("[TSRecordGetString] proxy.config.proxy_name=%s\n", rec_value); } TSfree(rec_value); rec_value = nullptr; // test RecordSet err = TSRecordSetString("proxy.config.proxy_name", (TSString)new_str, &action); if (err != TS_ERR_OKAY) { print_err("TSRecordSetString", err); } else { printf("[TSRecordSetString] proxy.config.proxy_name=%s\n", new_str); } // get err = TSRecordGetString("proxy.config.proxy_name", &rec_value); if (err != TS_ERR_OKAY) { print_err("TSRecordGetString", err); } else { printf("[TSRecordGetString] proxy.config.proxy_name=%s\n", rec_value); } printf("\n"); TSfree(rec_value); #endif #if TEST_INT printf("\n"); // test get integer if (TSRecordGetInt("proxy.config.cop.core_signal", &port1) != TS_ERR_OKAY) { printf("TSRecordGetInt FAILED!\n"); } else { printf("[TSRecordGetInt] proxy.config.cop.core_signal=%" PRId64 " \n", port1); } // test set integer if (TSRecordSetInt("proxy.config.cop.core_signal", new_port, &action) != TS_ERR_OKAY) { printf("TSRecordSetInt FAILED!\n"); } else { printf("[TSRecordSetInt] proxy.config.cop.core_signal=%" PRId64 " \n", new_port); } if (TSRecordGetInt("proxy.config.cop.core_signal", &port2) != TS_ERR_OKAY) { printf("TSRecordGetInt FAILED!\n"); } else { printf("[TSRecordGetInt] proxy.config.cop.core_signal=%" PRId64 " \n", port2); } printf("\n"); #endif #if TEST_COUNTER printf("\n"); if (TSRecordGetCounter("proxy.process.socks.connections_successful", &ctr1) != TS_ERR_OKAY) { printf("TSRecordGetCounter FAILED!\n"); } else { printf("[TSRecordGetCounter]proxy.process.socks.connections_successful=%" PRId64 " \n", ctr1); } if (TSRecordSetCounter("proxy.process.socks.connections_successful", new_ctr, &action) != TS_ERR_OKAY) { printf("TSRecordSetCounter FAILED!\n"); } else { printf("[TSRecordSetCounter] proxy.process.socks.connections_successful=%" PRId64 " \n", new_ctr); } if (TSRecordGetCounter("proxy.process.socks.connections_successful", &ctr2) != TS_ERR_OKAY) { printf("TSRecordGetCounter FAILED!\n"); } else { printf("[TSRecordGetCounter]proxy.process.socks.connections_successful=%" PRId64 " \n", ctr2); } printf("\n"); #endif } // retrieves the value of the "proxy.config.xxx" record requested at input void test_rec_get(char *rec_name) { TSRecordEle *rec_ele; TSMgmtError ret; char *name; name = ats_strdup(rec_name); printf("[test_rec_get] Get Record: %s\n", name); // retrieve a string value record using generic RecordGet rec_ele = TSRecordEleCreate(); if ((ret = TSRecordGet(name, rec_ele)) != TS_ERR_OKAY) { printf("TSRecordGet FAILED!\n"); } else { switch (rec_ele->rec_type) { case TS_REC_INT: printf("[TSRecordGet] %s=%" PRId64 "\n", name, rec_ele->valueT.int_val); break; case TS_REC_COUNTER: printf("[TSRecordGet] %s=%" PRId64 "\n", name, rec_ele->valueT.counter_val); break; case TS_REC_FLOAT: printf("[TSRecordGet] %s=%f\n", name, rec_ele->valueT.float_val); break; case TS_REC_STRING: printf("[TSRecordGet] %s=%s\n", name, rec_ele->valueT.string_val); break; default: // Handled here: // TS_REC_UNDEFINED break; } } print_err("TSRecordGet", ret); TSRecordEleDestroy(rec_ele); TSfree(name); } /* ------------------------------------------------------------------------ * test_record_get_mlt * ------------------------------------------------------------------------ * Creates a list of record names to retrieve, and then batch request to * get list of records */ void test_record_get_mlt() { TSStringList name_list; TSList rec_list; int i, num; char *v1, *v2, *v3, *v6, *v7; TSMgmtError ret; name_list = TSStringListCreate(); rec_list = TSListCreate(); const size_t v1_size = (sizeof(char) * (strlen("proxy.config.proxy_name") + 1)); v1 = static_cast(TSmalloc(v1_size)); ink_strlcpy(v1, "proxy.config.proxy_name", v1_size); const size_t v2_size = (sizeof(char) * (strlen("proxy.config.bin_path") + 1)); v2 = static_cast(TSmalloc(v2_size)); ink_strlcpy(v2, "proxy.config.bin_path", v2_size); const size_t v3_size = (sizeof(char) * (strlen("proxy.config.manager_binary") + 1)); v3 = static_cast(TSmalloc(v3_size)); ink_strlcpy(v3, "proxy.config.manager_binary", v3_size); const size_t v6_size = (sizeof(char) * (strlen("proxy.config.env_prep") + 1)); v6 = static_cast(TSmalloc(v6_size)); ink_strlcpy(v6, "proxy.config.env_prep", v6_size); const size_t v7_size = (sizeof(char) * (strlen("proxy.config.cop.core_signal") + 1)); v7 = static_cast(TSmalloc(v7_size)); ink_strlcpy(v7, "proxy.config.cop.core_signal", v7_size); // add the names to the get_list TSStringListEnqueue(name_list, v1); TSStringListEnqueue(name_list, v2); TSStringListEnqueue(name_list, v3); TSStringListEnqueue(name_list, v6); TSStringListEnqueue(name_list, v7); num = TSStringListLen(name_list); printf("Num Records to Get: %d\n", num); ret = TSRecordGetMlt(name_list, rec_list); // free the string list TSStringListDestroy(name_list); if (ret != TS_ERR_OKAY) { print_err("TSStringListDestroy", ret); } for (i = 0; i < num; i++) { TSRecordEle *rec_ele = static_cast(TSListDequeue(rec_list)); if (!rec_ele) { printf("ERROR\n"); break; } printf("Record: %s = ", rec_ele->rec_name); switch (rec_ele->rec_type) { case TS_REC_INT: printf("%" PRId64 "\n", rec_ele->valueT.int_val); break; case TS_REC_COUNTER: printf("%" PRId64 "\n", rec_ele->valueT.counter_val); break; case TS_REC_FLOAT: printf("%f\n", rec_ele->valueT.float_val); break; case TS_REC_STRING: printf("%s\n", rec_ele->valueT.string_val); break; default: // Handled here: // TS_REC_UNDEFINED break; } TSRecordEleDestroy(rec_ele); } TSListDestroy(rec_list); // must dequeue and free each string individually return; } /* ------------------------------------------------------------------------ * test_record_set_mlt * ------------------------------------------------------------------------ * Creates a list of TSRecordEle's, and then batch request to set records * Also checks to make sure correct action_need type is set. */ void test_record_set_mlt() { TSList list; TSRecordEle *ele1, *ele2; TSActionNeedT action = TS_ACTION_UNDEFINED; TSMgmtError err; list = TSListCreate(); ele1 = TSRecordEleCreate(); // TS_TYPE_UNDEFINED action ele1->rec_name = TSstrdup("proxy.config.cli_binary"); ele1->rec_type = TS_REC_STRING; ele1->valueT.string_val = TSstrdup(ele1->rec_name); ele2 = TSRecordEleCreate(); // undefined action ele2->rec_name = TSstrdup("proxy.config.cop.core_signal"); ele2->rec_type = TS_REC_INT; ele2->valueT.int_val = -4; TSListEnqueue(list, ele1); TSListEnqueue(list, ele2); err = TSRecordSetMlt(list, &action); print_err("TSRecordSetMlt", err); fprintf(stderr, "[TSRecordSetMlt] Action Required: %d\n", action); // cleanup: need to iterate through list and delete each ele int count = TSListLen(list); for (int i = 0; i < count; i++) { TSRecordEle *ele = static_cast(TSListDequeue(list)); TSRecordEleDestroy(ele); } TSListDestroy(list); } /*************************************************************************** * File I/O Testing ***************************************************************************/ // if valid==true, then use a valid url to read void test_read_url(bool valid) { char *header = nullptr; int headerSize; char *body = nullptr; int bodySize; TSMgmtError err; if (!valid) { // first try err = TSReadFromUrlEx("hsdfasdf.com:80/index.html", &header, &headerSize, &body, &bodySize, 50000); if (err != TS_ERR_OKAY) { print_err("TSReadFromUrlEx", err); } else { printf("--------------------------------------------------------------\n"); // printf("The header...\n%s\n%d\n", *header, *headerSize); printf("--------------------------------------------------------------\n"); printf("The body...\n%s\n%d\n", body, bodySize); } if (body) { TSfree(body); } if (header) { TSfree(header); } err = TSReadFromUrlEx("http://sadfasdfi.com:80/", &header, &headerSize, &body, &bodySize, 50000); if (err != TS_ERR_OKAY) { print_err("TSReadFromUrlEx", err); } else { printf("---------------------------------------------------------------\n"); printf("The header...\n%s\n%d\n", header, headerSize); printf("-------------------------------------------------------------\n"); printf("The body...\n%s\n%d\n", body, bodySize); } if (header) { TSfree(header); } if (body) { TSfree(body); } } else { // use valid urls err = TSReadFromUrlEx("lakota.example.com:80/", &header, &headerSize, &body, &bodySize, 50000); if (err != TS_ERR_OKAY) { print_err("TSReadFromUrlEx", err); } else { printf("---------------------------------------------------------------\n"); printf("The header...\n%s\n%d\n", header, headerSize); printf("-------------------------------------------------------------\n"); printf("The body...\n%s\n%d\n", body, bodySize); } if (header) { TSfree(header); } if (body) { TSfree(body); } // read second url err = TSReadFromUrlEx("http://www.apache.org:80/index.html", &header, &headerSize, &body, &bodySize, 50000); if (err != TS_ERR_OKAY) { print_err("TSReadFromUrlEx", err); } else { printf("---------------------------------------------------------------\n"); printf("The header...\n%s\n%d\n", header, headerSize); printf("-------------------------------------------------------------\n"); printf("The body...\n%s\n%d\n", body, bodySize); } if (header) { TSfree(header); } if (body) { TSfree(body); } } } /*************************************************************************** * Events Testing ***************************************************************************/ /* ------------------------------------------------------------------------ * print_active_events * ------------------------------------------------------------------------ * retrieves a list of all active events and prints out each event name, * one event per line */ void print_active_events() { TSList events; TSMgmtError ret; int count, i; char *name; printf("[print_active_events]\n"); events = TSListCreate(); ret = TSActiveEventGetMlt(events); if (ret != TS_ERR_OKAY) { print_err("TSActiveEventGetMlt", ret); goto END; } else { // successful get count = TSListLen(events); for (i = 0; i < count; i++) { name = static_cast(TSListDequeue(events)); printf("\t%s\n", name); TSfree(name); } } END: TSListDestroy(events); return; } /* ------------------------------------------------------------------------ * check_active * ------------------------------------------------------------------------ * returns true if the event named event_name is currently active (unresolved) * returns false otherwise */ bool check_active(char *event_name) { bool active; TSMgmtError ret; ret = TSEventIsActive(event_name, &active); print_err("TSEventIsActive", ret); if (active) { printf("%s is ACTIVE\n", event_name); } else { printf("%s is NOT-ACTIVE\n", event_name); } return active; } /* ------------------------------------------------------------------------ * try_resolve * ------------------------------------------------------------------------ * checks if the event_name is still unresolved; if it is, it then * resolves it, and checks the status of the event again to make sure * the event was actually resolved * * NOTE: all the special string manipulation is needed because the CLI * appends extra newline character to end of the user input; normally * do not have to do all this special string manipulation */ void try_resolve(char *event_name) { TSMgmtError ret; char *name; name = TSstrdup(event_name); printf("[try_resolve] Resolving event: %s\n", name); if (check_active(name)) { // resolve events ret = TSEventResolve(name); print_err("TSEventResolve", ret); check_active(name); // should be non-active now } TSfree(name); } /* ------------------------------------------------------------------------ * eventCallbackFn * ------------------------------------------------------------------------ * the callback function; when called, it just prints out the name * of the event that was signalled */ void eventCallbackFn(char *name, char *msg, int /* pri ATS_UNUSED */, void * /* data ATS_UNUSED */) { printf("[eventCallbackFn] EVENT: %s, %s\n", name, msg); return; } /* ------------------------------------------------------------------------ * register_event_callback * ------------------------------------------------------------------------ * registers the eventCallbackFn above for all events; this just means * that for any event that's signalled, the callback fn will also be called */ void register_event_callback() { TSMgmtError err; printf("\n[register_event_callback] \n"); err = TSEventSignalCbRegister(nullptr, eventCallbackFn, nullptr); print_err("TSEventSignalCbRegister", err); } /* ------------------------------------------------------------------------ * unregister_event_callback * ------------------------------------------------------------------------ * unregisters the eventCallbackFn above for all events; this just means * that it will remove this eventCallbackFn entirely so that for any * event called, the eventCallbackFn will NOT be called */ void unregister_event_callback() { TSMgmtError err; printf("\n[unregister_event_callback]\n"); err = TSEventSignalCbUnregister(nullptr, eventCallbackFn); print_err("TSEventSignalCbUnregister", err); } /*************************************************************************** * Statistics ***************************************************************************/ // generate dummy values for statistics void set_stats() { TSActionNeedT action; fprintf(stderr, "[set_stats] Set Dummy Stat Values\n"); TSRecordSetInt("proxy.process.http.user_agent_response_document_total_size", 100, &action); TSRecordSetInt("proxy.process.http.user_agent_response_header_total_size", 100, &action); TSRecordSetInt("proxy.process.http.current_client_connections", 100, &action); TSRecordSetInt("proxy.process.http.current_client_transactions", 100, &action); TSRecordSetInt("proxy.process.http.origin_server_response_document_total_size", 100, &action); TSRecordSetInt("proxy.process.http.origin_server_response_header_total_size", 100, &action); TSRecordSetInt("proxy.process.http.current_server_connections", 100, &action); TSRecordSetInt("proxy.process.http.current_server_transactions", 100, &action); TSRecordSetInt("proxy.node.proxy_running", 110, &action); TSRecordSetInt("proxy.node.proxy_running", 110, &action); } void print_stats() { TSInt i1, i2, i3, i4, i5, i6, i7, i8; fprintf(stderr, "[print_stats]\n"); TSRecordGetInt("proxy.process.http.user_agent_response_document_total_size", &i1); TSRecordGetInt("proxy.process.http.user_agent_response_header_total_size", &i2); TSRecordGetInt("proxy.process.http.current_client_connections", &i3); TSRecordGetInt("proxy.process.http.current_client_transactions", &i4); TSRecordGetInt("proxy.process.http.origin_server_response_document_total_size", &i5); TSRecordGetInt("proxy.process.http.origin_server_response_header_total_size", &i6); TSRecordGetInt("proxy.process.http.current_server_connections", &i7); TSRecordGetInt("proxy.process.http.current_server_transactions", &i8); fprintf(stderr, "%" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 "\n", i1, i2, i3, i4, i5, i6, i7, i8); TSRecordGetInt("proxy.node.proxy_running", &i4); TSRecordGetInt("proxy.node.proxy_running", &i6); fprintf(stderr, "%" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 "\n", i1, i7, i2, i3, i4, i5, i6); fprintf(stderr, "PROCESS stats: \n"); fprintf(stderr, "%" PRId64 ", %" PRId64 ", %" PRId64 ", %" PRId64 "\n", i1, i2, i3, i4); } void reset_stats() { TSMgmtError err = TSStatsReset(nullptr); print_err("TSStatsReset", err); return; } void sync_test() { TSActionNeedT action; TSRecordSetString("proxy.config.proxy_name", "dorkface", &action); printf("[TSRecordSetString] proxy.config.proxy_name \n\tAction Should: [%d]\n\tAction is : [%d]\n", TS_ACTION_UNDEFINED, action); TSMgmtError ret; if ((ret = TSProxyStateSet(TS_PROXY_OFF, TS_CACHE_CLEAR_NONE)) != TS_ERR_OKAY) { printf("[TSProxyStateSet] turn off FAILED\n"); } print_err("stop_TS", ret); } /* ########################################################################*/ /* ------------------------------------------------------------------------ * runInteractive * ------------------------------------------------------------------------ * the loop that processes the commands inputted by user */ static void runInteractive() { char buf[512]; // holds request from interactive prompt // process input from command line while (true) { // Display a prompt printf("api_cli-> "); // get input from command line ATS_UNUSED_RETURN(fgets(buf, 512, stdin)); // check status of 'stdin' after reading if (feof(stdin) != 0) { printf("EXIT api_cli_remote\n"); return; } else if (ferror(stdin) != 0) { printf("EXIT api_cli_remote\n"); return; } // continue on newline if (strcmp(buf, "\n") == 0) { continue; } // exiting/quitting? if (strcasecmp("quit\n", buf) == 0 || strcasecmp("exit\n", buf) == 0) { // Don't wait for response LM // exit(0); return; } // check what operation user typed in if (strstr(buf, "state")) { print_proxy_state(); } else if (strncmp(buf, "start", 5) == 0) { start_TS(buf); } else if (strstr(buf, "stop")) { stop_TS(); } else if (strstr(buf, "restart")) { restart(); } else if (strstr(buf, "reconfig")) { reconfigure(); } else if (strstr(buf, "records")) { test_records(); } else if (strstr(buf, "err_recs")) { test_error_records(); } else if (strstr(buf, "get_mlt")) { test_record_get_mlt(); } else if (strstr(buf, "set_mlt")) { test_record_set_mlt(); } else if (strstr(buf, "proxy.")) { test_rec_get(buf); } else if (strstr(buf, "active_events")) { print_active_events(); } else if (strstr(buf, "MGMT_ALARM_")) { try_resolve(buf); } else if (strncmp(buf, "register", 8) == 0) { register_event_callback(); } else if (strstr(buf, "unregister")) { unregister_event_callback(); } else if (strstr(buf, "read_url")) { test_read_url(true); } else if (strstr(buf, "test_url")) { test_read_url(false); } else if (strstr(buf, "reset_stats")) { reset_stats(); } else if (strstr(buf, "set_stats")) { set_stats(); } else if (strstr(buf, "print_stats")) { print_stats(); } else { sync_test(); } } // end while(1) } // end runInteractive /* ------------------------------------------------------------------------ * main * ------------------------------------------------------------------------ * Main entry point which connects the client to the API, does any * clean up on exit, and gets the interactive command-line running */ int main(int /* argc ATS_UNUSED */, char ** /* argv ATS_UNUSED */) { TSMgmtError ret; if ((ret = TSInit(nullptr, TS_MGMT_OPT_DEFAULTS)) == TS_ERR_OKAY) { runInteractive(); TSTerminate(); printf("END REMOTE API TEST\n"); } else { print_err("main", ret); } return 0; } // end main()