Given a function under test that does something like:
void funcUnderTest()
{
char buf[32];
int bufSize=32;
someReadFunction(buf, size);
}
int someReadFunction(char* buf, int size)
{
int readlen;
//loads buf with data
//returns number of bytes copied
return readlen;
}
How can i write my unit test such that the mock function:
Loads buf with specific data
returns a specified retval
eg:
void test_funcUnderTest()
{
char* testBuf="Hello World";
someReadFunc_ReturnArrayThruPtr_buf(testBuf,12) // Copy "testBuf" into "buf"
//How do we control return value?
funcUnderTest();
}
You can configure the Mock object by combining multiple expectations. It should work like this:
void test_funcUnderTest()
{
char* testBuf="Hello World";
someReadFunc_ExpectAnyArgsAndReturn(retval) // Return "retval" on next call
someReadFunc_ReturnArrayThruPtr_buf(testBuf,12) // Copy "testBuf" into "buf" on the same call
funcUnderTest();
}
Be aware though, that the order of this calls matters. Usually you need to call the "Expect" function first before defining the behavior of specific arguments.
Related
I'm working on a network service that based on commands it receives over the network, it has workers perform different jobs. I want to have a log entry for every time a certain worker is tasked with doing some job.
I have a function (say function_caller) which, among other things, calls another function which it receives its pointer as an argument. I'd like to have my logger notify what kind of function function_caller calls.
Originally I wanted the function_caller to receive some enum instead of a function pointer, provide the enum to the logger, and then use a helper function which returns a suitable pointer based on the enum. However, function_caller is already deeply tangled in the codebase I'm working on, and it looks like it would be a lot of work to refactor all the functions that call function_caller to choose the right enum and use a new argument.
So my next idea was having a switch that for every function pointer will have some string representation of, but I've never stumbled upon something like that (and struggled to find anyone even mentioning such an idea on Google), so I have a feeling I might be missing some serious downsides to this option.
The only significant problem I see is that every developer that decides to pass a new kind of function pointer to function_caller will have to somehow know to update the switch, otherwise it will fail.
Am I missing anything else? Or maybe there's some other approach I should consider?
How about something like this? Instead of a switch, store a table of functions and their name strings. The table can even be kept dynamically updated, unlike a switch case. You will not need to walk along the edge of the standard as well!
#include <stdio.h>
typedef void (*callback_t) (void);
void first (void) { printf("%d", 1); };
void second (void) { printf("%d", 2); };
void third (void) { printf("%d", 3); };
typedef struct fntable_t
{
callback_t fn;
char *name;
} fntable_t;
fntable_t fntable[] =
{
{ first, "first" },
{ second, "second" },
{ third, "third" }
};
char* log_str(callback_t c)
{
for(int i = 0; i < sizeof(fntable) / sizeof(fntable_t); i++)
{
if(fntable[i].fn == c)
return fntable[i].name;
}
return "unknown";
}
void function_caller(callback_t c)
{
printf("%s",log_str(c));
c();
}
int main(void)
{
function_caller(first);
function_caller(second);
function_caller(third);
return 0;
}
You could replace function_caller with a wrapper macro of the same name that calls the renamed function function_caller_internal which gets an additional string argument. The wrapper macro can then pass an additional stringified function name.
This works only if function_caller is always called with a function name, not a function pointer variable.
Example:
#include <stdio.h>
static void funcA(void)
{
printf("This is funcA\n");
}
static void funcB(void)
{
printf("This is funcB\n");
}
/* renamed function gets an additional string argument */
static void function_caller_internal(void (*func)(void), const char *name)
{
printf("calling %s\n", name);
func();
}
/* wrapper macro stringifies the function name to pass it the additional argument */
#define function_caller(func) function_caller_internal(func, #func)
int main(void)
{
/* unchanged calls */
function_caller(funcA);
function_caller(funcB);
return 0;
}
This prints
calling funcA
This is funcA
calling funcB
This is funcB
If you can change the API of the functions, then consider using __func__ to get the textual name of each function. If you can have a function pointer type along the lines of this:
typedef void func_t (const char** name);
Then you can have each function return its name to the caller.
void foo (const char** name)
{
/* do foo stuff here */
*name = __func__;
}
void bar (const char** name)
{
/* do bar stuff here */
*name = __func__;
}
Example:
#include <stdio.h>
typedef void func_t (const char** name);
void foo (const char** name)
{
/* do foo stuff here */
*name = __func__;
}
void bar (const char** name)
{
/* do bar stuff here */
*name = __func__;
}
const char* function_caller (func_t* func, const char** name)
{
func(name);
return *name;
}
int main(void)
{
static func_t*const func [] =
{
foo,
bar,
};
const char* name;
for(size_t i=0; i<sizeof func/sizeof *func; i++)
{
puts( function_caller(func[i], &name) );
}
}
Assuming your codebase has sane variable names and function names, you can add a char * argument to your function caller:
void function_caller(char *name, int fpnt());
and then provide a macro:
#define function_caller_autoname(fpnt) function_caller(#fpnt, fpnt)
(Or, for spaghetti code, you can provide a macro with the same name as the function).
The #fpnt will be expanded by the proceprocessor to a string literal with the function name.
Then when your codebase called:
function_caller(some_function)
refactor it to:
function_caller_autoname(some_function)
# will be expanded to by the processor:
# function_caller("some_function", some_function)
or refactor it manually to provide the name/identificator/description of the function:
function_caller("Some function: ", some_function)
That way you can pass a custom string that describes the function along with the pointer. Also, each developer can pass a custom description string.
This is a function to open a file dialog in Windows and return a string with the file name:
#include <windows.h>
#include <commdlg.h>
#include <string.h>
char* openFileDlg(char FileTypes[]);
char* openFileDlg(char FileTypes[]){
OPENFILENAME ofn;
char szFile[260];
HWND hwnd;
HANDLE hf;
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
strcpy(ofn.lpstrFilter,FileTypes);
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if(GetOpenFileNameA(&ofn)){
char *toReturn;
sprintf(toReturn,"%s",ofn.lpstrFile);
return toReturn;
}
else{
return NULL;
}
}
When I call this function and open a file, the process ends and returns value 3 (which means there is an error). How can I do so that this function returns a string with the path of the selected file?
Edit: I've changed my code to this and it still doesn't work:
#include <windows.h>
#include <commdlg.h>
#include <string.h>
void openFileDlg(char *toReturn[],char FileTypes[]);
void openFileDlg(char *toReturn[],char FileTypes[]){
OPENFILENAME ofn;
/*
Code for the settings of the GetOpenFileNameA, irrelevant in this question.
If you really need to know what's here, look at the code above.
*/
if(GetOpenFileNameA(&ofn)){
strcpy(*toReturn,ofn.lpstrFile);
}
else{
sprintf(*toReturn,"");
}
}
I should also say that if I press the Cancel button in the open file dialog box instead of selecting a file, it works fine. After some tests, I've noticed that it's the line strcpy(*toReturn,ofn.lpstrFile); that causes the error.
The pointer variable toReturn doesn't point anywhere, using it in any way without initializing it (i.e. making it point somewhere valid and big enough) will lead to undefined behavior
You have two solutions really:
Allocate memory dynamically and return a pointer to that. This of course requires the caller to free the memory when done with it.
Have the function take another two arguments: A pointer to a buffer and the length of the buffer. Then copy the string into that buffer, and return a boolean "true" or "false" success/failure status.
I recommend solution number two.
On an unrelated note, there's no need to use the expensive sprintf function in your case, a simple strcpy (or strncpy if you go with the second solution) will do.
You also have to remember in both cases that strings in C have an actual length of one more than e.g. strlen reports, for the terminating '\0' character.
In general, if you want to return a string in C, I'd use one of the following methods:
1) pass in a string buffer for the method to write to:
int openFileDlg(char FileTypes[], char* toReturn, int bufLen) {
/* ... */
snprintf(toReturn, bufLen, /* what you want to print */);
return ERROR; // status-code
}
/* ... */
char errorBuf[80];
int result;
result = openFileDlg(..., errorBuf, sizeof(errorBuf));
2) allocate memory, expect caller to free it:
char* openFileDlg(char FileTypes[]) {
/* ... */
char *toReturn = malloc(/* big enough */);
sprintf(toReturn, /* what you want to print */);
return toReturn;
}
/* ... */
char* error = openFileDlg(...);
if (error) {
/* ... */
free(error);
}
personally, I'd prefer (1) because it's safer. Option (2) is nicer to the API of the function, but has a risk of memory leaks if you forget to free the returned buffer. In a bigger project (especially with multiple people working on it) this is a very real risk.
(I realise this is pretty much the same as Joachim's answer, but his went up as I was writing mine)
You did not allocate memory for your return value. If you know the length of ofn.lpstrFile you could do this:
char *toReturn = malloc( (sizeOfLpstrFile + 1) * sizeof(char)) ;
sprintf(toReturn,"%s",ofn.lpstrFile);
return toReturn;
Still I consider this a bad idea because the calling function will have to free the memory which is not obvious from the interface.
I'm currently trying to write a general function to measure the time another function func needs for execution. I'm able to calculate the time with <time.h> and so on.
My approach looks something like this:
void measure_time(void *(func)(), unsigned loops);
For now it is enough if the result is just printed within measure_time (later I could let measure_time return some information).
I'm able to calculate the execution time and so on (with <time.h>) but at the moment my problem is that I want this to be a general function and it should be able to take all sort of functions 'func' with different return types and different argument sizes/types.
Currently I have no clue how I could manage to give measure_time the function 'func' and let it execute it with arguments I am able to specify.
For example:
int a[1000] = {15, 53, ..., 42};
void sort_something(int *a, int n_elements) { ... };
void measure_time(sort_somthing(a, 1000), 100);
This should call sort_something 100 times with the arguments "a and 1000" and measure the time needed for the execution.
I'm more than happy to give some more information if you need them.
Cheers!
LastSeconds
The general scheme should be:
void general_timer(void (*function)(void *context), void *context, int loops);
This takes a function that returns no value and takes a single void * argument for context, and passes the context. Depending on what you need to pass as context, that might be the address of a structure, or something as simple as a FILE *.
Inside the implementation:
void general_timer(void (*function)(void *context), void *context, int loops)
{
Clock clk;
clk_init(&clk);
clk_start(&clk);
for (int i = 0; i < loops; i++
(*function)(context);
clk_stop(&clk);
char buffer[32];
printf("%s seconds for %d iterations\n",
clk_elapsed_microsecs(&clk, buffer, sizeof(buffer)), loops);
}
Where the type Clock and the functions starting clk_ are parts of a high-resolution timing package, using whatever is convenient.
You could write the function call as:
function(context);
It would work exactly the same. This is the more modern style; I prefer the old-fashioned (*function)(context) call as it makes it clear that function is a function pointer, not the name of a function. YMMV.
Yes, I do have a specific implementation of such a package. However, the concept applies readily regardless of how you implement it.
You might have a function to be timed. It might use the structure:
struct TwoFiles
{
FILE *f_in;
FILE *f_out;
};
and the function might be:
void file_copier(void *ctxt)
{
struct TwoFiles *info = ctxt;
char buffer[4096];
size_t bytes;
rewind(info->f_in);
rewind(info->f_out);
while ((bytes = fread(buffer, sizeof(buffer), sizeof(char), info->f_in)) > 0)
{
if (frwite(buffer, bytes, sizeof(char), info->f_out) != bytes)
{
…report error…abandon loop…
}
}
}
and the call might be:
struct TwoFiles ctxt;
ctxt.f_in = fopen(some_file_name, "r");
ctxt.f_out = fopen(another_name, "w");
general_timer(file_copier, &ctxt, 100);
Note that to be useful, the file copier function needed to rewind the input and output file streams so that it would do work each time the general timer function calls it. That is, however, a detail for the specific task on hand.
So far I have gotten my libev code to successfully return a static sting that says "OMP OMP", however when I write a function that returns a "static" string it never seems to work. (Sidenote: the idea is to turn that same function into a dynamic response but just for agile testing purposes I need this to work first). My code for the libev read callback is as the following...
void p2pserver_network_buf_read_callback(struct bufferevent *incoming, void *arg){
//Define function local variables
struct evbuffer *evreturn;
char *req;
//Begin function local logic
req = evbuffer_readline(incoming->input);
if (req == NULL){
return;
}
char *response;
parse_json_command(req, response);
//response = "OMP OMP";
g_print("PARSED");
evreturn = evbuffer_new();
evbuffer_add_printf(evreturn, "%s", response);
bufferevent_write_buffer(incoming,evreturn);
evbuffer_free(evreturn);
free(req);
g_print("%s", response);
}
The parse_json_command function is as the following...
void parse_json_command(char json_command, char *response){
//Define Local Variables
g_print("PARSING");
response = "YOU KNOW";
//Print out the recieved message....
//g_message("%s", json_command);
/**
* TODO: check if the JSON is valid before parsing
* to prevent "Segmentation Defaults"
* and its good sanity checks.
**/
//Parse JSON incomming
/*json_object * jobj = json_tokener_parse(json_command);
enum json_type type;
json_object_object_foreach(jobj, key, val){
g_print("%s\n", key);
if(g_utf8_collate(key, "cmd") >= 0){
//Looks like the user has sent a "cmd" (command), lets analyze the "val" (value) of that command to see what the caller/client needs to be attending to...
//Is the client requesting an "Identity Update" (Pings server: if this is the first time ping, the server and client will exachange keys if the relationship exists the server just accepts the encrypted "ping" packet update)
type = json_object_get_type(val);
if(type == json_type_string){
char* cmd_value;
cmd_value = json_object_get_string(val);
//g_print("VALUE:%d\n", g_utf8_collate(cmd_value, "identupdate"));
if(g_utf8_collate(cmd_value, "identupdate") == 0){
//Call "Identity Update Response"
//char return_response = p2pserver_json_identupdate_response(json_command);
}
}
}
}
*/
return;
}
If you want to see the complete code (only a couple of pages big at the time of this writing) you can go to the source code at the following link: https://github.com/Xenland/P2PCrypt-Server
Thanks for your time and help!
c passes arguments by value, not by reference. You problem is here:
void parse_json_command(char json_command, char *response){
[...]
response = "YOU KNOW";
[...]
}
char *response;
parse_json_command(req, response);
response is a uninitialized pointer to a string. You are assigning a pointer to a static string to the response pointer in the function, but that does not modify response outside of the function, it just changes response within the function. There are different ways to fix this. Probably the easiest one for a quick fix would be to change the function's prototype to return a char * instead of void:
char * parse_json_command(char json_command){
char *response;
[...]
response = "YOU KNOW";
[...]
return response;
}
char *response;
response = parse_json_command(req);
Also, the json_command argument should probably be a char * or const char *, not just a single char, if you want to pass more than a single byte there.
I have this .c file that counts the system calls that linux calls. These are just the main functions. There were a couple of other things that I had to do, like create an array
unsigned long syscall_counts[345];
and then in another file with some assembly I incremented the array with the command:
incl syscall_counts(,%eax,4)
// This function is called each time the application calls read(). It starts the process of
// accumulating data to fill the application buffer. Return a pointer representing the current
// item. Return NULL if there are no more items.
//
static void *counter_seq_start(struct seq_file *s, loff_t *record_number)
{
if (*record_number > 347)
return NULL;
return (void*)s;
}
// This function is called to compute the next record in the sequence given a pointer to the
// current record (in bookmark). It returns a pointer to the new record (essentially, an updated
// bookmark) and updates *record_number appropriately. Return NULL if there are no more items.
//
static void *counter_seq_next(struct seq_file *s, void *bookmark, loff_t *record_number)
{
unsigned long *temp_b =(unsigned long*) bookmark;
(*temp_b)++;
if (*temp_b > 345)
return NULL;
return (void*)temp_b;
}
// This function is called whenever an application buffer is filled (or when start or next
// returns NULL. It can be used to undo any special preparations done in start (such as
// deallocating auxillary memory that was allocated in start. In simple cases, you often do not
// need to do anything in this function.
//
static void counter_seq_stop(struct seq_file *s, void *bookmark)
{
}
// This function is called after next to actually compute the output. It can use various seq_...
// printing functions (such as seq_printf) to format the output. It returns 0 if successful or a
// negative value if it fails.
//
static int counter_seq_show(struct seq_file *s, void *bookmark)
{
loff_t *bpos = (loff_t *) bookmark;
seq_printf(s, "value: %Ld\n", *bpos);
return 0;
}
// Define the only file handling function we need.
static int counter_open(struct inode *inode, struct file *file)
{
return seq_open(file, &counter_seq_ops);
}
my output is very strange:
Anyone have any idea where the issue is?
Don't you think :
static int counter_seq_show(struct seq_file *s, void *bookmark) {
unsigned long *bpos = (unsigned long *) bookmark;
seq_printf(s, "value: %Ld\n", *bpos);
return 0;
}
Or even
static int counter_seq_show(struct seq_file *s, void *bookmark) {
seq_printf(s, "value: %lu\n", *((unsigned long *)bpos));
return 0;
}
I haven't fully understood your program but I saw two different ways you cast 'bookmark'. In one function you cast it to be 'unsigned long *' and other you do 'loff_t *' (long int). Ideally they should be the same, but are you doing it this way for some reason ?
HTH