Skip to content

Instantly share code, notes, and snippets.

@nycdavid
Created February 10, 2019 13:19
Show Gist options
  • Save nycdavid/faa3be3b0f2e975537b27c5200217906 to your computer and use it in GitHub Desktop.
Save nycdavid/faa3be3b0f2e975537b27c5200217906 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <netinet/in.h>
#include "gf-student.h"
// constants
const char* invalid = "INVALID";
// test loggers
void test_case_failure(char* msg);
void test_case_passed();
// test helpers
int request_test(char* request_string, const struct GetResponse* resp);
int make_socket();
int main() {
const struct GetResponse invalid_resp = {
.scheme = "",
.status = "INVALID",
.length = 0
};
const struct GetResponse file_not_found = {
.scheme = "",
.status = "FILE_NOT_FOUND",
.length = 0
};
/* Start TC */
printf("When an empty string is sent, the server sends an INVALID status.");
if (request_test("", &invalid_resp) == 0) {
test_case_passed();
}
/* End TC */
/* Start TC */
printf("When missing the scheme, the server sends an INVALID status.");
if (
request_test(
"GET /path/to/file.pdf\r\n\r\n",
&invalid_resp
) == 0
) {
test_case_passed();
}
/* End TC */
/* Start TC */
printf("When missing the method, the server sends an INVALID status.");
if (
request_test(
"GETFILE /path/to/file.pdf\r\n\r\n",
&invalid_resp
) == 0
) {
test_case_passed();
}
/* End TC */
/* Start TC */
printf("When missing the path, the server sends an INVALID status.");
if (
request_test(
"GETFILE GET\r\n\r\n",
&invalid_resp
) == 0
) {
test_case_passed();
}
/* End TC */
/* Start TC */
printf("When the path is missing a leading slash, the server sends an INVALID status.");
if (
request_test(
"GETFILE GET path/to/file.pdf\r\n\r\n",
&invalid_resp
) == 0
) {
test_case_passed();
}
/* End TC */
/* Start TC */
printf("When the file cannot be found, the server sends a FILE_NOT_FOUND status.");
if (
request_test(
"GETFILE GET /path/to/nonexistent.pdf\r\n\r\n",
&file_not_found
) == 0
) {
test_case_passed();
}
/* End TC */
/* Start TC */
const struct GetResponse paraglider_res = {
.scheme = "GETFILE",
.status = "OK",
.length = 233174
};
printf("When the file exists, the server sends an OK status.");
if (
request_test(
"GETFILE GET /courses/ud923/filecorpus/paraglider.jpg\r\n\r\n",
&paraglider_res
) == 0
) {
test_case_passed();
}
/* End TC */
/* Start TC */
printf("When the header is missing the end marker, the server sends an INVALID status");
if (
request_test(
"GETFILE GET /courses/ud923/filecorpus/paraglider.jpg",
&invalid_resp
) == 0
) {
test_case_passed();
}
/* End TC */
return 0;
}
int make_socket() {
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
int option = 1;
setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(50419);
server_address.sin_addr.s_addr = INADDR_ANY;
if (
connect(server_socket,
(struct sockaddr*) &server_address,
sizeof(server_address)) == -1
) {
test_case_failure("Error connecting.");
}
return server_socket;
}
int request_test(char* request_string, const struct GetResponse* resp) {
int socket = make_socket();
// Make proper transforms and send request
char req[strlen(request_string)+1];
strcpy(req, request_string);
if (send(socket, &req, sizeof(req), 0) == -1)
test_case_failure("Error sending.");
// Serialize buffer into Response struct
struct GetResponse received_resp = { .scheme = "", .status = "", .length = 0 };
serialize_into_response(&received_resp, socket);
char* received_status = received_resp.status;
char* expected_status = resp->status;
int received_length = received_resp.length;
int expected_length = resp->length;
if (strcmp(received_status, expected_status) != 0) {
char error_msg[255] = "";
sprintf(
error_msg,
"Expected status to be %s, got %s",
expected_status,
received_status
);
test_case_failure(error_msg);
close(socket);
return -1;
}
if (received_length != expected_length) {
char error_msg[255] = "";
sprintf(
error_msg,
"Expected length to be %d, got %d",
expected_length,
received_length
);
test_case_failure(error_msg);
close(socket);
return -1;
}
close(socket);
return 0;
}
void test_case_failure(char* msg) {
fprintf(stdout, "\033[0;31m"); // Set text color to red
fprintf(stdout, " [FAILED]\n");
fprintf(stdout, "\033[0m"); // Reset text color
fprintf(stdout, " %s\n", msg);
}
void test_case_passed() {
fprintf(stdout, "\033[0;32m"); // Set text color to green
fprintf(stdout, " [PASSED]\n");
fprintf(stdout, "\033[0m"); // Reset text color
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment