This commit is contained in:
Daniel Graziotin 2012-06-16 11:02:48 +02:00
parent a6cc7a45b6
commit 1078814133
8 changed files with 550 additions and 336 deletions

View file

@ -24,6 +24,11 @@ Compile with
Manually compile with Manually compile with
gcc -o bin/mbpfan src/mbpfan.c -lm gcc -o bin/mbpfan src/mbpfan.c -lm
Run The Tests (Recommended)
---------------------------
It is recommended to run the tests before installing the program
sudo ./bin/mbpfan -t
Install Instructions Install Instructions
-------------------- --------------------

View file

@ -29,150 +29,177 @@
#include "mbpfan.h" #include "mbpfan.h"
#include "global.h" #include "global.h"
int write_pid(int pid){ int write_pid(int pid)
FILE *file = NULL; {
file = fopen(program_pid, "w"); FILE *file = NULL;
if(file != NULL) { file = fopen(program_pid, "w");
fprintf(file, "%d", pid); if(file != NULL)
fclose(file); {
return 1; fprintf(file, "%d", pid);
}else{ fclose(file);
return 0; return 1;
} }
else
{
return 0;
}
} }
int read_pid(){ int read_pid()
FILE *file = NULL; {
int pid = -1; FILE *file = NULL;
file = fopen(program_pid, "r"); int pid = -1;
if(file != NULL) { file = fopen(program_pid, "r");
fscanf(file, "%d", &pid); if(file != NULL)
fclose(file); {
return pid; fscanf(file, "%d", &pid);
} fclose(file);
return -1; return pid;
}
return -1;
} }
int delete_pid(){ int delete_pid()
return remove(program_pid); {
return remove(program_pid);
} }
void signal_handler(int signal) void signal_handler(int signal)
{ {
switch(signal) { switch(signal)
case SIGHUP: {
//TODO: restart myself case SIGHUP:
syslog(LOG_WARNING, "Received SIGHUP signal."); //TODO: restart myself
delete_pid(); syslog(LOG_WARNING, "Received SIGHUP signal.");
exit(0); delete_pid();
break; exit(0);
case SIGTERM: break;
syslog(LOG_WARNING, "Received SIGTERM signal."); case SIGTERM:
delete_pid(); syslog(LOG_WARNING, "Received SIGTERM signal.");
//TODO: free resources delete_pid();
exit(0); //TODO: free resources
break; exit(0);
case SIGINT: break;
syslog(LOG_WARNING, "Received SIGINT signal."); case SIGINT:
delete_pid(); syslog(LOG_WARNING, "Received SIGINT signal.");
//TODO: free resources delete_pid();
exit(0); //TODO: free resources
default: exit(0);
syslog(LOG_WARNING, "Unhandled signal (%d) %s", signal, strsignal(signal)); default:
break; syslog(LOG_WARNING, "Unhandled signal (%d) %s", signal, strsignal(signal));
} break;
}
} }
void go_daemon(void (*fan_control)()) void go_daemon(void (*fan_control)())
{ {
// Setup signal handling before we start // Setup signal handling before we start
signal(SIGHUP, signal_handler); signal(SIGHUP, signal_handler);
signal(SIGTERM, signal_handler); signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler); signal(SIGINT, signal_handler);
syslog(LOG_INFO, "%s starting up", program_name); syslog(LOG_INFO, "%s starting up", program_name);
// Setup syslog logging - see SETLOGMASK(3) // Setup syslog logging - see SETLOGMASK(3)
if(verbose) { if(verbose)
setlogmask(LOG_UPTO(LOG_DEBUG)); {
openlog(program_name, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER); setlogmask(LOG_UPTO(LOG_DEBUG));
} else { openlog(program_name, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
setlogmask(LOG_UPTO(LOG_INFO)); }
openlog(program_name, LOG_CONS, LOG_USER); else
{
setlogmask(LOG_UPTO(LOG_INFO));
openlog(program_name, LOG_CONS, LOG_USER);
}
pid_t pid_slave;
pid_t sid_slave;
if (daemonize)
{
pid_slave = fork();
if (pid_slave < 0)
{
exit(EXIT_FAILURE);
}
if (pid_slave > 0)
{
// kill the father
exit(EXIT_SUCCESS);
}
umask(0022);
// new sid_slave for the child process
sid_slave = setsid();
if (sid_slave < 0)
{
exit(EXIT_FAILURE);
}
if ((chdir("/")) < 0)
{
exit(EXIT_FAILURE);
} }
pid_t pid_slave;
pid_t sid_slave;
if (daemonize) { /* Close out the standard file descriptors */
close(STDIN_FILENO);
pid_slave = fork(); close(STDOUT_FILENO);
if (pid_slave < 0) { close(STDERR_FILENO);
exit(EXIT_FAILURE); }
}
if (pid_slave > 0) {
// kill the father
exit(EXIT_SUCCESS);
}
umask(0022);
// new sid_slave for the child process
sid_slave = setsid();
if (sid_slave < 0) {
exit(EXIT_FAILURE);
}
if ((chdir("/")) < 0) {
exit(EXIT_FAILURE);
}
int current_pid = getpid();
/* Close out the standard file descriptors */ if (read_pid() == -1)
close(STDIN_FILENO); {
close(STDOUT_FILENO); if (verbose)
close(STDERR_FILENO); {
printf("Writing a new .pid file with value %d at: %s", current_pid, program_pid);
syslog(LOG_INFO, "Writing a new .pid file with value %d at: %s", current_pid, program_pid);
} }
if (write_pid(current_pid) == 0)
{
int current_pid = getpid(); syslog(LOG_ERR, "Can not create a .pid file at: %s. Aborting", program_pid);
if (verbose)
if (read_pid() == -1){ {
if (verbose){ printf("ERROR: Can not create a .pid file at: %s. Aborting", program_pid);
printf("Writing a new .pid file with value %d at: %s", current_pid, program_pid); }
syslog(LOG_INFO, "Writing a new .pid file with value %d at: %s", current_pid, program_pid); exit(EXIT_FAILURE);
}
if (write_pid(current_pid) == 0){
syslog(LOG_ERR, "Can not create a .pid file at: %s. Aborting", program_pid);
if (verbose){
printf("ERROR: Can not create a .pid file at: %s. Aborting", program_pid);
}
exit(EXIT_FAILURE);
}else{
if (verbose){
printf("Successfully written a new .pid file with value %d at: %s", current_pid, program_pid);
syslog(LOG_INFO, "Successfully written a new .pid file with value %d at: %s", current_pid, program_pid);
}
}
}else{
syslog(LOG_ERR, "A previously created .pid file exists at: %s. Aborting", program_pid);
if (verbose){
printf("ERROR: a previously created .pid file exists at: %s.\n Aborting\n", program_pid);
}
exit(EXIT_FAILURE);
} }
else
{
fan_control(); if (verbose)
{
if(daemonize){ printf("Successfully written a new .pid file with value %d at: %s", current_pid, program_pid);
syslog(LOG_INFO, "%s daemon exiting", program_name); syslog(LOG_INFO, "Successfully written a new .pid file with value %d at: %s", current_pid, program_pid);
}
} }
}
else
{
syslog(LOG_ERR, "A previously created .pid file exists at: %s. Aborting", program_pid);
if (verbose)
{
printf("ERROR: a previously created .pid file exists at: %s.\n Aborting\n", program_pid);
}
exit(EXIT_FAILURE);
}
return;
fan_control();
if(daemonize)
{
syslog(LOG_INFO, "%s daemon exiting", program_name);
}
return;
} }

