1. 程式人生 > >一個簡單的linux的測試修改模板

一個簡單的linux的測試修改模板

//一個簡單的linux的測試用例模板
//編譯命令 : g++ -o1 -g simple_test_template.cpp -lpthread -o simple_test.exe 

//標準c標頭檔案
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <malloc.h>
#include <time.h>
#include <errno.h>

//linux下標頭檔案
#include <unistd.h>
#include <getopt.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <arpa/inet.h>

//日誌列印級別巨集定義
#define LOG_LEVEL_FALT      (0x06)
#define LOG_LEVEL_ERROR     (0x05)
#define LOG_LEVEL_WARN      (0x04)
#define LOG_LEVEL_INFO      (0x03)
#define LOG_LEVEL_DEBUG     (0x02)
#define LOG_LEVEL_TRACE     (0x01)

//簡單的日誌列印巨集定義
#define simple_log(s,l,fmt,...)  do{ if(l >= g_Config.level) { fprintf(stderr,"[%s] "fmt"\n",s,##__VA_ARGS__); fflush(stderr);}} while (0);
#define log_falt(fmt,...)          simple_log("FALT" ,LOG_LEVEL_FALT ,fmt,##__VA_ARGS__);
#define log_error(fmt,...)         simple_log("ERROR",LOG_LEVEL_ERROR,fmt,##__VA_ARGS__);
#define log_warn(fmt,...)          simple_log("WARN" ,LOG_LEVEL_WARN ,fmt,##__VA_ARGS__);
#define log_info(fmt,...)          simple_log("INFO" ,LOG_LEVEL_INFO ,fmt,##__VA_ARGS__);
#define log_debug(fmt,...)         simple_log("DEBUG",LOG_LEVEL_DEBUG,fmt,##__VA_ARGS__);
#define log_trace(fmt,...)         simple_log("TRACE",LOG_LEVEL_TRACE,fmt,##__VA_ARGS__);

//函式前置宣告
int64_t getS();
int64_t getMS();
int64_t getUS();

//一些執行時的配置資訊,大多數可以由命令列設定
struct GCONFIG
{
	GCONFIG()
	{
		show_args = false;
		level     = LOG_LEVEL_INFO;
		run_time  = -1;
	}

	//當前程式是否可以執行
	bool isRun()
	{
		return run_time <= 0 || getS() < run_time;
	}

	//顯示main的命令列引數
	bool show_args; 
	//log列印級別
	int  level;
	//程式執行時間,不大於0表示永久執行,單位s
	int  run_time;
};

//配置
GCONFIG g_Config;

//全域性的時間變數資訊,用於獲取程式執行時間,由單獨的執行緒更新
static volatile int64_t g_time_us = -1;
static volatile int64_t g_time_s  = -1;
static volatile int64_t g_time_ms = -1;

//獲取程式開始到目前執行的時間,單位s
inline int64_t getS()
{
	return g_time_s;
}

//獲取程式開始到目前的執行時間,單位us
inline int64_t getUS()
{
	return g_time_us;
}

//獲取程式開始到目前的執行時間,單位ms
inline int64_t getMS()
{
	return getUS() / 1000;
}

//更新時間資訊的執行緒
void *update_runtime_thread(void *para)
{
	static bool bFirst = true;
	static time_t first_time_s = -1;
	static struct timeval first_tv;
	int ret = 0;
	if (bFirst)
	{
		first_time_s = time(NULL);
		ret = gettimeofday(&first_tv, NULL);
		if (-1 == ret)
		{
			log_falt("[getUS] gettimeofday failed,errno=%d", errno);
			exit(0);
		}
		bFirst = false;
	}

	struct timeval now_tv;
	time_t now_time_s = -1;
	while (g_Config.isRun())
	{
		ret = gettimeofday(&now_tv, NULL);
		if (-1 == ret)
		{
			log_falt("[getUS] gettimeofday failed,errno=%d", errno);
			exit(0);
		}

		now_time_s = time(NULL);

		g_time_us = (now_tv.tv_sec * 1000000 + now_tv.tv_usec) - (first_tv.tv_sec * 1000000 + first_tv.tv_usec);
		g_time_s = now_time_s - first_time_s;

		//sleep
		usleep(100);
	}
}

//啟動更新時間資訊的執行緒
void startTimer()
{
	pthread_t pid;
	int ret = pthread_create(&pid, NULL,&update_runtime_thread, NULL);
	if (ret == 0)
	{
		log_info("[startTimer] success.")
	}
	else
	{
		log_error("[startTimer] failed,errno = %d.",errno);
	}
}

//usage
void usage()
{
	fprintf(stderr, "==============================================================\n");
	fprintf(stderr, "simple_test_template version=0.0.1,create by wangzhang 2017/03/23 09:30\n");
	fprintf(stderr, "usage:\n");
	fprintf(stderr, "\t -h[--help]\n");
	fprintf(stderr, "\t -v[--version]\n");
	fprintf(stderr, "\t -l[--level]           set log level\n");
	fprintf(stderr, "\t -s[--show_args]       show main args\n");
	fprintf(stderr, "\t -r[--runtime]         set program run time\n");
	fprintf(stderr, "==============================================================\n");
}

//初始化解析命令列引數
void init_para(int argc, char *argv[])
{
	if (argc <= 1)
	{
		usage();
		exit(0);
	}

	static struct option long_options[] = {
		{ "level",     required_argument, NULL, 'l' },
		{ "show_args", no_argument,       NULL, 's' },
		{ "runtime",   required_argument, NULL, 'r' },
		{ "help",      no_argument,       NULL, 'h' },
		{ "version",   no_argument,       NULL, 'v' },
		{ NULL, 0, NULL, 0 }
	};

	int  ch = 0;
	// 
	while ((ch = getopt_long(argc, argv, "l:sr:hv", long_options, NULL)) != -1)
	{
		fprintf(stderr, "optind=%d optarg=%s argv[%d]=%s\n", optind, optarg, optind, argv[optind]);

		switch (ch)
		{
		case 'h':
		case 'v':
		{
			usage();
			exit(0);
		}
		break;
		case 'l':
		{
			g_Config.level = atoi(optarg);
		}
		break;
		case 's':
		{
			g_Config.show_args = true;
		}
		break;
		case 'r':
		{
			g_Config.run_time = atoi(optarg);
		}
		break;
		default: 
		{
			exit(0); 
		}
		}
	}

	return ;
}

//主函式
int main(int argc,char *argv[])
{
	//引數解析
	init_para(argc, argv);
	
	//啟動更新時間執行緒
	startTimer();

	//顯示main引數
	if (g_Config.show_args)
	{//
		log_info("argc=%d", argc);
		for (int idx = 0; idx < argc; ++idx)
		{
			log_info("argv[%d]=%s", idx, argv[idx]);
		}
	}

	//新增測試程式碼

	//主執行緒
	while (g_Config.isRun())
	{
		log_info("man thread running, escape(ms) = %lld", getMS());
		//sleep one sesond
		usleep(1000000);
	}

	log_info("[main] end.total run time(s) = %lld", getS());

	return 0;
}