log_collection_tester.c 5.97 KB
Newer Older
1 2
/*
	belle-sip - SIP (RFC3261) library.
3
	Copyright (C) 2010  Belledonne Communications SARL
4

5 6 7 8
	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 2 of the License, or
	(at your option) any later version.
9

10 11 12 13
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
14

15 16
	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 18 19
*/

#include <stdio.h>
20 21 22 23
#ifndef __USE_XOPEN
	/*on Debian OS, time.h does declare strptime only if __USE_XOPEN is declared */
	#define __USE_XOPEN
#endif
24 25 26 27 28 29
#include <time.h>
#include "CUnit/Basic.h"
#include "linphonecore.h"
#include "private.h"
#include "liblinphone_tester.h"

30 31 32 33
#ifdef HAVE_ZLIB
#include <zlib.h>
#endif

34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90

/*getline is not available on android...*/
#ifdef ANDROID
/* This code is public domain -- Will Hartung 4/9/09 */
size_t getline(char **lineptr, size_t *n, FILE *stream) {
	char *bufptr = NULL;
	char *p = bufptr;
	size_t size;
	int c;

	if (lineptr == NULL) {
		return -1;
	}
	if (stream == NULL) {
		return -1;
	}
	if (n == NULL) {
		return -1;
	}
	bufptr = *lineptr;
	size = *n;

	c = fgetc(stream);
	if (c == EOF) {
		return -1;
	}
	if (bufptr == NULL) {
		bufptr = malloc(128);
		if (bufptr == NULL) {
			return -1;
		}
		size = 128;
	}
	p = bufptr;
	while(c != EOF) {
		if ((p - bufptr) > (size - 1)) {
			size = size + 128;
			bufptr = realloc(bufptr, size);
			if (bufptr == NULL) {
				return -1;
			}
		}
		*p++ = c;
		if (c == '\n') {
			break;
		}
		c = fgetc(stream);
	}

	*p++ = '\0';
	*lineptr = bufptr;
	*n = size;

	return p - bufptr - 1;
}
#endif

91 92 93 94 95 96 97 98 99 100 101 102 103
static LinphoneLogCollectionState old_collection_state;
void collect_init()  {
	old_collection_state = linphone_core_log_collection_enabled();
	linphone_core_set_log_collection_path(liblinphone_tester_writable_dir_prefix);
}

void collect_cleanup(LinphoneCoreManager *marie)  {
	linphone_core_manager_destroy(marie);

	linphone_core_enable_log_collection(old_collection_state);
	linphone_core_reset_log_collection();
}

104 105
LinphoneCoreManager* setup(bool_t enable_logs)  {
	LinphoneCoreManager *marie;
106 107
	int timeout = 300;

108
	collect_init();
Simon Morlat's avatar
Simon Morlat committed
109
	linphone_core_enable_log_collection(enable_logs);
110 111 112

	marie = linphone_core_manager_new( "marie_rc");
	// wait a few seconds to generate some traffic
113 114 115 116
	while (--timeout){
		// Generate some logs - error logs because we must ensure that
		// even if user did not enable logs, we will see them
		ms_error("(test error)Timeout in %d...", timeout);
117 118 119 120
	}
	return marie;
}

121 122 123 124 125 126 127 128 129
#if HAVE_ZLIB
/*returns uncompressed log file*/
FILE* gzuncompress(const char* filepath) {
		gzFile file = gzopen(filepath, "rb");
		FILE *output = NULL;
		char *newname = ms_strdup_printf("%s.txt", filepath);
		char buffer[512];
		output = fopen(newname, "w+");
		while (gzread(file, buffer, 511) > 0) {
130 131
			fputs(buffer, output);
			memset(buffer, 0, strlen(buffer));
132 133
		}

134
		CU_ASSERT_EQUAL(gzclose(file), Z_OK);
135 136 137 138 139 140 141
		ms_free(newname);

		fseek(output, 0, SEEK_SET);
		return (FILE*)output;
}
#endif