View file

@ -36,7 +36,7 @@ int read_pid();
* Return TRUE on success * Return TRUE on success
* Return FALSE otherwise * Return FALSE otherwise
*/ */
int delete_pid(); int delete_pid();
/** /**
* ...handles signals :-) * ...handles signals :-)

View file

@ -19,6 +19,7 @@
#include "mbpfan.h" #include "mbpfan.h"
#include "daemon.h" #include "daemon.h"
#include "global.h" #include "global.h"
#include "minunit.h"
int daemonize = 1; int daemonize = 1;
int verbose = 0; int verbose = 0;
@ -28,41 +29,51 @@ const char *program_pid = "/var/run/mbpfan.pid";
void print_usage(int argc, char *argv[]) void print_usage(int argc, char *argv[])
{ {
if (argc >=1) { if (argc >=1)
printf("Usage: %s OPTION(S) \n", argv[0]); {
printf("Options:\n"); printf("Usage: %s OPTION(S) \n", argv[0]);
printf("\t-h Show this help screen\n"); printf("Options:\n");
printf("\t-f Run in foreground\n"); printf("\t-h Show this help screen\n");
printf("\t-v Be (a lot) verbose\n"); printf("\t-f Run in foreground\n");
printf("\n"); printf("\t-t Run the tests\n");
} printf("\t-v Be (a lot) verbose\n");
printf("\n");
}
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int c; int c;
while( (c = getopt(argc, argv, "hfv|help")) != -1) { while( (c = getopt(argc, argv, "hftv|help")) != -1)
switch(c) { {
case 'h': switch(c)
print_usage(argc, argv); {
exit(0); case 'h':
break; print_usage(argc, argv);
case 'f': exit(0);
daemonize = 0; break;
break; case 'f':
case 'v': daemonize = 0;
verbose = 1; break;
break; case 't':
default: tests();
print_usage(argc, argv); exit(0);
exit(0); break;
break; case 'v':
} verbose = 1;
break;
default:
print_usage(argc, argv);
exit(0);
break;
} }
}
// pointer to mbpfan() function in mbpfan.c // pointer to mbpfan() function in mbpfan.c
void (*fan_control)() = mbpfan; void (*fan_control)() = mbpfan;
go_daemon(fan_control); go_daemon(fan_control);
exit(0); exit(0);
} }

View file

@ -55,161 +55,177 @@ int max_temp = 86; // do not set it > 90
int polling_interval = 7; int polling_interval = 7;
struct s_sensors { struct s_sensors
char* path; {
char* fan_min_path; char* path;
char* fan_man_path; char* fan_min_path;
unsigned int temperature; char* fan_man_path;
struct s_sensors *next; unsigned int temperature;
struct s_sensors *next;
}; };
t_sensors *retrieve_sensors() t_sensors *retrieve_sensors()
{ {
t_sensors *sensors_head = NULL; t_sensors *sensors_head = NULL;
t_sensors *s = NULL; t_sensors *s = NULL;
char *path = NULL; char *path = NULL;
const char *path_begin = "/sys/devices/platform/coretemp.0/temp"; const char *path_begin = "/sys/devices/platform/coretemp.0/temp";
const char *path_end = "_input"; const char *path_end = "_input";
int path_size = strlen(path_begin) + strlen(path_end) + 2; int path_size = strlen(path_begin) + strlen(path_end) + 2;
char number[1]; char number[1];
sprintf(number,"%d",0); sprintf(number,"%d",0);
int i = 0; int i = 0;
for(i = 0; i<10; i++) { for(i = 0; i<10; i++)
path = (char*) malloc(sizeof( char ) * path_size); {
path = (char*) malloc(sizeof( char ) * path_size);
sprintf(number,"%d",i); sprintf(number,"%d",i);
path[0] = '\0'; path[0] = '\0';
strncat( path, path_begin, strlen(path_begin) ); strncat( path, path_begin, strlen(path_begin) );
strncat( path, number, strlen(number) ); strncat( path, number, strlen(number) );
strncat( path, path_end, strlen(path_begin) ); strncat( path, path_end, strlen(path_begin) );
FILE *file = fopen(path, "r"); FILE *file = fopen(path, "r");
if(file != NULL) { if(file != NULL)
s = (t_sensors *) malloc( sizeof( t_sensors ) ); {
s->path = (char *) malloc(sizeof( char ) * path_size); s = (t_sensors *) malloc( sizeof( t_sensors ) );
strcpy(s->path, path); s->path = (char *) malloc(sizeof( char ) * path_size);
fscanf(file, "%d", &s->temperature); strcpy(s->path, path);
if (sensors_head == NULL) { fscanf(file, "%d", &s->temperature);
sensors_head = s; if (sensors_head == NULL)
sensors_head->next = NULL; {
} else { sensors_head = s;
t_sensors *tmp = sensors_head; sensors_head->next = NULL;
while (tmp->next != NULL) { }
tmp = tmp->next; else
} {
tmp->next = s; t_sensors *tmp = sensors_head;
tmp->next->next = NULL; while (tmp->next != NULL)
} {
fclose(file); tmp = tmp->next;
} }
free(path); tmp->next = s;
path = NULL; tmp->next->next = NULL;
}
fclose(file);
} }
if(sensors_head != NULL) free(path);
find_fans(sensors_head); path = NULL;
return sensors_head; }
if(sensors_head != NULL)
find_fans(sensors_head);
return sensors_head;
} }
void find_fans(t_sensors* sensors) void find_fans(t_sensors* sensors)
{ {
t_sensors *tmp = sensors; t_sensors *tmp = sensors;
char *path_min = NULL; char *path_min = NULL;
char *path_man = NULL; char *path_man = NULL;
const char *path_begin = "/sys/devices/platform/applesmc.768/fan"; const char *path_begin = "/sys/devices/platform/applesmc.768/fan";
const char *path_min_end = "_min"; const char *path_min_end = "_min";
const char *path_man_end = "_manual"; const char *path_man_end = "_manual";
int path_min_size = strlen(path_begin) + strlen(path_min_end) + 2; int path_min_size = strlen(path_begin) + strlen(path_min_end) + 2;
int path_man_size = strlen(path_begin) + strlen(path_man_end) + 2; int path_man_size = strlen(path_begin) + strlen(path_man_end) + 2;
char number[1]; char number[1];
sprintf(number,"%d",0); sprintf(number,"%d",0);
int n_sensors = 0; int n_sensors = 0;
int n_fans = 0; int n_fans = 0;
for(n_sensors = 0; n_sensors<10; n_sensors++) { for(n_sensors = 0; n_sensors<10; n_sensors++)
path_min = (char*) malloc(sizeof( char ) * path_min_size); {
path_min[0] = '\0'; path_min = (char*) malloc(sizeof( char ) * path_min_size);
path_man = (char*) malloc(sizeof( char ) * path_man_size); path_min[0] = '\0';
path_man[0] = '\0'; path_man = (char*) malloc(sizeof( char ) * path_man_size);
sprintf(number,"%d",n_sensors); path_man[0] = '\0';
sprintf(number,"%d",n_sensors);
strncat( path_min, path_begin, strlen(path_begin) ); strncat( path_min, path_begin, strlen(path_begin) );
strncat( path_min, number, strlen(number) ); strncat( path_min, number, strlen(number) );
strncat( path_min, path_min_end, strlen(path_begin) ); strncat( path_min, path_min_end, strlen(path_begin) );
strncat( path_man, path_begin, strlen(path_begin) ); strncat( path_man, path_begin, strlen(path_begin) );
strncat( path_man, number, strlen(number) ); strncat( path_man, number, strlen(number) );
strncat( path_man, path_man_end, strlen(path_begin) ); strncat( path_man, path_man_end, strlen(path_begin) );
FILE *file = fopen(path_min, "r"); FILE *file = fopen(path_min, "r");
if(file != NULL) { if(file != NULL)
if (tmp->path != NULL) { {
tmp->fan_min_path = (char *) malloc(sizeof( char ) * path_min_size); if (tmp->path != NULL)
tmp->fan_man_path = (char *) malloc(sizeof( char ) * path_man_size); {
} tmp->fan_min_path = (char *) malloc(sizeof( char ) * path_min_size);
strcpy(tmp->fan_min_path, path_min); tmp->fan_man_path = (char *) malloc(sizeof( char ) * path_man_size);
strcpy(tmp->fan_man_path, path_man); }
tmp = tmp->next; strcpy(tmp->fan_min_path, path_min);
n_fans++; strcpy(tmp->fan_man_path, path_man);
fclose(file); tmp = tmp->next;
} n_fans++;
fclose(file);
} }
}
if(verbose) { if(verbose)
printf("Found %d: sensors and %d fans\n", n_sensors, n_fans); {
if(daemonize) { printf("Found %d: sensors and %d fans\n", n_sensors, n_fans);
syslog(LOG_INFO, "Found %d: sensors and %d fans", n_sensors, n_fans); if(daemonize)
} {
syslog(LOG_INFO, "Found %d: sensors and %d fans", n_sensors, n_fans);
} }
}
free(path_min); free(path_min);
path_min = NULL; path_min = NULL;
free(path_man); free(path_man);
path_man = NULL; path_man = NULL;
} }
void set_fans_man(t_sensors *sensors) void set_fans_man(t_sensors *sensors)
{ {
t_sensors *tmp = sensors; t_sensors *tmp = sensors;
FILE *file; FILE *file;
while(tmp != NULL) { while(tmp != NULL)
file = fopen(tmp->fan_man_path, "rw+"); {
if(file != NULL) { file = fopen(tmp->fan_man_path, "rw+");
fprintf(file, "%d", 0); if(file != NULL)
fclose(file); {
} fprintf(file, "%d", 0);
tmp = tmp->next; fclose(file);
} }
tmp = tmp->next;
}
} }
t_sensors *refresh_sensors(t_sensors *sensors) t_sensors *refresh_sensors(t_sensors *sensors)
{ {
t_sensors *tmp = sensors; t_sensors *tmp = sensors;
while(tmp != NULL) { while(tmp != NULL)
FILE *file = fopen(tmp->path, "r"); {
FILE *file = fopen(tmp->path, "r");
if(file != NULL) { if(file != NULL)
fscanf(file, "%d", &tmp->temperature); {
fclose(file); fscanf(file, "%d", &tmp->temperature);
} fclose(file);
tmp = tmp->next;
} }
return sensors;
tmp = tmp->next;
}
return sensors;
} }
@ -217,18 +233,20 @@ t_sensors *refresh_sensors(t_sensors *sensors)
/* Controls the speed of the fan */ /* Controls the speed of the fan */
void set_fan_speed(t_sensors* sensors, int speed) void set_fan_speed(t_sensors* sensors, int speed)
{ {
t_sensors *tmp = sensors; t_sensors *tmp = sensors;
FILE *file; FILE *file;
while(tmp != NULL) { while(tmp != NULL)
file = fopen(tmp->fan_min_path, "rw+"); {
if(file != NULL) { file = fopen(tmp->fan_min_path, "rw+");
fprintf(file, "%d", speed); if(file != NULL)
fclose(file); {
} fprintf(file, "%d", speed);
fclose(file);
tmp = tmp->next;
} }
tmp = tmp->next;
}
} }
@ -236,85 +254,97 @@ void set_fan_speed(t_sensors* sensors, int speed)
/* Returns average CPU temp in degrees (ceiling) */ /* Returns average CPU temp in degrees (ceiling) */
unsigned short get_temp(t_sensors* sensors) unsigned short get_temp(t_sensors* sensors)
{ {
sensors = refresh_sensors(sensors); sensors = refresh_sensors(sensors);
int sum_temp = 0; int sum_temp = 0;
unsigned short temp = 0; unsigned short temp = 0;
t_sensors* tmp = sensors; t_sensors* tmp = sensors;
while(tmp != NULL) { while(tmp != NULL)
sum_temp += tmp->temperature; {
tmp = tmp->next; sum_temp += tmp->temperature;
} tmp = tmp->next;
temp = (unsigned short)( ceil( (float)( sum_temp ) / 2000. ) ); }
return temp; temp = (unsigned short)( ceil( (float)( sum_temp ) / 2000. ) );
return temp;
} }
void mbpfan() void mbpfan()
{ {
int old_temp, new_temp, fan_speed, steps; int old_temp, new_temp, fan_speed, steps;
int temp_change; int temp_change;
int step_up, step_down; int step_up, step_down;
t_sensors* sensors = retrieve_sensors(); t_sensors* sensors = retrieve_sensors();
set_fans_man(sensors); set_fans_man(sensors);
new_temp = get_temp(sensors); new_temp = get_temp(sensors);
fan_speed = 2000; fan_speed = 2000;
set_fan_speed(sensors, fan_speed); set_fan_speed(sensors, fan_speed);
if(verbose) { if(verbose)
printf("Sleeping for %d seconds\n", polling_interval); {
if(daemonize) { printf("Sleeping for %d seconds\n", polling_interval);
syslog(LOG_INFO, "Sleeping for %d seconds\n", polling_interval); if(daemonize)
} {
syslog(LOG_INFO, "Sleeping for %d seconds\n", polling_interval);
} }
sleep(polling_interval); }
sleep(polling_interval);
step_up = (float)( max_fan_speed - min_fan_speed ) / step_up = (float)( max_fan_speed - min_fan_speed ) /
(float)( ( max_temp - high_temp ) * ( max_temp - high_temp + 1 ) / 2 ); (float)( ( max_temp - high_temp ) * ( max_temp - high_temp + 1 ) / 2 );
step_down = (float)( max_fan_speed - min_fan_speed ) / step_down = (float)( max_fan_speed - min_fan_speed ) /
(float)( ( max_temp - low_temp ) * ( max_temp - low_temp + 1 ) / 2 ); (float)( ( max_temp - low_temp ) * ( max_temp - low_temp + 1 ) / 2 );
while(1) { while(1)
old_temp = new_temp; {
new_temp = get_temp(sensors); old_temp = new_temp;
new_temp = get_temp(sensors);
if(new_temp >= max_temp && fan_speed != max_fan_speed) { if(new_temp >= max_temp && fan_speed != max_fan_speed)
fan_speed = max_fan_speed; {
} fan_speed = max_fan_speed;
if(new_temp <= low_temp && fan_speed != min_fan_speed) {
fan_speed = min_fan_speed;
}
temp_change = new_temp - old_temp;
if(temp_change > 0 && new_temp > high_temp && new_temp < max_temp) {
steps = ( new_temp - high_temp ) * ( new_temp - high_temp + 1 ) / 2;
fan_speed = max( fan_speed, ceil(min_fan_speed + steps * step_up) );
}
if(temp_change < 0 && new_temp > low_temp && new_temp < max_temp) {
steps = ( max_temp - new_temp ) * ( max_temp - new_temp + 1 ) / 2;
fan_speed = min( fan_speed, floor(max_fan_speed - steps * step_down) );
}
if(verbose) {
printf("Old Temp %d: New Temp: %d, Fan Speed: %d\n", old_temp, new_temp, fan_speed);
if(daemonize) {
syslog(LOG_INFO, "Old Temp %d: New Temp: %d, Fan Speed: %d\n", old_temp, new_temp, fan_speed);
}
}
set_fan_speed(sensors, fan_speed);
if(verbose) {
printf("Sleeping for %d seconds\n", polling_interval);
if(daemonize) {
syslog(LOG_INFO, "Sleeping for %d seconds\n", polling_interval);
}
}
sleep(polling_interval);
} }
if(new_temp <= low_temp && fan_speed != min_fan_speed)
{
fan_speed = min_fan_speed;
}
temp_change = new_temp - old_temp;
if(temp_change > 0 && new_temp > high_temp && new_temp < max_temp)
{
steps = ( new_temp - high_temp ) * ( new_temp - high_temp + 1 ) / 2;
fan_speed = max( fan_speed, ceil(min_fan_speed + steps * step_up) );
}
if(temp_change < 0 && new_temp > low_temp && new_temp < max_temp)
{
steps = ( max_temp - new_temp ) * ( max_temp - new_temp + 1 ) / 2;
fan_speed = min( fan_speed, floor(max_fan_speed - steps * step_down) );
}
if(verbose)
{
printf("Old Temp %d: New Temp: %d, Fan Speed: %d\n", old_temp, new_temp, fan_speed);
if(daemonize)
{
syslog(LOG_INFO, "Old Temp %d: New Temp: %d, Fan Speed: %d\n", old_temp, new_temp, fan_speed);
}
}
set_fan_speed(sensors, fan_speed);
if(verbose)
{
printf("Sleeping for %d seconds\n", polling_interval);
if(daemonize)
{
syslog(LOG_INFO, "Sleeping for %d seconds\n", polling_interval);
}
}
sleep(polling_interval);
}
} }

