It covers:
stream_default_ops()stream_default_env()stream_create() / stream_destroy()stream_read()stream_write()stream_flush()See stream_default_ops() specifications
| WHEN | EXPECT |
|---|---|
stream_default_ops() is called | retis non-NULL;ret->read != NULL;ret->write != NULL;ret->flush != NULL |
NULL ops pointer implies well-formed” invariant for the stream port.env.mem == mem_ops.osal_mem_ops_t| WHEN | EXPECT |
|---|---|
stream_default_env(mem_ops) is called with a valid mem_ops pointer | returns a stream_env_t such that env.mem == mem_ops |
out, vtbl, env must not be NULL.vtbl->read, vtbl->write, vtbl->flush, vtbl->close must not be NULL.env->mem must not be NULL.STREAM_STATUS_OK.*out.stream_destroy().STREAM_STATUS_INVALID for invalid argumentsSTREAM_STATUS_OOM on allocation failure*out unchanged if out is not NULL.stream_destroy() does nothing if s == NULL or *s == NULL.*s to NULL.fake_memory| WHEN | EXPECT |
|---|---|
stream_create(out, vtbl, backend, env) is called with valid arguments | returns STREAM_STATUS_OK;stores a non-NULL stream handle in *out;the produced handle is eligible for destruction by stream_destroy() |
out == NULL | returns STREAM_STATUS_INVALID;no stream handle is produced |
vtbl == NULL and out != NULL | returns STREAM_STATUS_INVALID;leaves *out unchanged |
env == NULL and out != NULL | returns STREAM_STATUS_INVALID;leaves *out unchanged |
env != NULL but env->mem == NULL and out != NULL | returns STREAM_STATUS_INVALID;leaves *out unchanged |
| allocation of the stream handle fails | returns STREAM_STATUS_OOM;leaves *out unchanged |
stream_create() succeeds and stream_destroy() is called twice | first stream_destroy(&s) releases the handle and sets s to NULL;second stream_destroy(&s) is a no-op and keeps s as NULL |
vtbl != NULL but vtbl->read == NULL and out != NULL | returns STREAM_STATUS_INVALID;leaves *out unchanged |
s != NULL, s has been created by stream_create() with fake_stream_vtbl and fake_stream_backend.fake_stream_backend_tfake_stream_vtbl| WHEN | EXPECT |
|---|---|
n == 0 and st != NULL | returns 0;sets *st = STREAM_STATUS_OK;does not call fake_stream_vtbl.read/write/flush/close |
n == 0 and st == NULL | returns 0;does not call fake_stream_vtbl.read/write/flush/close |
n > 0 and s == NULL and st != NULL | returns 0;sets *st = STREAM_STATUS_INVALID;does not call fake_stream_vtbl.read/write/flush/close |
n > 0 and s == NULL and st == NULL | returns 0;does not call fake_stream_vtbl.read/write/flush/close |
n > 0 and buf == NULL and st != NULL | returns 0;sets *st = STREAM_STATUS_INVALID;does not call fake_stream_vtbl.read/write/flush/close |
n > 0 and buf == NULL and st == NULL | returns 0;does not call fake_stream_vtbl.read/write/flush/close |
n > 0 and s != NULL and buf != NULL and s->backend == NULL and st != NULL | returns 0;sets *st = STREAM_STATUS_NO_BACKEND;does not call fake_stream_vtbl.read/write/flush/close |
n > 0 and s != NULL and buf != NULL and s->backend == NULL and st == NULL | returns 0;does not call fake_stream_vtbl.read/write/flush/close |
n > 0 and s != NULL and buf != NULL and s->backend != NULL and st != NULL, with fake_stream_backend configured as read_ret = n and read_st_to_set = STREAM_STATUS_OK | calls fake_stream_vtbl.read(fake_stream_backend, buf, n, st) exactly once;does not call fake_stream_vtbl.write/flush/close;returns n;sets *st = STREAM_STATUS_OK |
n > 0 and s != NULL and buf != NULL and s->backend != NULL and st != NULL, with fake_stream_backend configured as read_ret = 0 and read_st_to_set = STREAM_STATUS_EOF | calls fake_stream_vtbl.read(fake_stream_backend, buf, n, st) exactly once;does not call fake_stream_vtbl.write/flush/close;returns 0;sets *st = STREAM_STATUS_EOF |
n > 0 and s != NULL and buf != NULL and s->backend != NULL and st == NULL, with fake_stream_backend configured as read_ret = 5 | calls fake_stream_vtbl.read(fake_stream_backend, buf, n, st = NULL) exactly once;does not call fake_stream_vtbl.write/flush/close;returns 5 |
n == 0, the operation succeeds immediately without consulting the backend.st == NULL, status propagation is omitted but return-value and forwarding behavior remain verified.read operation and the absence of unrelated backend calls.s != NULL, s has been created by stream_create() with fake_stream_vtbl and fake_stream_backend.fake_stream_backend_tfake_stream_vtbl| WHEN | EXPECT |
|---|---|
n == 0 and st != NULL | returns 0;sets *st = STREAM_STATUS_OK;does not call fake_stream_vtbl.read/write/flush/close |
n == 0 and st == NULL | returns 0;does not call fake_stream_vtbl.read/write/flush/close |
n > 0 and s == NULL and st != NULL | returns 0;sets *st = STREAM_STATUS_INVALID;does not call fake_stream_vtbl.read/write/flush/close |
n > 0 and s == NULL and st == NULL | returns 0;does not call fake_stream_vtbl.read/write/flush/close |
n > 0 and buf == NULL and st != NULL | returns 0;sets *st = STREAM_STATUS_INVALID;does not call fake_stream_vtbl.read/write/flush/close |
n > 0 and buf == NULL and st == NULL | returns 0;does not call fake_stream_vtbl.read/write/flush/close |
n > 0 and s != NULL and buf != NULL and s->backend == NULL and st != NULL | returns 0;sets *st = STREAM_STATUS_NO_BACKEND;does not call fake_stream_vtbl.read/write/flush/close |
n > 0 and s != NULL and buf != NULL and s->backend == NULL and st == NULL | returns 0;does not call fake_stream_vtbl.read/write/flush/close |
n > 0 and s != NULL and buf != NULL and s->backend != NULL and st != NULL, with fake_stream_backend configured as write_ret = n and write_st_to_set = STREAM_STATUS_OK | calls fake_stream_vtbl.write(fake_stream_backend, buf, n, st) exactly once;does not call fake_stream_vtbl.read/flush/close;returns n;sets *st = STREAM_STATUS_OK |
n > 0 and s != NULL and buf != NULL and s->backend != NULL and st != NULL, with fake_stream_backend configured as write_ret = 0 and write_st_to_set = STREAM_STATUS_IO_ERROR | calls fake_stream_vtbl.write(fake_stream_backend, buf, n, st) exactly once;does not call fake_stream_vtbl.read/flush/close;returns 0;sets *st = STREAM_STATUS_IO_ERROR |
n > 0 and s != NULL and buf != NULL and s->backend != NULL and st == NULL, with fake_stream_backend configured as write_ret = 5 | calls fake_stream_vtbl.write(fake_stream_backend, buf, n, st = NULL) exactly once;does not call fake_stream_vtbl.read/flush/close;returns 5 |
n == 0, the operation succeeds immediately without consulting the backend.st == NULL, status propagation is omitted but return-value and forwarding behavior remain verified.write operation and the absence of unrelated backend calls.s != NULL, s has been created by stream_create() with fake_stream_vtbl and fake_stream_backend.fake_stream_backend_tfake_stream_vtbl| WHEN | EXPECT |
|---|---|
s == NULL | returns STREAM_STATUS_INVALID;does not call fake_stream_vtbl.read/write/flush/close |
s != NULL and s->backend == NULL | returns STREAM_STATUS_NO_BACKEND;does not call fake_stream_vtbl.flush |
s != NULL and s->backend != NULL, with fake_stream_backend configured as flush_ret = STREAM_STATUS_OK | returns STREAM_STATUS_OK;calls fake_stream_vtbl.flush(fake_stream_backend) exactly once;does not call fake_stream_vtbl.read/write/close |
s != NULL and s->backend != NULL, with fake_stream_backend configured as flush_ret = STREAM_STATUS_IO_ERROR | returns STREAM_STATUS_IO_ERROR;calls fake_stream_vtbl.flush(fake_stream_backend) exactly once;does not call fake_stream_vtbl.read/write/close |
flush operation and the absence of unrelated backend calls.backend == NULL case verifies that the port reports the missing backend without attempting any flush operation.