142 143
time_t check_file(LinphoneCoreManager* mgr)  {

Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
144
	time_t last_log = ms_time(NULL);
145 146
	char*    filepath = linphone_core_compress_log_collection(mgr->lc);
	time_t  time_curr = -1;
147
	uint32_t timediff = 0;
148
	FILE *file = NULL;
149

150
	CU_ASSERT_PTR_NOT_NULL(filepath);
151

152 153 154 155 156 157 158
	if (filepath != NULL) {
		int line_count = 0;
		char *line = NULL;
		size_t line_size = 256;
		struct tm tm_curr;
		time_t time_prev = -1;

159 160 161 162 163 164 165
#if HAVE_ZLIB
		// 0) if zlib is enabled, we must decompress the file first
		file = gzuncompress(filepath);
#else
		file = fopen(filepath, "r");
#endif

166 167 168 169 170
		// 1) expect to find folder name in filename path
		CU_ASSERT_PTR_NOT_NULL(strstr(filepath, liblinphone_tester_writable_dir_prefix));

		// 2) check file contents
		while (getline(&line, &line_size, file) != -1) {
171
			// a) there should be at least 25 lines
172 173 174 175 176 177 178 179 180 181 182 183
			++line_count;
			// b) logs should be ordered by date (format: 2014-11-04 15:22:12:606)
			if (strlen(line) > 24) {
				char date[24] = {'\0'};
				memcpy(date, line, 23);
				if (strptime(date, "%Y-%m-%d %H:%M:%S", &tm_curr) != NULL) {
					time_curr = mktime(&tm_curr);
					CU_ASSERT_TRUE(time_curr >= time_prev);
					time_prev = time_curr;
				}
			}
		}
184
		CU_ASSERT_TRUE(line_count > 25);
185 186 187
		free(line);
		fclose(file);
		ms_free(filepath);
188

189
		timediff = labs((long int)time_curr - (long int)last_log);
190

191 192 193 194
		CU_ASSERT_TRUE( timediff <= 1 );
		if( !(timediff <= 1) ){
			ms_error("time_curr: %ld, last_log: %ld timediff: %d", time_curr, last_log, timediff );
		}
195
	}
196 197 198 199 200 201 202
	// return latest time in file
	return time_curr;
}

static void collect_files_disabled()  {
	LinphoneCoreManager* marie = setup(FALSE);
	CU_ASSERT_PTR_NULL(linphone_core_compress_log_collection(marie->lc));
203
	collect_cleanup(marie);
204 205 206 207
}

static void collect_files_filled() {
	LinphoneCoreManager* marie = setup(TRUE);
208
	check_file(marie);
209
	collect_cleanup(marie);
210 211 212 213
}

static void collect_files_small_size()  {
	LinphoneCoreManager* marie = setup(TRUE);
214
	linphone_core_set_log_collection_max_file_size(5000);
215
	check_file(marie);
216
	collect_cleanup(marie);
217 218 219 220 221 222
}

static void collect_files_changing_size()  {
	LinphoneCoreManager* marie = setup(TRUE);
	int waiting = 100;

223
	check_file(marie);
224

225
	linphone_core_set_log_collection_max_file_size(5000);
226 227 228
	// Generate some logs
	while (--waiting) ms_error("(test error)Waiting %d...", waiting);

229
	check_file(marie);
230

231
	collect_cleanup(marie);
232 233 234 235 236 237
}

test_t log_collection_tests[] = {
	{ "No file when disabled", collect_files_disabled},
	{ "Collect files filled when enabled", collect_files_filled},
	{ "Logs collected into small file", collect_files_small_size},
238
	{ "Logs collected when decreasing max size", collect_files_changing_size},
239 240 241 242
};

test_suite_t log_collection_test_suite = {
	"LogCollection",
243 244
	NULL,
	NULL,
245 246 247 248
	sizeof(log_collection_tests) / sizeof(log_collection_tests[0]),
	log_collection_tests
};