mirror of
https://github.com/google/pebble.git
synced 2025-03-19 10:31:21 +00:00
203 lines
6.2 KiB
C
203 lines
6.2 KiB
C
|
/*
|
||
|
* Copyright 2024 Google LLC
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
#include "clar.h"
|
||
|
|
||
|
#include "util/mbuf.h"
|
||
|
#include "util/mbuf_iterator.h"
|
||
|
|
||
|
#include "stubs_logging.h"
|
||
|
#include "stubs_mutex.h"
|
||
|
#include "stubs_passert.h"
|
||
|
#include "stubs_pbl_malloc.h"
|
||
|
#include "stubs_serial.h"
|
||
|
|
||
|
extern MBuf *s_free_list;
|
||
|
|
||
|
|
||
|
// Setup
|
||
|
|
||
|
void test_mbuf__initialize(void) {
|
||
|
}
|
||
|
|
||
|
void test_mbuf__cleanup(void) {
|
||
|
}
|
||
|
|
||
|
|
||
|
// Tests
|
||
|
|
||
|
void test_mbuf__length(void) {
|
||
|
// test the mbuf_get_length()/mbuf_get_chain_length() functions
|
||
|
char *data = __FILE_NAME__; // dummy data
|
||
|
char data_length = sizeof(__FILE_NAME__);
|
||
|
MBuf mbuf1 = MBUF_EMPTY;
|
||
|
MBuf mbuf2 = MBUF_EMPTY;
|
||
|
MBuf mbuf3 = MBUF_EMPTY;
|
||
|
|
||
|
// empty mbuf chain
|
||
|
cl_assert(mbuf_get_chain_length(NULL) == 0);
|
||
|
|
||
|
// single empty mbuf in the chain
|
||
|
mbuf1 = MBUF_EMPTY;
|
||
|
cl_assert(mbuf_get_length(&mbuf1) == 0);
|
||
|
cl_assert(mbuf_get_chain_length(&mbuf1) == 0);
|
||
|
|
||
|
// single mbuf of non-zero length
|
||
|
mbuf1 = MBUF_EMPTY;
|
||
|
mbuf_set_data(&mbuf1, data, data_length);
|
||
|
cl_assert(mbuf_get_length(&mbuf1) == data_length);
|
||
|
cl_assert(mbuf_get_chain_length(&mbuf1) == data_length);
|
||
|
|
||
|
// three mbufs of 0 length
|
||
|
mbuf1 = MBUF_EMPTY;
|
||
|
mbuf2 = MBUF_EMPTY;
|
||
|
mbuf3 = MBUF_EMPTY;
|
||
|
mbuf_append(&mbuf1, &mbuf2);
|
||
|
mbuf_append(&mbuf1, &mbuf3);
|
||
|
cl_assert(mbuf_get_length(&mbuf1) == 0);
|
||
|
cl_assert(mbuf_get_chain_length(&mbuf1) == 0);
|
||
|
|
||
|
// three mbufs of non-zero length in a chain
|
||
|
mbuf1 = MBUF_EMPTY;
|
||
|
mbuf2 = MBUF_EMPTY;
|
||
|
mbuf3 = MBUF_EMPTY;
|
||
|
mbuf_set_data(&mbuf1, data, data_length);
|
||
|
mbuf_set_data(&mbuf2, data, data_length);
|
||
|
mbuf_set_data(&mbuf3, data, data_length);
|
||
|
mbuf_append(&mbuf1, &mbuf2);
|
||
|
mbuf_append(&mbuf1, &mbuf3);
|
||
|
cl_assert(mbuf_get_length(&mbuf1) == data_length);
|
||
|
cl_assert(mbuf_get_length(&mbuf2) == data_length);
|
||
|
cl_assert(mbuf_get_length(&mbuf3) == data_length);
|
||
|
cl_assert(mbuf_get_chain_length(&mbuf1) == (3 * data_length));
|
||
|
|
||
|
// three mbufs with one of zero length
|
||
|
mbuf1 = MBUF_EMPTY;
|
||
|
mbuf2 = MBUF_EMPTY;
|
||
|
mbuf3 = MBUF_EMPTY;
|
||
|
mbuf_set_data(&mbuf1, data, data_length);
|
||
|
mbuf_set_data(&mbuf3, data, data_length);
|
||
|
mbuf_append(&mbuf1, &mbuf2);
|
||
|
mbuf_append(&mbuf1, &mbuf3);
|
||
|
cl_assert(mbuf_get_length(&mbuf1) == data_length);
|
||
|
cl_assert(mbuf_get_length(&mbuf2) == 0);
|
||
|
cl_assert(mbuf_get_length(&mbuf3) == data_length);
|
||
|
cl_assert(mbuf_get_chain_length(&mbuf1) == (2 * data_length));
|
||
|
}
|
||
|
|
||
|
void test_mbuf__iter_empty(void) {
|
||
|
// test iteratoring over empty mbuf chains
|
||
|
MBuf mbuf1 = MBUF_EMPTY;
|
||
|
MBuf mbuf2 = MBUF_EMPTY;
|
||
|
MBufIterator iter;
|
||
|
mbuf_append(&mbuf1, &mbuf2);
|
||
|
mbuf_iterator_init(&iter, NULL);
|
||
|
cl_assert(mbuf_iterator_is_finished(&iter));
|
||
|
mbuf_iterator_init(&iter, &mbuf2);
|
||
|
cl_assert(mbuf_iterator_is_finished(&iter));
|
||
|
mbuf_iterator_init(&iter, &mbuf1);
|
||
|
cl_assert(mbuf_iterator_is_finished(&iter));
|
||
|
uint8_t data;
|
||
|
cl_assert(!mbuf_iterator_read_byte(&iter, &data));
|
||
|
cl_assert(!mbuf_iterator_get_current_mbuf(&iter));
|
||
|
}
|
||
|
|
||
|
void test_mbuf__iter_modify(void) {
|
||
|
// modify (read and then write) the data in an mbuf chain using an mbuf iterator
|
||
|
// test reading from an mbuf chain via an mbuf iterator
|
||
|
uint8_t data1[] = {10, 11, 12};
|
||
|
uint8_t data3[] = {13, 14, 15};
|
||
|
MBufIterator write_iter, read_iter;
|
||
|
MBuf mbuf1 = MBUF_EMPTY;
|
||
|
MBuf mbuf2 = MBUF_EMPTY;
|
||
|
MBuf mbuf3 = MBUF_EMPTY;
|
||
|
mbuf_set_data(&mbuf1, data1, 3);
|
||
|
mbuf_set_data(&mbuf3, data3, 3);
|
||
|
mbuf_append(&mbuf1, &mbuf2);
|
||
|
mbuf_append(&mbuf1, &mbuf3);
|
||
|
mbuf_iterator_init(&write_iter, &mbuf1);
|
||
|
mbuf_iterator_init(&read_iter, &mbuf1);
|
||
|
for (int i = 0; i < 6; i++) {
|
||
|
cl_assert(!mbuf_iterator_is_finished(&write_iter));
|
||
|
cl_assert(!mbuf_iterator_is_finished(&read_iter));
|
||
|
// check we're on the exected mbuf
|
||
|
if (i < 3) {
|
||
|
cl_assert(mbuf_iterator_get_current_mbuf(&write_iter) == &mbuf1);
|
||
|
cl_assert(mbuf_iterator_get_current_mbuf(&read_iter) == &mbuf1);
|
||
|
} else {
|
||
|
cl_assert(mbuf_iterator_get_current_mbuf(&write_iter) == &mbuf3);
|
||
|
cl_assert(mbuf_iterator_get_current_mbuf(&read_iter) == &mbuf3);
|
||
|
}
|
||
|
uint8_t data_byte = 0;
|
||
|
bool have_byte = mbuf_iterator_read_byte(&read_iter, &data_byte);
|
||
|
cl_assert(have_byte);
|
||
|
// check that the data is what we expect
|
||
|
cl_assert(data_byte == (i + 10));
|
||
|
// modify the data by increasing the value by 10
|
||
|
cl_assert(mbuf_iterator_write_byte(&write_iter, data_byte + 10));
|
||
|
}
|
||
|
cl_assert(mbuf_iterator_is_finished(&write_iter));
|
||
|
cl_assert(mbuf_iterator_is_finished(&read_iter));
|
||
|
// verify the final value of the data
|
||
|
for (int i = 0; i < 6; i++) {
|
||
|
uint8_t *data;
|
||
|
int index;
|
||
|
if (i < 3) {
|
||
|
data = data1;
|
||
|
index = i;
|
||
|
} else {
|
||
|
data = data3;
|
||
|
index = i - 3;
|
||
|
}
|
||
|
cl_assert(data[index] == (i + 20));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static int prv_get_free_list_length(void) {
|
||
|
int len = 0;
|
||
|
for (MBuf *m = s_free_list; m; m = mbuf_get_next(m)) {
|
||
|
len++;
|
||
|
}
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
void test_mbuf__mbuf_pool(void) {
|
||
|
// get an MBuf and the pool should still be empty
|
||
|
MBuf *mbuf1 = mbuf_get(NULL, 0, MBufPoolUnitTest);
|
||
|
cl_assert(prv_get_free_list_length() == 0);
|
||
|
|
||
|
// free the mbuf and the pool should now contain it
|
||
|
mbuf_free(mbuf1);
|
||
|
cl_assert(prv_get_free_list_length() == 1);
|
||
|
cl_assert(s_free_list == mbuf1);
|
||
|
|
||
|
// get another mbuf and expect that it's the same one and the pool is empty
|
||
|
MBuf *mbuf2 = mbuf_get(NULL, 0, MBufPoolUnitTest);
|
||
|
cl_assert(mbuf2 == mbuf1);
|
||
|
cl_assert(prv_get_free_list_length() == 0);
|
||
|
|
||
|
// get another mbuf and expect that it's not the same as the previous one
|
||
|
MBuf *mbuf3 = mbuf_get(NULL, 0, MBufPoolUnitTest);
|
||
|
cl_assert(mbuf3 != mbuf2);
|
||
|
cl_assert(prv_get_free_list_length() == 0);
|
||
|
|
||
|
// free both of the mbufs (one at a time)
|
||
|
mbuf_free(mbuf2);
|
||
|
cl_assert(prv_get_free_list_length() == 1);
|
||
|
mbuf_free(mbuf3);
|
||
|
cl_assert(prv_get_free_list_length() == 2);
|
||
|
}
|