added more RawQueue tests
diff --git a/aos/linux_code/ipc_lib/queue.cc b/aos/linux_code/ipc_lib/queue.cc
index ab117d1..739f2bb 100644
--- a/aos/linux_code/ipc_lib/queue.cc
+++ b/aos/linux_code/ipc_lib/queue.cc
@@ -23,7 +23,7 @@
               "RawQueue instances go into shared memory");
 
 const bool kReadDebug = false;
-const bool kWriteDebug = false;
+const bool kWriteDebug = true;
 const bool kRefDebug = false;
 const bool kFetchDebug = false;
 const bool kReadIndexDebug = false;
@@ -146,8 +146,6 @@
 }
 
 void *RawQueue::GetMessage() {
-  // TODO(brians): Test this function.
-
   MessageHeader *header = __atomic_load_n(&free_messages_, __ATOMIC_RELAXED);
   do {
     if (__builtin_expect(header == nullptr, 0)) {
@@ -280,19 +278,9 @@
 }
 
 bool RawQueue::WriteMessage(void *msg, int options) {
-  // TODO(brians): Test this function.
   if (kWriteDebug) {
     printf("queue: %p->WriteMessage(%p, %x)\n", this, msg, options);
   }
-  if (msg == NULL || msg < reinterpret_cast<void *>(global_core->mem_struct) ||
-      msg > static_cast<void *>((
-              reinterpret_cast<char *>(global_core->mem_struct) +
-              global_core->size))) {
-    fprintf(stderr, "queue: attempt to write bad message %p to %p. aborting\n",
-            msg, this);
-    printf("see stderr\n");
-    abort();
-  }
   {
     MutexLocker locker(&data_lock_);
     bool writable_waited = false;
diff --git a/aos/linux_code/ipc_lib/raw_queue_test.cc b/aos/linux_code/ipc_lib/raw_queue_test.cc
index e91655a..ca84c51 100644
--- a/aos/linux_code/ipc_lib/raw_queue_test.cc
+++ b/aos/linux_code/ipc_lib/raw_queue_test.cc
@@ -471,6 +471,12 @@
   EXPECT_EQ(message2, queue->GetMessage());
 }
 
+// All of the tests from here down are designed to test every branch to
+// make sure it does what it's supposed to. They are generally pretty repetitive
+// and boring, and some of them may duplicate other tests above, but these ones
+// make it a lot easier to figure out what's wrong with bugs not related to race
+// conditions.
+
 TEST_F(RawQueueTest, ReadIndexNotFull) {
   RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 2);
   const TestMessage *message, *peek_message;
@@ -877,5 +883,47 @@
   EXPECT_EQ(0, kExtraMessages + 2 - queue->FreeMessages());
 }
 
+// Tests that writing with kNonBlock fails and frees the message.
+TEST_F(RawQueueTest, WriteDontBlock) {
+  RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 1);
+  void *message;
+
+  PushMessage(queue, 971);
+  int free_before = queue->FreeMessages();
+  message = queue->GetMessage();
+  ASSERT_NE(nullptr, message);
+  EXPECT_NE(free_before, queue->FreeMessages());
+  EXPECT_FALSE(queue->WriteMessage(message, RawQueue::kNonBlock));
+  EXPECT_EQ(free_before, queue->FreeMessages());
+}
+
+// Tests that writing with kOverride pushes the last message out of the queue.
+TEST_F(RawQueueTest, WriteOverride) {
+  RawQueue *const queue = RawQueue::Fetch("Queue", sizeof(TestMessage), 1, 2);
+  TestMessage *message1;
+
+  PushMessage(queue, 971);
+  PushMessage(queue, 1768);
+  int free_before = queue->FreeMessages();
+  message1 = static_cast<TestMessage *>(queue->GetMessage());
+  ASSERT_NE(nullptr, message1);
+  EXPECT_NE(free_before, queue->FreeMessages());
+  message1->data = 254;
+  EXPECT_TRUE(queue->WriteMessage(message1, RawQueue::kOverride));
+  EXPECT_EQ(free_before, queue->FreeMessages());
+
+  const TestMessage *message2;
+  message2 =
+      static_cast<const TestMessage *>(queue->ReadMessage(RawQueue::kNonBlock));
+  EXPECT_EQ(1768, message2->data);
+  queue->FreeMessage(message2);
+  EXPECT_EQ(free_before + 1, queue->FreeMessages());
+  message2 =
+      static_cast<const TestMessage *>(queue->ReadMessage(RawQueue::kNonBlock));
+  EXPECT_EQ(254, message2->data);
+  queue->FreeMessage(message2);
+  EXPECT_EQ(free_before + 2, queue->FreeMessages());
+}
+
 }  // namespace testing
 }  // namespace aos