Init commit of jobs output/error message peek project.

This commit is contained in:
Lei Chen 2026-05-09 16:57:54 +08:00
parent c772d7e601
commit d2b47e3985
38 changed files with 2267 additions and 21 deletions

View file

@ -29,6 +29,7 @@ extern void test_jobobj(void);
extern void test_qobj(void);
extern void test_wobj(void);
extern void test_request(void);
extern void test_cbuf(void);
void setUp(void) { return; }
@ -127,6 +128,7 @@ int main(int argc, char* argv[])
TEST(test_wobj);
TEST(test_qobj);
TEST(test_request);
TEST(test_cbuf);
return UNITY_END();
}

View file

@ -0,0 +1,207 @@
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <time.h>
#include <unity/unity.h>
#include "mylock.h"
/* ------------------------------------------------------------------ *
* helpers
* ------------------------------------------------------------------ */
static void make_deadline(struct timespec *ts, long ms)
{
clock_gettime(CLOCK_REALTIME, ts);
ts->tv_sec += ms / 1000;
ts->tv_nsec += (ms % 1000) * 1000000L;
if (ts->tv_nsec >= 1000000000L) {
ts->tv_sec++;
ts->tv_nsec -= 1000000000L;
}
}
/* ------------------------------------------------------------------ *
* cbuf_timedget: argument validation
* ------------------------------------------------------------------ */
static void test_cbuf_timedget_null_buf(void)
{
int val;
struct timespec ts;
make_deadline(&ts, 100);
TEST_ASSERT_EQUAL_INT(-EINVAL, cbuf_timedget(NULL, &val, &ts));
}
static void test_cbuf_timedget_null_item(void)
{
cbuf_t b;
cbuf_init(&b, 4, sizeof(int));
struct timespec ts;
make_deadline(&ts, 100);
TEST_ASSERT_EQUAL_INT(-EINVAL, cbuf_timedget(&b, NULL, &ts));
cbuf_fini(&b);
}
static void test_cbuf_timedget_null_deadline(void)
{
cbuf_t b;
cbuf_init(&b, 4, sizeof(int));
int val;
TEST_ASSERT_EQUAL_INT(-EINVAL, cbuf_timedget(&b, &val, NULL));
cbuf_fini(&b);
}
/* ------------------------------------------------------------------ *
* cbuf_timedget: timeout on empty buffer
* ------------------------------------------------------------------ */
static void test_cbuf_timedget_timeout_empty(void)
{
cbuf_t b;
cbuf_init(&b, 4, sizeof(int));
int val = 0;
struct timespec ts;
make_deadline(&ts, 50); /* 50 ms */
int rc = cbuf_timedget(&b, &val, &ts);
TEST_ASSERT_EQUAL_INT(-ETIMEDOUT, rc);
cbuf_fini(&b);
}
/* ------------------------------------------------------------------ *
* cbuf_timedget: normal read when item is already available
* ------------------------------------------------------------------ */
static void test_cbuf_timedget_success_immediate(void)
{
cbuf_t b;
cbuf_init(&b, 4, sizeof(int));
int put_val = 42;
cbuf_put(&b, &put_val);
int got_val = 0;
struct timespec ts;
make_deadline(&ts, 1000); /* generous 1 s */
int rc = cbuf_timedget(&b, &got_val, &ts);
TEST_ASSERT_EQUAL_INT(0, rc);
TEST_ASSERT_EQUAL_INT(42, got_val);
cbuf_fini(&b);
}
/* ------------------------------------------------------------------ *
* cbuf_timedget: producer thread scenario
* ------------------------------------------------------------------ */
typedef struct {
cbuf_t *buf;
int value;
long delay_ms;
} producer_arg_t;
static void *producer_thread(void *arg)
{
producer_arg_t *a = (producer_arg_t *)arg;
struct timespec ts = { .tv_sec = a->delay_ms / 1000,
.tv_nsec = (a->delay_ms % 1000) * 1000000L };
nanosleep(&ts, NULL);
cbuf_put(a->buf, &a->value);
return NULL;
}
static void test_cbuf_timedget_success_after_producer(void)
{
cbuf_t b;
cbuf_init(&b, 4, sizeof(int));
producer_arg_t arg = { .buf = &b, .value = 99, .delay_ms = 30 };
pthread_t tid;
pthread_create(&tid, NULL, producer_thread, &arg);
int got_val = 0;
struct timespec ts;
make_deadline(&ts, 500); /* 500 ms — producer fires at 30 ms */
int rc = cbuf_timedget(&b, &got_val, &ts);
pthread_join(tid, NULL);
TEST_ASSERT_EQUAL_INT(0, rc);
TEST_ASSERT_EQUAL_INT(99, got_val);
cbuf_fini(&b);
}
/* ------------------------------------------------------------------ *
* cbuf_timedget: timeout beats slow producer
* ------------------------------------------------------------------ */
static void test_cbuf_timedget_timeout_beats_slow_producer(void)
{
cbuf_t b;
cbuf_init(&b, 4, sizeof(int));
/* Producer fires at 200 ms, but we timeout at 50 ms */
producer_arg_t arg = { .buf = &b, .value = 7, .delay_ms = 200 };
pthread_t tid;
pthread_create(&tid, NULL, producer_thread, &arg);
int got_val = 0;
struct timespec ts;
make_deadline(&ts, 50);
int rc = cbuf_timedget(&b, &got_val, &ts);
TEST_ASSERT_EQUAL_INT(-ETIMEDOUT, rc);
pthread_join(tid, NULL);
cbuf_fini(&b);
}
/* ------------------------------------------------------------------ *
* cbuf_tryget: basic tests (also not previously declared in header)
* ------------------------------------------------------------------ */
static void test_cbuf_tryget_empty(void)
{
cbuf_t b;
cbuf_init(&b, 4, sizeof(int));
int val;
TEST_ASSERT_EQUAL_INT(-EAGAIN, cbuf_tryget(&b, &val));
cbuf_fini(&b);
}
static void test_cbuf_tryget_success(void)
{
cbuf_t b;
cbuf_init(&b, 4, sizeof(int));
int put_val = 77;
cbuf_put(&b, &put_val);
int got_val = 0;
TEST_ASSERT_EQUAL_INT(0, cbuf_tryget(&b, &got_val));
TEST_ASSERT_EQUAL_INT(77, got_val);
cbuf_fini(&b);
}
/* ------------------------------------------------------------------ *
* suite entry point
* ------------------------------------------------------------------ */
void test_cbuf(void)
{
printf("\n>> cbuf_timedget / cbuf_tryget tests\n\n");
RUN_TEST(test_cbuf_timedget_null_buf);
RUN_TEST(test_cbuf_timedget_null_item);
RUN_TEST(test_cbuf_timedget_null_deadline);
RUN_TEST(test_cbuf_timedget_timeout_empty);
RUN_TEST(test_cbuf_timedget_success_immediate);
RUN_TEST(test_cbuf_timedget_success_after_producer);
RUN_TEST(test_cbuf_timedget_timeout_beats_slow_producer);
RUN_TEST(test_cbuf_tryget_empty);
RUN_TEST(test_cbuf_tryget_success);
}