END_TEST START_TEST (test_conninvalid_disconnectinvalidparam) { int status = storage_disconnect(NULL); fail_unless(status == -1, "storage_disconnect with invalid param should fail."); fail_unless(errno == ERR_INVALID_PARAM, "storage_disconnect with invalid param not setting errno properly."); }
void libetpan_storage_disconnect(struct mailengine * engine, struct mailstorage * storage) { struct storage_ref_info * ref_info; ref_info = get_storage_ref_info(engine, storage); storage_disconnect(ref_info); }
/** * @brief Attempts to disconnect from the server. * @return Returns 0 on success, -1 otherwise. */ int client_disconnect() { int status = storage_disconnect(conn); if(status != 0) printf("storage_disconnect failed. Error code: %d.\n", errno); else { printf("Server connection closed.\n"); conn = NULL; } return status; }
END_TEST START_TEST (test_conn_basic) { int serverpid = start_server(ONETABLE_CONF, NULL, "test_conn_basic.serverout"); fail_unless(serverpid > 0, "Server didn't run properly."); void *conn = storage_connect(SERVERHOST, server_port); fail_unless(conn != NULL, "Couldn't connect to server."); int status = storage_disconnect(conn); fail_unless(status == 0, "Error disconnecting from the server."); }
/** * @brief Attempts to authenticate the user with the server. * * Closes server connection and exits if the user fails to authenticate. * @return Returns 0 on success, -1 otherwise. */ int client_auth() { char username[MAX_USERNAME_LEN] = {0}, password[MAX_ENC_PASSWORD_LEN] = {0}; bool read_success = false; while(read_success == false) { printf("Please enter the username: "******"%s %s", username, trash) != 1)) printf("Please enter a valid username (no spaces).\n"); else read_success = true; } read_success = false; while(read_success == false) { printf("Please enter the password: "******"%s %s", password, trash) != 1)) printf("Please enter a valid password (no spaces).\n"); else read_success = true; } int i; char pass_asterik[strlen(password) + 1]; for(i = 0; i < strlen(password); i++) pass_asterik[i] = '*'; pass_asterik[i] = 0; int status = storage_auth(username, password, conn); if(status != 0) { printf("storage_auth failed with username '%s' and password '%s'. " \ "Error code: %d.\n", username, pass_asterik, errno); storage_disconnect(conn); } else printf("storage_auth: successful.\nWelcome %s!\n", username); return status; }
END_TEST /* * Connection tests: * connect to and disconnect from server (pass) * connect to server without server running (fail) * connect to server with invalid hostname (fail) * disconnect from server with invalid params (fail) */ START_TEST (test_conn_basic) { int serverpid = start_server(ONETABLE_CONF, NULL, "test_conn_basic.serverout"); fail_unless(serverpid > 0, "Server didn't run properly."); void *conn = storage_connect(SERVERHOST, server_port); fail_unless(conn != NULL, "Couldn't connect to server."); int status = storage_disconnect(conn); fail_unless(status == 0, "Error disconnecting from the server."); }
/** * @brief Text fixture teardown. Disconnect from the server. */ void test_teardown() { // Disconnect from the server. storage_disconnect(test_conn); //fail_unless(status == 0, "Error disconnecting from the server."); }
int main(int argc, char *argv[]) { // initial variables used throughout all of the commands int i; int SERVERPORT; char SERVERHOST[MAX_HOST_LEN], SERVERUSERNAME[MAX_USERNAME_LEN], SERVERPASSWORD[MAX_ENC_PASSWORD_LEN], SERVERPORTstr[MAX_PORT_LEN]; char TABLE[MAX_TABLE_LEN], KEY[MAX_KEY_LEN]; char **key = malloc(sizeof(char**)*800); char PREDICATES_1[500]; char PREDICATES[500]; void *conn = NULL; int status; struct storage_record r; int authenticated = 0; do{ printmenu(&i); // function to prompt the user for the menu and read in and update the variable i if(i == 0){// Connect to server if(conn != NULL) printf("You are already connected. Please choose another option.\n\n"); else { conn = storage_connect("localhost",2222); if(!conn) { printf("Cannot connect to server @ %s:%d. Error code: %d.\n", SERVERHOST, SERVERPORT, errno); //return -1; } else printf("\nUser conncected with the server\n"); status = storage_auth("admin", "dog4sale", conn); if(status != 0) { printf("storage_auth failed with username '%s' and password '%s'. " \ "Error code: %d, status: %d\n", SERVERUSERNAME, SERVERPASSWORD, errno, status); //storage_disconnect(conn); //return status; } else{ authenticated = 1; printf("\nUser authenticated with the server\n"); } } } if(i == 1) {// Connect to server if(conn != NULL) printf("You are already connected. Please choose another option.\n\n"); else { printf("Enter the Server Host\n"); fgets(SERVERHOST, MAX_HOST_LEN, stdin); sscanf(SERVERHOST, "%s", SERVERHOST); printf("Enter the Server Port\n"); fgets(SERVERPORTstr, MAX_PORT_LEN, stdin); sscanf(SERVERPORTstr, "%d", &SERVERPORT); conn = storage_connect(SERVERHOST, SERVERPORT); if(!conn) { printf("Cannot connect to server @ %s:%d. Error code: %d.\n", SERVERHOST, SERVERPORT, errno); //return -1; } else printf("\nUser connected with the server\n"); } } else if(i == 2) {// Authenticate the client. if(conn == NULL) printf("You are not connected yet. Please connect to the server first.\n\n"); //else if(authenticated == 1) //printf("You are already authenticated. Please choose another option.\n\n"); else { printf("Enter the UserName Host\n"); fgets(SERVERUSERNAME, MAX_USERNAME_LEN, stdin); sscanf(SERVERUSERNAME, "%s", SERVERUSERNAME); printf("Enter the Password Host\n"); fgets(SERVERPASSWORD, MAX_ENC_PASSWORD_LEN, stdin); sscanf(SERVERPASSWORD, "%s", SERVERPASSWORD); status = storage_auth(SERVERUSERNAME, SERVERPASSWORD, conn); if(status != 0) { printf("storage_auth failed with username '%s' and password '%s'. " \ "Error code: %d, status: %d\n", SERVERUSERNAME, SERVERPASSWORD, errno, status); } else{ authenticated = 1; printf("\nUser authenticated with the server\n"); } } } else if(i == 3) {// SET command if(conn == NULL) printf("You are not connected yet. Please connect to the server first.\n\n"); else { printf("Please enter the Table\n"); fgets(TABLE, MAX_TABLE_LEN, stdin); sscanf(TABLE, "%s", TABLE); printf("Please enter the Key\n"); fgets(KEY, MAX_KEY_LEN, stdin); sscanf(KEY, "%s", KEY); printf("Please Enter the record that you wish to store\n"); fgets(r.value, MAX_VALUE_LEN, stdin); r.value[strlen(r.value)-1] = '\0'; //strncpy(r.value, value, sizeof value); //This is for measuring the server processing time //remember when the process started clock_t t; t=clock(); //issue set call to DATABASE with TABLE, KEY and r.value if(!strcmp(r.value,"null")){ status = storage_set(TABLE,KEY,NULL,conn); } if(strcmp(r.value,"null")) status = storage_set(TABLE, KEY, &r, conn); //find how long it took to perform the GET operation //current time minus the time when the operation started t=clock()-t; if(status != 0) { printf("storage_set failed. Error code: %d.\n", errno); } else printf("storage_set: successful.\n"); } } else if(i == 4) {// GET command if(conn == NULL) printf("You are not connected yet. Please connect to the server first.\n\n"); //else if(authenticated == 0) //printf("You are not authenticated yet. Please authenticate first.\n\n"); else { printf("Please enter the Table\n"); fgets(TABLE, MAX_TABLE_LEN, stdin); sscanf(TABLE, "%s", TABLE); printf("Please enter the Key\n"); fgets(KEY, MAX_KEY_LEN, stdin); sscanf(KEY, "%s", KEY); status = storage_get(TABLE, KEY, &r, conn); if(status != 0) { printf("storage_get failed. Error code: %d.\n", errno); storage_disconnect(conn); return status; } else printf("storage_get: the value returned for key '%s' is '%s'.\n", KEY, r.value); } } else if(i == 5) {// QUERY command if(conn == NULL) printf("You are not connected yet. Please connect to the server first.\n\n"); else { printf("Please enter the Table\n"); fgets(TABLE, MAX_TABLE_LEN, stdin); sscanf(TABLE, "%s", TABLE); printf("Please enter the Predicates\n"); fgets(PREDICATES_1, 500, stdin); sscanf(PREDICATES_1, "%[^'\n]",PREDICATES); // (const char *table, const char *predicates, char **keys, const int max_keys, void *conn) status = storage_query(TABLE, PREDICATES, key, &r, conn); //int foundkeys = storage_query(INTTABLE, "col<-1", test_keys, MAX_RECORDS_PER_TABLE, test_conn); printf("status/number of keys: %d\n",status); if(status == -1) { printf("storage_query failed. Error code: %d.\n", errno); storage_disconnect(conn); return status; } else { int p = 0; int i = 0; while (key[i] != NULL){ printf("key: '%s'\n", key[i]); i++; } } } } else if(i==6) {// Disconnect from server status = storage_disconnect(conn); if(status != 0) { printf("storage_disconnect failed. Error code: %d.\n", errno); return status; } else { conn = NULL; authenticated = 0; printf("You are now disconnected\n"); } } else if (i==8){ // import the census into the data base if(conn == NULL) printf("You are not connected yet. Please connect to the server first.\n\n"); FILE* fp; fp=fopen("census", "r"); //open the file for reading only if(fp == NULL) printf("Error opening file"); else { int loop; //populate the table with all the data in the data file (city + its population) do { char name[100]; char value[MAX_VALUE_LEN]; char line[100]; char *l = fgets(line, sizeof line, fp); if (!feof(fp)){ sscanf(l, "%s %s", name, value); printf("name: %s , value: %s \n", name, value); strcpy(r.value,value); status = storage_set("census", name, &r, conn); if(status != 0) { printf("storage_set failed. Error code: %d.\n", errno); } } } while(!feof(fp)); //read the first line (city) } } } while (i!=7); // if i is 6, we want to exit from client // Exit return 0; }
const char* testClient(void* parameters) { struct workerTask* worker = (struct workerTask*)parameters; uint16_t randContext[3]; for(int i = 0; i < 3; i++) { randContext[i] = time(NULL) ^ worker->workerID; } if(!worker->conn) { //spread the load from new connections so the server won't be overloaded usleep(erand48(randContext) * 1000 + 1000*worker->connOpenDelay); worker->conn = storage_connect(worker->hostname, worker->port); if(!worker->conn) { printf("storage_connect failed\n"); return ece297strerror(errno); } int result = storage_auth(worker->username, worker->password, worker->conn); if(result == -1) { printf("storage_auth failed\n"); storage_disconnect(worker->conn); worker->conn = NULL; return ece297strerror(errno); } } uint64_t loopCount = worker->numKeys; if(worker->type == kClientRunWorkload) { loopCount = worker->count; } uint64_t period = 0; //0 throughput = no limit if(worker->throughput) { period = (1/worker->throughput) * 1000000; //start at a random time usleep(erand48(randContext) * period); } struct timeval next; gettimeofday(&next, NULL); for(uint64_t i = 0; i < loopCount; i++) { if(worker->throughput) { int64_t timeRemaining = -uSElapsed(&next); if(timeRemaining > 0) { usleep((uint32_t)timeRemaining); } uint64_t newTime = next.tv_usec + period; next.tv_sec += newTime / 1000000; next.tv_usec = newTime % 1000000; } switch (worker->type) { case kClientAddKeys: { char keyBuf[20]; //as per ECE297 spec stringGen(worker->startingKey + i, worker->keySecret, keyBuf, sizeof(keyBuf)); struct storage_record record; memset(&record.metadata, 0, sizeof(record.metadata)); stringGen(worker->startingKey + i, worker->valueSecret, record.value, sizeof(record.value)); struct timeval start; gettimeofday(&start, NULL); if(storage_set(worker->table, keyBuf, &record, worker->conn) == -1) { printf("storage_set failed\n"); return ece297strerror(errno); } recordLatency(timeElapsed(&start), worker->latencyResults); break; } case kClientRunWorkload: { //WATCH the floating point promotion - it must be cast to a uint64_t BEFORE adding worker->startingKey uint64_t keyIndex = ((uint64_t)(erand48(randContext) * worker->numKeys)) + worker->startingKey; char keyBuf[20]; //as per ECE297 spec stringGen(keyIndex, worker->keySecret, keyBuf, sizeof(keyBuf)); char expectedValue[1024]; stringGen(keyIndex, worker->valueSecret, expectedValue, sizeof(expectedValue)); struct timeval start; gettimeofday(&start, NULL); struct storage_record rec; if(storage_get(worker->table, keyBuf, &rec, worker->conn) == -1) { printf("storage_get failed (key index = %u)\n", keyIndex); return ece297strerror(errno); } if(strcmp(rec.value, expectedValue)) { return "Server returned incorrect key"; } recordLatency(timeElapsed(&start), worker->latencyResults); } } } return NULL; }
int beginSlavery(int fd) { uint16_t randContext[3]; for(int i = 0; i < 3; i++) { randContext[i] = time(NULL) ^ getpid(); } int returnCode = -1; json_t* params = NULL; json_t* nextCommand = NULL; char** values = NULL; struct workerTask* tasks = NULL; uint32_t connPoolSize = 128; uint32_t connPoolCount = 0; void** connPool = __xmalloc(sizeof(void*) * connPoolSize); memset(connPool, 0, sizeof(void*) * connPoolSize); //recieve initial parameters params = readCommand(fd, 5000); if(!params) { fprintf(stderr, "No initialization packet\n"); goto exit; } //make sure the initial packet has all of the required info uint64_t slaveID; const char* command; const char* address; const char* username; const char* password; const char* tableName; int port; int errorChecking; int valueLength; int result = json_unpack(params, "{s:s, s:s, s:i, s:I, s:s, s:s, s:s, s:b, s:i}", "command", &command, "address", &address, "port", &port, "slave-id", &slaveID, "username", &username, "password", &password, "table", &tableName, "error-checking", &errorChecking, "value-length", &valueLength); if(result != 0 || strcmp(command, "init") || port <= 0 || port > 65535) { fprintf(stderr, "Invalid initialization packet recieved\n"); goto exit; } uint64_t numKeys = 0; //loop and execute commands from the master while(1) { nextCommand = readCommand(fd, 15000); if(!nextCommand) { fprintf(stderr, "Invalid next command\n"); goto exit; } const char* command; int result = json_unpack(nextCommand, "{s:s}", "command", &command); if(result == -1) { fprintf(stderr, "Packet missing command field\n"); goto exit; } //parse commands and modify keyRange array if needed struct workerTask task; if(!strcmp(command, "add")) { uint64_t numKeysToAdd; int result = json_unpack(nextCommand, "{s:I}", "amount", &numKeysToAdd); if(result == -1) { goto exit; } if(errorChecking) { values = __xrealloc(values, sizeof(char*) * (numKeys + numKeysToAdd)); for(uint64_t i = 0; i < numKeysToAdd; i++) { values[numKeys + i] = __xmalloc(valueLength + 1); for(int j = 0; j < valueLength; j++) { values[numKeys + i][j] = (erand48(randContext) * 26) + 'A'; } values[numKeys + i][valueLength] = '\0'; } } task.startingKey = slaveID + numKeys; task.numKeys = numKeysToAdd; task.type = kClientAddKeys; task.values = values; numKeys += task.numKeys; } else if(!strcmp(command, "remove")) { uint64_t numKeysToRemove; int result = json_unpack(nextCommand, "{s:I}", "amount", &numKeysToRemove); if(result == -1) { goto exit; } if(errorChecking) { uint64_t position = numKeys - numKeysToRemove; for(uint64_t i = 0; i < numKeysToRemove; i++) { free(values[position + i]); } values = __xrealloc(&values, sizeof(char*) * (numKeys - numKeysToRemove)); } if(numKeysToRemove > numKeys) { goto exit; } task.startingKey = slaveID + numKeys - numKeysToRemove; task.numKeys = numKeysToRemove; task.type = kClientRemoveKeys; task.values = NULL; numKeys -= numKeysToRemove; } else if(!strcmp(command, "test")) { json_t* array = json_object_get(nextCommand, "workload"); //right now we only need 1 workload type if(!(json_is_array(array) && json_array_size(array) == kWorkloadTypes)) { goto exit; } for(int i = 0; i < kWorkloadTypes; i++) { task.workloadComposition[i] = json_number_value(json_array_get(array, i)); } int result = json_unpack(nextCommand, "{s:I}", "amount", &task.count); if(result == -1) { goto exit; } task.startingKey = slaveID; task.numKeys = numKeys; task.values = values; task.type = kClientRunWorkload; } else if(!strcmp(command, "quit")) { returnCode = 0; goto exit; } else { fprintf(stderr, "unknown command from client: %s\n", command); goto exit; } int numClients; result = json_unpack(nextCommand, "{s:i, s:F}", "num-clients", &numClients, "throughput", &task.throughput); if(result == -1) { fprintf(stderr, "Packet missing number of clients or throughput value\n"); goto exit; } task.connOpenDelay = 0; //fill out the generic task information task.table = tableName; task.valueSize = valueLength; task.workerID = slaveID; task.hostname = address; task.username = username; task.password = password; task.port = port; //split the request between the clients while(numClients >= connPoolSize) { size_t oldSize = connPoolSize; connPoolSize *= 8; connPool = __xrealloc(connPool, connPoolSize * sizeof(void*)); memset(&connPool[oldSize], 0, sizeof(void*) * oldSize * 7); } if(numClients < connPoolCount) { for(int i = connPoolCount - 1; i >= numClients; i--) { storage_disconnect(connPool[i]); connPool[i] = NULL; } } tasks = __xmalloc(sizeof(struct workerTask) * numClients); splitTasks(&task, tasks, numClients, connPool); //perform the request json_t* requestResponse; performRequest(tasks, numClients, &requestResponse); //save the connections for next time for(int i = 0; i < numClients; i++) { connPool[i] = tasks[i].conn; } connPoolCount = numClients; //send the result back to the master char* serialResponse = json_dumps(requestResponse, JSON_COMPACT); json_decref(requestResponse); size_t len = strlen(serialResponse); if(len > 1048576) { fprintf(stderr, "Response too large (%zd)\n", len); free(serialResponse); goto exit; } char sizeBuf[9]; sprintf(sizeBuf, "%08d", (int)len); sendAll(fd, sizeBuf, 8); if(sendAll(fd, serialResponse, strlen(serialResponse)) == -1) { free(serialResponse); goto exit; } free(serialResponse); free(tasks); tasks = NULL; //free the parsed command json_decref(nextCommand); nextCommand = NULL; } exit: for(uint32_t i = 0; i < connPoolCount; i++) { storage_disconnect(connPool[i]); } free(connPool); free(tasks); json_decref(nextCommand); json_decref(params); if(values) { for(uint64_t i = 0; i < numKeys; i++) { free(values[i]); } free(values); } return returnCode; }
/** * @brief Start a client to interact with the storage server. * * If connect is successful, the client performs a storage_set/get() on * TABLE and KEY and outputs the results on stdout. Finally, it exists * after disconnecting from the server. */ int main(int argc, char *argv[]) { if(LOGGING == 1) ClientFile = stdout; else if(LOGGING == 2) { time_t Time = time(NULL); struct tm *currentTime = localtime(&Time); char ClientFileName[MAX_CONFIG_LINE_LEN]; int day = currentTime->tm_mday; int month = currentTime->tm_mon + 1; // Month is 0 - 11, add 1 to get a jan-dec 1-12 concept int year = currentTime->tm_year + 1900; int hour = currentTime->tm_hour; int minute = currentTime->tm_min; int second = currentTime->tm_sec; snprintf(ClientFileName, sizeof ClientFileName, "Client-%d-%02d-%02d-%02d-%02d-%02d.log",year,month,day,hour,minute,second);//making a string ClientFile = fopen(ClientFileName,"a"); } int selection = 0, port, status; char hostname[MAX_HOST_LEN+1], username[MAX_USERNAME_LEN], password[MAX_ENC_PASSWORD_LEN],table[MAX_TABLE_LEN],key[MAX_KEY_LEN], strc[MAX_CONFIG_LINE_LEN]; struct storage_record r; void *conn; // Client Interaction with the server while(selection!=6) { printf("> ----------------------\n"); printf("> 1) Connect\n"); printf("> 2) Authenticate\n"); printf("> 3) Get\n"); printf("> 4) Set\n"); printf("> 5) Disconnect\n"); printf("> 6) Exit\n"); printf("> ----------------------\n"); printf("> Please enter your selection: "); scanf("%d",&selection); // Connect to server if(selection == 1) { printf("> Please input the hostname: "); scanf("%s",hostname); printf("> Please input the port: "); scanf("%d",&port); conn = storage_connect(hostname, port); if(!conn) { snprintf(strc, sizeof strc, "> Cannot connect to server @ %s:%d. Error code: %d.\n",hostname, port, errno); printf("%s",strc); logger(ClientFile,"a"); return -1; } snprintf(strc, sizeof strc, "> Connecting to %s:%d ...\n",hostname,port); printf("%s",strc); logger(ClientFile,"a"); } // Authenticate the client. else if (selection == 2) { printf("> Please enter your username: "******"%s",username); printf("> Please enter your password: "******"%s",password); status = storage_auth(username, password, conn); if(status != 0) { snprintf(strc, sizeof strc, "> storage_auth failed with username '%s' and password '%s'. " \ "Error code: %d.\n", username, password, errno); printf("%s",strc); logger(ClientFile,strc); storage_disconnect(conn); return status; } snprintf(strc, sizeof strc, "> storage_auth: successful.\n"); printf("%s",strc); logger(ClientFile,strc); } // Issue storage_get else if (selection == 3) { printf("> Please enter table name: "); scanf("%s",table); printf("> Please enter key: "); scanf("%s",key); status = storage_get(table, key, &r, conn); if(status != 0) { snprintf(strc, sizeof strc, "> storage_get failed. Error code: %d.\n", errno); printf("%s",strc); logger(ClientFile,strc); storage_disconnect(conn); return status; } snprintf(strc, sizeof strc, "> storage_get: the value returned for key '%s' is '%s'.\n", key, r.value); printf("%s",strc); logger(ClientFile,strc); } // Issue storage_set else if(selection == 4) { printf("> Please enter table name: "); scanf("%s",table); printf("> Please enter key: "); scanf("%s",key); strncpy(r.value, "some_value", sizeof r.value); status = storage_set(table, key, &r, conn); if(status != 0) { snprintf(strc, sizeof strc, "> storage_set failed. Error code: %d.\n", errno); printf("%s",strc); logger(ClientFile,strc); storage_disconnect(conn); return status; } snprintf(strc, sizeof strc, "> storage_set: successful.\n"); printf("%s",strc); logger(ClientFile,strc); } // Disconnect from server else if (selection == 5) { status = storage_disconnect(conn); if(status != 0) { snprintf(strc, sizeof strc, "> storage_disconnect failed. Error code: %d.\n", errno); printf("%s",strc); logger(ClientFile,strc); return status; } snprintf(strc, sizeof strc, "> Disconnecting from %s:%d ...\n",hostname,port); printf("%s",strc); logger(ClientFile,strc); } //Exit else if (selection == 6) printf("> Exiting server...\n"); else printf("> Enter your selection again\n"); } fclose(ClientFile); return 0; }