View file

@ -61,6 +61,11 @@ void find_fans(t_sensors *sensors);
*/ */
void set_fans_man(t_sensors *sensors); void set_fans_man(t_sensors *sensors);
/**
* Return average CPU temp in degrees (ceiling)
*/
unsigned short get_temp(t_sensors* sensors);
/** /**
* Main Program * Main Program
*/ */

120
src/minunit.c Normal file
View file

@ -0,0 +1,120 @@
/* file minunit_example.c */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>
#include "mbpfan.h"
#include "minunit.h"
int tests_run = 0;
struct s_sensors
{
char* path;
char* fan_min_path;
char* fan_man_path;
unsigned int temperature;
struct s_sensors *next;
};
typedef s_sensors t_sensors;
static char *test_sensor_paths()
{
t_sensors* sensors = retrieve_sensors();
mu_assert("No sensors found", sensors != NULL);
t_sensors* tmp = sensors;
while(tmp != NULL)
{
mu_assert("Sensor does not have a valid path", tmp->path != NULL);
if(tmp->path != NULL)
mu_assert("Sensor does not have valid temperature", tmp->temperature > 0);
tmp = tmp->next;
}
return 0;
}
static char *test_fan_paths()
{
t_sensors* sensors = retrieve_sensors();
mu_assert("No sensors found", sensors != NULL);
t_sensors* tmp = sensors;
int found_fan_path = 0;
while(tmp != NULL)
{
if(tmp->fan_min_path != NULL)
found_fan_path++;
tmp = tmp->next;
}
mu_assert("No fans found", found_fan_path != 0);
return 0;
}
unsigned time_seed()
{
time_t now = time ( 0 );
unsigned char *p = (unsigned char *)&now;
unsigned seed = 0;
size_t i;
for ( i = 0; i < sizeof now; i++ )
seed = seed * ( UCHAR_MAX + 2U ) + p[i];
return seed;
}
// nothing better than a horrible piece of code to
// stress a little bit the CPU
int stress(int n)
{
int f = n;
while (f > 0)
{
while(n > 0)
{
srand ( time_seed() );
n--;
}
f--;
n = f;
}
}
static char *test_get_temp()
{
t_sensors* sensors = retrieve_sensors();
mu_assert("No sensors found", sensors != NULL);
unsigned short temp_1 = get_temp(sensors);
mu_assert("Invalid Global Temperature Found", temp_1 > 1 && temp_1 < 150);
stress(2000);
unsigned short temp_2 = get_temp(sensors);
mu_assert("Invalid Higher temp test (if fan was already spinning high, this is not worrying)", temp_1 < temp_2);
return 0;
}
static char *all_tests()
{
mu_run_test(test_sensor_paths);
mu_run_test(test_fan_paths);
mu_run_test(test_get_temp);
return 0;
}
int tests()
{
printf("Starting the tests..\n");
printf("It is normal for them to take a bit to finish.\n");
char *result = all_tests();
if (result != 0)
{
printf("%s \n", result);
}
else
{
printf("ALL TESTS PASSED\n");
}
printf("Tests run: %d\n", tests_run);
return result != 0;
}

16
src/minunit.h Normal file
View file

@ -0,0 +1,16 @@
/**
* This is the MinUnit testing framework - http://www.jera.com/techinfo/jtns/jtn002.html
*/
#define mu_assert(message, test) do { if (!(test)) return message; } while (0)
#define mu_run_test(test) do { char *message = test(); tests_run++; \
if (message) return message; } while (0)
extern int tests_run;
static char *test_sensor_paths();
static char *test_fan_paths();
static char *test_get_temp();
static char *all_tests();
int tests();