[PATCH 2 of 5 c-hglib 🐮 ] Add test for hg_read_header

Giovanni Gherdovich g.gherdovich at gmail.com
Thu Nov 6 18:28:25 CST 2014


# HG changeset patch
# User Giovanni Gherdovich <g.gherdovich at gmail.com>
# Date 1413013112 -7200
#      Sat Oct 11 09:38:32 2014 +0200
# Node ID a61825bf20a7e8924e950bba9f1120904dbbb865
# Parent  0e3aafee43ea6cacff9bc8ac5c71657985e4b22b
Add test for hg_read_header

Where hg_read_header would expect input and output pipes
connected to stdin and stdout of a command server process,
we give it pipes that simulates some command server's behaviour:

the test writes the header ('o', 42) (42 bytes are coming on channel 'output')
and checks that hg_read_header gets that correctly.

Consider this as a demo test for the "Greatest" framework:
it shows we can test basic behaviour of a "read" function
in the c-hglib API.

diff -r 0e3aafee43ea -r a61825bf20a7 Makefile
--- a/Makefile	Sat Oct 11 12:12:27 2014 +0200
+++ b/Makefile	Sat Oct 11 09:38:32 2014 +0200
@@ -16,6 +16,9 @@
 HGLIB_DIR_PATH = ./hglib
 EXAMPLES_DIR_PATH = ./examples
 
+TESTS_DIR_PATH = ./tests
+TEST_TARGET = $(TESTS_DIR_PATH)/test_runner
+TEST_FILES = $(TESTS_DIR_PATH)/tests_level0.c
 
 # Build Target
 ##############
@@ -29,6 +32,7 @@
 	@echo '  build        - build the shared library in the local directory'
 	@echo '  install      - install the shared library to PREFIX ($(SHARED_LIB_PATH))'
 	@echo '  examples     - build example executable'
+	@echo '  tests        - build unit tests'
 	@echo '  clean        - remove files created by other targets'
 	@echo '  uninstall    - uninstall the shared library'
 
@@ -61,13 +65,25 @@
 examples/%.o: examples/%.c
 	$(CC) $(CFLAGS) -c $< -o $@ -I$(HGLIB_DIR_PATH)
 
+# Tests
+#######
+
+tests: build buildtests
+buildtests: $(TEST_TARGET).o $(TEST_FILES:c=o)
+	$(CC) $(CFLAGS) $^ -o $(TEST_TARGET) -l$(SHARED_LIBRARY) -L.
+$(TESTS_DIR_PATH)/%.o: $(TESTS_DIR_PATH)/%.c
+	$(CC) $(CFLAGS) -c $^ -o $(^:c=o) -I$(HGLIB_DIR_PATH) -I$(TESTS_DIR_PATH)
 
 # Clean
 #######
-clean: cleanex cleanhg
+clean: cleantests cleanex cleanhg
 	rm -f *.o *~
 	rm -f lib$(SHARED_LIBRARY).so
 
+cleantests:
+	rm -f $(TESTS_DIR_PATH)/*.o $(TESTS_DIR_PATH)/*~
+	rm -f $(TEST_TARGET)
+
 cleanex:
 	rm -f $(EXAMPLES_DIR_PATH)/*.o $(EXAMPLES_DIR_PATH)/*~
 	rm -f $(EXAMPLES_TARGETS)
@@ -75,4 +91,4 @@
 cleanhg:
 	rm -f $(HGLIB_DIR_PATH)/*.o $(HGLIB_DIR_PATH)/*~
 
-.PHONY: build clean install uninstall examples
+.PHONY: build clean install uninstall examples tests
diff -r 0e3aafee43ea -r a61825bf20a7 tests/test_runner.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test_runner.c	Sat Oct 11 09:38:32 2014 +0200
@@ -0,0 +1,12 @@
+#include "greatest.h"
+
+extern SUITE(hg_level0_tests);
+
+GREATEST_MAIN_DEFS();
+
+int main(int argc, char **argv) {
+	GREATEST_MAIN_BEGIN();
+	RUN_SUITE(hg_level0_tests);
+	GREATEST_MAIN_END();
+}
+
diff -r 0e3aafee43ea -r a61825bf20a7 tests/tests_level0.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/tests_level0.c	Sat Oct 11 09:38:32 2014 +0200
@@ -0,0 +1,77 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "greatest.h"
+#include "client.h"
+#include "utils.h"
+
+typedef struct test_environment {
+	int setup_error;
+	int wpipe[2];
+	int rpipe[2];
+	hg_handle *handle;
+} test_environment;
+
+SUITE(hg_level0_tests);
+
+TEST hg_read_header_ok(test_environment *e) {
+	uint32_t length = 42;
+	uint32_t length_bigendian = swap_uint32(length);
+	char channel = 'o';
+	char payload[] = "This data will be ignored. Only the header is read.";
+
+	if (e->setup_error != 0) {
+		FAILm("Error reported by the setup callback.");
+	}
+
+	if (write(e->rpipe[1], &channel, 1) < 0) {
+		FAILm("Error writing on c-hglib's input pipe.");
+	}
+	if (write(e->rpipe[1], &length_bigendian, sizeof(length)) < 0) {
+		FAILm("Error writing on c-hglib's input pipe.");
+	}
+	if (write(e->rpipe[1], &payload, 51) < 0) {
+		FAILm("Error writing on c-hglib's input pipe.");
+	}
+
+	if (hg_read_header(e->handle) == NULL) {
+		FAILm("hg_read_header returned NULL.");
+	}
+
+	ASSERT_EQ(length, e->handle->header->length);
+	ASSERT_EQ(channel, e->handle->header->channel);
+	PASS();
+}
+
+static void setup_cb(void *data) {
+	test_environment *e = (test_environment *)data;
+	e->setup_error = 0;
+	e->handle = malloc(sizeof(hg_handle));
+	e->handle->header = malloc(sizeof(hg_header));
+
+	if (pipe(e->wpipe) < 0 || pipe(e->rpipe) < 0) {
+		e->setup_error = 1;
+	}
+
+	e->handle->bytes_on_pipe = 0;
+	e->handle->p_read = e->rpipe[0];
+	e->handle->p_write = e->wpipe[1];
+	e->handle->protect = 0;
+	e->handle->out_data_size = 0;
+	e->handle->out_data = NULL;
+}
+
+static void teardown_cb(void *data) {
+	test_environment *e = (test_environment *)data;
+	hg_close(&(e->handle));
+}
+
+SUITE(hg_level0_tests) {
+	test_environment *environment = malloc(sizeof(test_environment));
+	SET_SETUP(setup_cb, environment);
+	SET_TEARDOWN(teardown_cb, environment);
+	RUN_TEST1(hg_read_header_ok, environment);
+}


More information about the Mercurial-devel mailing list