LF OS
Hobby operating system for amd64 with high ambitions
Loading...
Searching...
No Matches
test_mq.cxx
Go to the documentation of this file.
1#include <lfostest.h>
2
3namespace LFOS {
4 #include <message_passing.h>
5
6 extern "C" {
7 #include <mq.c>
8 #include <tpa.c>
9 #include <flexarray.c>
10 }
11
12 void scheduler_waitable_done(enum wait_reason r, union wait_data d, size_t m) {
13 }
14
15 class MessageQueueTest : public ::testing::Test {
16 public:
18 : _message((Message*)malloc(sizeof(Message) + 1)) {
21
22 _message->size = 1 + sizeof(struct Message);
25 _message->user_data.raw[0] = rand() % 0xFF;
26 }
27
33
34 protected:
37 };
38
39 TEST_F(MessageQueueTest, PopFromEmptyQueue) {
40 struct Message msg = { .size = sizeof(Message) };
41 EXPECT_EQ(mq_peek(_messageQueue, &msg), ENOMSG) << "Did not peek message from empty queue";
42 }
43
44 TEST_F(MessageQueueTest, UnlimitedQueue) {
45 // TODO: interface for setting queue limits, make unlimited here
46 //mq.max_items = 0;
47 //mq.max_bytes = 0;
48
49 EXPECT_EQ(mq_push(_messageQueue, _message), 0) << "Added message to unlimited queue";
50
51 Message* msg = (Message*)malloc(sizeof(Message) + 1);
52 msg->size = sizeof(msg);
53
54 EXPECT_EQ(mq_peek(_messageQueue, msg), EMSGSIZE) << "Did not peek messsage because not enough buffer space";
55 EXPECT_EQ(msg->size, sizeof(Message) + 1) << "After peek we know the needed buffer space";
56 EXPECT_EQ(msg->type, MT_Invalid) << "When message buffer is too small, message type is MT_Invalid";
57
58 memset(msg, 0, sizeof(Message) + 1);
59 msg->size = sizeof(Message) + 1;
60
61 EXPECT_EQ(mq_peek(_messageQueue, msg), 0) << "Peeked message from queue with a single message in it";
62 EXPECT_EQ(msg->user_data.raw[0], _message->user_data.raw[0]) << "Contents of peeked message correct";
63 EXPECT_EQ(msg->type, MT_UserDefined) << "Peeked message has correct type";
64
65 memset(msg, 0, sizeof(Message) + 1);
66 msg->size = sizeof(Message) + 1;
67
68 EXPECT_EQ(mq_peek(_messageQueue, msg), 0) << "Again peeked message from queue with a single message in it";
69 EXPECT_EQ(msg->user_data.raw[0], _message->user_data.raw[0]) << "Contents of peeked message correct";
70 EXPECT_EQ(msg->type, MT_UserDefined) << "Peeked message has correct type";
71
72 memset(msg, 0, sizeof(Message) + 1);
73 msg->size = sizeof(Message) + 1;
74
75 EXPECT_EQ(mq_pop(_messageQueue, msg), 0) << "Message in queue, popped it";
76 EXPECT_EQ(msg->user_data.raw[0], _message->user_data.raw[0]) << "Contents of peeked message correct";
77 EXPECT_EQ(msg->type, MT_UserDefined) << "Peeked message has correct type";
78
79 memset(msg, 0, sizeof(Message) + 1);
80 msg->size = sizeof(Message) + 1;
81
82 EXPECT_EQ(mq_pop(_messageQueue, msg), ENOMSG) << "Popping again gives no message but correct error code";
83
84 free(msg);
85 }
86
87 TEST_F(MessageQueueTest, ManyMessageTest) {
88 const size_t num_messages = 16;
89
90 for(size_t i = 0; i < num_messages; ++i) {
91 Message* msg = (Message*)malloc(sizeof(Message) + 1);
92 msg->size = sizeof(Message) + 1;
93 msg->user_size = 1;
94 msg->user_data.raw[0] = i % 255;
95
96 EXPECT_EQ(mq_push(_messageQueue, msg), 0) << "Pushed message to queue";
97
98 free(msg);
99 }
100
101 for(size_t i = 0; i < num_messages; ++i) {
102 Message* msg_peeked = (Message*)malloc(sizeof(Message) + 1);
103 msg_peeked->size = sizeof(Message) + 1;
104
105 Message* msg_popped = (Message*)malloc(sizeof(Message) + 1);
106 msg_popped->size = sizeof(Message) + 1;
107
108 EXPECT_EQ(mq_peek(_messageQueue, msg_peeked), 0) << "Successfully peeked message from queue";
109 EXPECT_EQ(mq_pop(_messageQueue, msg_popped), 0) << "Successfully popped message from queue";
110
111 EXPECT_EQ(msg_peeked->size, msg_popped->size) << "Messages have identical size";
112 EXPECT_EQ(msg_peeked->user_data.raw[0], msg_popped->user_data.raw[0]) << "Messages have identical raw user data";
113 EXPECT_EQ(msg_peeked->user_data.raw[0], i) << "Messages have correct raw user data";
114
115 free(msg_peeked);
116 free(msg_popped);
117 }
118 }
119
120 // TODO: build new interface for limitting queues and test the functionality here
121 /*TEST_F(MessageQueueTest, LimitedQueue) {
122 //mq.max_items = 0;
123 //mq.max_bytes = message.size;
124 //t->eq_bool(false, mq_push(&mq, &message), "Correctly denied adding to item-full queue");
125 //t->eq_ptr_t(0, (ptr_t)mq_peek(&mq), "No data in queue, by peek");
126
127 //mq.max_items = 1;
128 //mq.max_bytes = 0;
129 //t->eq_bool(false, mq_push(&mq, &message), "Correctly denied adding to byte-full queue");
130 //t->eq_ptr_t(0, (ptr_t)mq_peek(&mq), "No data in queue, by peek");
131 }*/
132}
allocator_t kernel_alloc
Definition vm.c:737
unsigned long uint64_t
Definition arch.h:14
#define EMSGSIZE
Definition errno-defs.h:33
#define ENOMSG
Definition errno-defs.h:29
void * memset(void *dest, int c, size_t size)
Definition string.c:72
void * malloc(size_t size)
Definition string.c:169
void free(void *ptr)
Definition string.c:180
size_t size
Size of the message, including metadata.
union Message::UserData user_data
@ MT_UserDefined
@ MT_Invalid
Invalid message, only size is valid.
size_t user_size
Size of the user data.
enum MessageType type
Type of the message.
uint64_t mq_push(uint64_t mq, struct Message *message)
Definition mq.c:144
uint64_t mq_pop(uint64_t mq, struct Message *msg)
Definition mq.c:190
uint64_t mq_peek(uint64_t mq, struct Message *msg)
Definition mq.c:218
static tpa_t * mqs
Definition mq.c:12
uint64_t mq_create(allocator_t *alloc)
Definition mq.c:69
void init_mq(allocator_t *alloc)
Definition mq.c:65
void mq_destroy(uint64_t mq)
Definition mq.c:93
TEST_F(MessageQueueTest, PopFromEmptyQueue)
Definition test_mq.cxx:39
void scheduler_waitable_done(enum wait_reason r, union wait_data d, size_t m)
Definition test_mq.cxx:12
wait_reason
Definition scheduler.h:13
void(* dealloc)(struct allocator *alloc, void *mem)
Definition allocator.h:10