view src/test.cpp @ 236:c0d2e99c0a1d

Add surbl checks on the smtp helo value, client reverse dns name, and mail from domain name
author Carl Byington <carl@five-ten-sg.com>
date Tue, 29 Sep 2009 11:36:15 -0700
parents 4db1457cd11a
children 5209e92b4885
line wrap: on
line source

/*

Copyright (c) 2007 Carl Byington - 510 Software Group, released under
the GPL version 3 or any later version at your choice available at
http://www.gnu.org/licenses/gpl-3.0.txt

*/

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <set>

using namespace std;

struct ltstr {
	bool operator()(char* s1, char* s2) const {
		return strcmp(s1, s2) < 0;
	}
};

typedef set<char *, ltstr>				  string_set;

static string_set all_strings;		// owns all the strings, only modified by the config loader thread

struct stats {
	bool	stop;
	bool	running;
	int 	counter;
	int 	errors;
	stats();
};
stats::stats() {
	stop	= false;
	running = false;
	counter = 0;
	errors	= 0;
}

////////////////////////////////////////////////
// helper to discard the strings held by a string_set
//
static void discard(string_set &s);
static void discard(string_set &s) {
	for (string_set::iterator i=s.begin(); i!=s.end(); i++) {
		free(*i);
	}
	s.clear();
}

////////////////////////////////////////////////
// helper to register a string in a string set
//
static char* register_string(string_set &s, char *name);
static char* register_string(string_set &s, char *name) {
	string_set::iterator i = s.find(name);
	if (i != s.end()) return *i;
	char *x = strdup(name);
	s.insert(x);
	return x;
}


////////////////////////////////////////////////
// thread tester
//
static void* tester(void *arg);
static void* tester(void *arg) {
	stats &st = *((stats *)arg);
	st.running = true;
	while (!st.stop) {
		const int LIMIT = 1000;
		string_set *mine = new string_set;
		string_set &me = *mine;
		for (int i=0; i<LIMIT; i++) {
			char buf[100];
			snprintf(buf, sizeof(buf), "this is string %d", i);
			register_string(me, buf);
		}
		for (int i=0; i<LIMIT; i+=5) {
			char buf[100];
			snprintf(buf, sizeof(buf), "this is string %d", i);
			string_set::iterator j = me.find(buf);
			if (j == me.end()) st.errors++;
		}
		discard(me);
		delete mine;
		st.counter++;
	}
	st.running = false;
	return NULL;
}

int main(int argc, char**argv)
{
	stats st1;
	stats st2;
	pthread_t tid;
	if (pthread_create(&tid, 0, tester, &st1))
		fprintf(stdout, "failed to create test thread");
	if (pthread_detach(tid))
		fprintf(stdout, "failed to detach test thread");
	if (pthread_create(&tid, 0, tester, &st2))
		fprintf(stdout, "failed to create test thread");
	if (pthread_detach(tid))
		fprintf(stdout, "failed to detach test thread");

	fprintf(stdout, "tests are running\n");
	sleep(60);
	st1.stop = true;
	st2.stop = true;
	while (st1.running || st2.running) {
		sleep(1);
	}

	fprintf(stdout, "counter 1 = %d\n", st1.counter);
	fprintf(stdout, "counter 2 = %d\n", st2.counter);
	fprintf(stdout, "errors 1 = %d\n", st1.errors);
	fprintf(stdout, "errors 2 = %d\n", st2.errors);
	return 0;
}