/* Check the test fixture is OK. */
TEST_F(iovectest, fixture) {
ASSERT_LT(0, sizeof(test_pattern));
/* Non-zero clear because last character of the pattern is null. */ char buf[sizeof(test_pattern)];
memset(buf, 0xff, sizeof(test_pattern));
/* Read back the test pattern. */ int ret = copy_from_user(buf, _state->buffer_addr, sizeof(test_pattern));
ASSERT_EQ(0, ret);
/* Make sure it's what we expect. */
ASSERT_EQ(0, memcmp(test_pattern, buf, sizeof(test_pattern)));
test_abort:;
}
/* Write an iovec with evenly spaced chunks to userspace. */ staticint write_chunked_iovec(iovectest_t* _state, int size) { struct iovec_user uiov[sizeof(test_pattern)]; unsignedint index = 0; for (unsignedint i = 0; i < sizeof(test_pattern); i += size, index += 1) {
uiov[index].iov_base = _state->buffer_addr + i; int len = sizeof(test_pattern) - i; if (size < len) {
len = size;
}
uiov[index].iov_len = len;
}
/* Copy into user space. */
ASSERT_EQ(0,
copy_to_user(_state->iovec_addr, uiov, sizeof(struct iovec_user) * index), "chunk %d", size);
return index;
test_abort: return0;
}
/* A format string to help understand the exact case the assertion failed. */ #define LOCATION_MESSAGE "chunk size %zu / iov_cnt %d", buffer_chunk, iov_cnt
/* Copy all the data from userspace using a buffer of limited size. */ staticvoid iovectest_readback(iovectest_t* _state,
size_t buffer_chunk, int iov_cnt, constvoid* expected,
size_t expected_len) {
uint8_t buf[sizeof(test_pattern) * 2];
memset(buf, 0xff, sizeof(buf));
/* Read the data a buffer at a time. */ struct iovec_iter iter = iovec_iter_create(iov_cnt);
size_t total_bytes = 0; while (iovec_iter_has_next(&iter)) { int ret = user_iovec_to_membuf_iter(tmp, buffer_chunk,
_state->iovec_addr, &iter); /* Check the return value. */
ASSERT_LE(0, ret, LOCATION_MESSAGE);
ASSERT_LE(ret, buffer_chunk, LOCATION_MESSAGE); /* If there is more data, the buffer should be filled. */ if (iter.iov_index < iter.iov_cnt) {
ASSERT_EQ(ret, buffer_chunk, LOCATION_MESSAGE);
} /* Accumulate the result. */
memcpy(buf + total_bytes, tmp, ret);
total_bytes += ret;
} /* Did we get the data we expect? */
ASSERT_EQ(expected_len, total_bytes, LOCATION_MESSAGE);
ASSERT_EQ(0, memcmp(expected, buf, expected_len), LOCATION_MESSAGE);
test_abort:;
}
/* Test various combinations of iovec size and read buffer size. */
TEST_F(iovectest, varied_chunk_sizes) { /* Note the chunk sizes can exceed the size of the payload. */ for (size_t iovec_chunk = 1; iovec_chunk <= sizeof(test_pattern) + 2;
iovec_chunk++) { for (size_t buffer_chunk = 1; buffer_chunk <= sizeof(test_pattern) + 2;
buffer_chunk++) { int iov_cnt = write_chunked_iovec(_state, iovec_chunk);
iovectest_readback(_state, buffer_chunk, iov_cnt, test_pattern, sizeof(test_pattern));
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.