我有一个接收描述符的函数(您知道,这些open()
和socket()
吐出的东西之一),从中读取并对数据进行处理:
int do_something(int fd);
我要测试此功能。为了便于调试,最好将输入数据置于测试声明的旁边。 (因此,应避免实际读取文件。)在我看来,理想的选择是
unsigned char test_input[] = { 1, 2, 3 };
int fd = char_array_to_fd(test_input);
ck_assert(do_something(fd) == 1234);
({ck_assert
来自Check framework。这只是典型的单元测试声明。)
是否有实现char_array_to_fd()
的方法?我不在乎是否需要对数组进行NULL终止或将长度发送进来。
我想我可以为自己打开一个套接字并在一端写入,以便测试函数在另一端接收数据。我只是不想写笨拙的东西,而发现Unix一直以来的设计欠佳。该解决方案应该是对Unix友好的。
(基本上,我要求C等于ByteArrayInputStream
。)
或者:我是否应该以其他方式解决这个问题?
答案 0 :(得分:1)
在Linux上,您可以使用memfd_create()
创建由内存支持的临时文件:
import pandas as pd
pd.Series(A).value_counts().reindex(B).to_dict()
#{1: 1, 5: 3, 7: 3}
请注意,完全没有错误检查。
答案 1 :(得分:0)
您可以使用mkstemp
制作一个临时文件并对其进行写入或读取:
int fd = mkstemp("tempXXXXXX");
如果您想要更多动态的东西,可以使用socketpair
创建一对连接的套接字。
int pair[2];
socketpair(AF_UNIX, SOCK_STREAM, 0, pair);
然后您可以派生进程或线程与被测程序进行交互。
答案 2 :(得分:0)
@ChrisDodd的答案已经被接受,但是为了完整起见,我想添加我开发的管道解决方案(由于@Someprogrammerdude的评论):
/*
* Like write(), except it keeps pummeling the buffer into the fd
* until it is fully written.
*/
static int write_exact(int fd, unsigned char *buffer, size_t length)
{
size_t written;
int written_now;
for (written = 0; written < length; written += written_now) {
written_now = write(fd, buffer + written, length - written);
if (written_now == -1)
return errno;
}
return 0;
}
/*
* Wrapper for quick & easy testing of the do_something() function.
* Replaces the fd parameter for a char array and its size.
*/
static int __do_something(unsigned char *input, size_t size)
{
int fd[2];
int err;
int result;
if (pipe(fd) == -1) {
printf("Pipe creation failed with errno %d.\n", errno);
return -abs(errno);
}
err = write_exact(fd[1], input, size);
close(fd[1]);
if (err) {
close(fd[0]);
printf("Pipe write failed with errcode %d.\n", err);
return -abs(err);
}
/*
* Note that, for the sake of simplicity, I'm
* assuming that do_something returns positive on
* success, negative on failure.
*/
result = do_something(fd[0]);
close(fd[0]);
return result;
}
然后,我可以根据需要继续测试do_something
:
unsigned char input1[] = { 0, 0, 1 };
ck_assert(__do_something(input1, sizeof(input1)) == 1234);
unsigned char input2[] = { 'a', 66, 'd', 0 };
ck_assert(__do_something(input2, sizeof(input2)) == 0);
unsigned char input3[] = { 9, 8, 7, 6, 5, 4 };
ck_assert(__do_something(input3, sizeof(input3)) == 555);
...