Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ CC = gcc
SRC_DIR := $(shell pwd)/src
INCLUDES = -I
OBJS = src/resolver.o
STD = -ansi

default: test
default: run_tests

deps:
pip install -r requirements.txt

test: $(OBJS)
psychic --cargs='$(OBJS) $(INCLUDES) $(SRC_DIR)'
psychic --cargs='$(OBJS) $(INCLUDES) $(SRC_DIR) $(STD)'

clean:
rm src/*.o

run_tests: clean test
16 changes: 16 additions & 0 deletions src/constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef CONSTANTS_H
#define CONSTANTS_H

#define QUERY 0
#define STANDARD_QUERY 0
#define NOT_AUTHORITATIVE 0
#define NOT_TRUNCATED 0
#define RECURSION_DESIRED 1
#define RECURSION_NOT_AVAILABLE 0
#define NO_ERRORS 0
#define ONE_QUESTION 1
#define NO_RESOURCE_RECORDS_IN_ANSWER 0
#define NO_RESOURCE_RECORDS_IN_AUTHORITY 0
#define NO_RESOURCE_RECORDS_IN_ADDITIONAL 0

#endif
64 changes: 64 additions & 0 deletions src/resolver.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,67 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "types.h"
#include "constants.h"

char* resolve(char* domain_name) {
return "161.47.4.22";
}

uint16_t counter = 1;

void reset_counter() {
counter = 1;
}

uint16_t generate_id() {
uint16_t c = counter;
counter++;
return c;
}

header* build_header() {
header *head = malloc(sizeof(header));
head -> id = generate_id();
head -> qr = QUERY;
head -> opcode = STANDARD_QUERY;
head -> aa = NOT_AUTHORITATIVE;
head -> tc = NOT_TRUNCATED;
head -> rd = RECURSION_DESIRED;
head -> rs = RECURSION_NOT_AVAILABLE;
head -> rcode = NO_ERRORS;
head -> qdcount = ONE_QUESTION;
head -> ancount = NO_RESOURCE_RECORDS_IN_ANSWER;
head -> nscount = NO_RESOURCE_RECORDS_IN_AUTHORITY;
head -> arcount = NO_RESOURCE_RECORDS_IN_ADDITIONAL;
return head;
};

int count_words(char* string) {
int word_counter = 1;
int i;
for(i = 0; i < strlen(string); i++){
if (string[i] == '.') {
word_counter++;
}
}
return word_counter;
};

char** split_by_period(char* string) {
int word_count = count_words(string);
char **words = malloc(word_count);

char *s = strdup(string);
char *delim = ".";

int i;
for(i=0; i < word_count; i++) {
char *word = strsep(&s, delim);
words[i] = malloc(strlen(word)+1);
strcpy(words[i], word);
}
return words;
};
12 changes: 12 additions & 0 deletions src/resolver.h
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
#include "types.h"

char* resolve(char*);

header* build_header();

void reset_counter();

int count_words(char*);

void append(char*, char);

char** split_by_period(char*);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we export these functions from resolver? Is the plan to have something in the domain outside the resolver use these methods?

25 changes: 25 additions & 0 deletions src/types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef TYPES_H
#define TYPES_H

#include <stdint.h>

typedef struct {
uint16_t id;
uint16_t qr;
uint16_t opcode;
uint16_t aa;
uint16_t tc;
uint16_t rd;
uint16_t rs;
uint16_t rcode;
uint16_t qdcount;
uint16_t ancount;
uint16_t nscount;
uint16_t arcount;
} header;

typedef struct {
header* header;
} message;

#endif
120 changes: 120 additions & 0 deletions tests/test_resolver.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,127 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "resolver.h"
#include "types.h"

void free_header(header *head) {
free(head);
}

void teardown() {
reset_counter();
}

void test_returns_ip_addr_for_domain_name() {
char* ip = resolve("www.thoughtworks.com");
char* expectedIp = "161.47.4.22";
assert_equals_str(ip, expectedIp);
}

void test_parses_string_input_to_message_creates_header_with_query() {
}

void test_build_header_for_query_sets_to_query() {
header *head = build_header();
assert_equals_int(head->qr, 0);
free_header(head);
}

void test_build_header_generates_id() {
header *header1 = build_header();
assert_equals_int(header1->id, 1);
free_header(header1);

header *header2 = build_header();
assert_equals_int(header2->id, 2);
free_header(header2);
}

void test_build_header_sets_opcode_for_standard_query() {
header *head = build_header();
assert_equals_int(head->opcode, 0);
free_header(head);
}

void test_build_header_sets_authoritative_answer_as_non_authoritative() {
header *head = build_header();
assert_equals_int(head->aa, 0);
free_header(head);
}

void test_build_header_sets_truncation_to_not_truncated() {
header *head = build_header();
assert_equals_int(head->tc, 0);
free_header(head);
}

void test_build_header_sets_recursion_desired_to_true() {
header *head = build_header();
assert_equals_int(head->rd, 1);
free_header(head);
}

void test_build_header_sets_recursion_available_to_false() {
header *head = build_header();
assert_equals_int(head->rs, 0);
free_header(head);
}

void test_build_header_sets_response_code_to_no_errors() {
header *head = build_header();
assert_equals_int(head->rcode, 0);
free_header(head);
}

void test_build_header_sets_qdcount_to_number_of_questions_asked() {
header *head = build_header();
assert_equals_int(head->qdcount, 1);
free_header(head);
}

void test_build_header_sets_qdcount_to_number_of_rrs_in_answer_section() {
header *head = build_header();
assert_equals_int(head->ancount, 0);
free_header(head);
}

void test_build_header_sets_qdcount_to_number_of_rrs_in_authority_section() {
header *head = build_header();
assert_equals_int(head->nscount, 0);
free_header(head);
}

void test_build_header_sets_qdcount_to_number_of_rrs_in_additional_section() {
header *head = build_header();
assert_equals_int(head->arcount, 0);
free_header(head);
}

void test_count_words_returns_number_of_words_separated_by_dots() {
char* test_str = "something.else.another";

int num_words = count_words(test_str);

assert_equals_int(num_words, 3);
}

void test_split_by_dot_separates_string() {
char* test_str = "something.else.another";
char *expected[] = {
"something",
"else",
"another"
};

char **words = split_by_period(test_str);

assert_equals_str(words[0], expected[0]);
assert_equals_str(words[1], expected[1]);
assert_equals_str(words[2], expected[2]);

free(words[0]);
free(words[1]);
free(words[2]);
free(words);
}