CommandProcessor: add a mock

Add the MockCommandProcessor class, so that we can
test how upper layers of wifilogd interact with the
CommandProcessor.

Along the way:
- make CommandProcessor::ProcessCommand() a virtual
  method
- make the CommandProcessor dtor virtual

While there: fix some typos in TODOs.

Bug: 32779626
Test: ./runtests.sh (on angler)
Change-Id: I12d9560ed3a1bcd6bc90ffe444dc3ac6a473328e
diff --git a/Android.mk b/Android.mk
index eabfb24..a25d048 100644
--- a/Android.mk
+++ b/Android.mk
@@ -57,6 +57,7 @@
     tests/main.cpp \
     tests/memory_reader_unittest.cpp \
     tests/message_buffer_unittest.cpp \
+    tests/mock_command_processor.cpp \
     tests/mock_os.cpp \
     tests/mock_raw_os.cpp \
     tests/os_unittest.cpp \
diff --git a/command_processor.cpp b/command_processor.cpp
index 64e1489..b969bb4 100644
--- a/command_processor.cpp
+++ b/command_processor.cpp
@@ -90,13 +90,13 @@
   constexpr char kBufferOverrunError[] = "[buffer-overrun]";
   constexpr char kZeroLengthError[] = "[empty]";
   if (!desired_len) {
-    // TODO(b/32098735): Incremement stats counter.
+    // TODO(b/32098735): Increment stats counter.
     return kZeroLengthError;
   }
 
   auto effective_len = desired_len;
   if (buffer_reader->size() < effective_len) {
-    // TODO(b/32098735): Incremement stats counter.
+    // TODO(b/32098735): Increment stats counter.
     effective_len = buffer_reader->size();
   }
 
@@ -128,11 +128,14 @@
                                    std::unique_ptr<Os> os)
     : current_log_buffer_(buffer_size_bytes), os_(std::move(os)) {}
 
+CommandProcessor::~CommandProcessor() {}
+
 bool CommandProcessor::ProcessCommand(const void* input_buffer,
                                       size_t n_bytes_read, int fd) {
   unique_fd wrapped_fd(fd);
 
   if (n_bytes_read < sizeof(protocol::Command)) {
+    // TODO(b/32098735): Increment stats counter.
     return false;
   }
 
@@ -155,7 +158,7 @@
 
   LOG(DEBUG) << "Received unexpected opcode "
              << local_utils::CastEnumToInteger(command_header.opcode);
-  // TODO(b/32098735): Incremement stats counter.
+  // TODO(b/32098735): Increment stats counter.
   return false;
 }
 
@@ -253,7 +256,7 @@
 std::string CommandProcessor::FormatAsciiMessage(MemoryReader buffer_reader) {
   constexpr char kShortHeaderError[] = "[truncated-header]";
   if (buffer_reader.size() < sizeof(protocol::AsciiMessage)) {
-    // TODO(b/32098735): Incremement stats counter.
+    // TODO(b/32098735): Increment stats counter.
     return kShortHeaderError;
   }
 
diff --git a/command_processor.h b/command_processor.h
index ae9d91c..1ad1719 100644
--- a/command_processor.h
+++ b/command_processor.h
@@ -41,6 +41,8 @@
   // This method allows tests to provide a MockOs.
   CommandProcessor(size_t buffer_size_bytes, std::unique_ptr<Os> os);
 
+  virtual ~CommandProcessor();
+
   // Processes the given command, with the given file descriptor. The effect of
   // this call depends on the contents of |input_buf|. In particular, depending
   // on the command, |fd| may be used for reading or writing, or |fd| may be
@@ -48,11 +50,10 @@
   // returns, in all cases.
   //
   // (Ideally, we might want to take |fd| as a unique_fd. Unfortunately,
-  // GoogleMock doesn't deal well with move-only parameters. And we'll
-  // want to mock this method, eventually.
+  // GoogleMock doesn't deal well with move-only parameters.
   // https://github.com/google/googletest/issues/395)
-  bool ProcessCommand(NONNULL const void* input_buf, size_t n_bytes_read,
-                      int fd);
+  virtual bool ProcessCommand(NONNULL const void* input_buf,
+                              size_t n_bytes_read, int fd);
 
  private:
   // Copies |command_buffer| into the log buffer. Returns true if the
diff --git a/tests/mock_command_processor.cpp b/tests/mock_command_processor.cpp
new file mode 100644
index 0000000..b16cec5
--- /dev/null
+++ b/tests/mock_command_processor.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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 <memory>
+
+#include "wifilogd/tests/mock_command_processor.h"
+#include "wifilogd/tests/mock_os.h"
+
+namespace android {
+namespace wifilogd {
+
+namespace {
+constexpr auto kBufferSizeBytes = 4096;
+}
+
+// If we've properly mocked out all of our methods, then the base class
+// should never actually call over to the Os instance. Hence the use
+// of a StrictMock<MockOs>.
+MockCommandProcessor::MockCommandProcessor()
+    : CommandProcessor(kBufferSizeBytes,
+                       std::make_unique<::testing::StrictMock<MockOs>>()) {}
+
+MockCommandProcessor::~MockCommandProcessor() {}
+
+}  // namespace wifilogd
+}  // namespace android
diff --git a/tests/mock_command_processor.h b/tests/mock_command_processor.h
new file mode 100644
index 0000000..da46adf
--- /dev/null
+++ b/tests/mock_command_processor.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#ifndef TESTS_MOCK_COMMAND_PROCESSOR_H_
+#define TESTS_MOCK_COMMAND_PROCESSOR_H_
+
+#include "android-base/macros.h"
+#include "gmock/gmock.h"
+
+#include "wifilogd/command_processor.h"
+
+namespace android {
+namespace wifilogd {
+
+class MockCommandProcessor : public CommandProcessor {
+ public:
+  MockCommandProcessor();
+  virtual ~MockCommandProcessor();
+
+  MOCK_METHOD3(ProcessCommand,
+               bool(const void* input_buf, size_t n_bytes_read, int fd));
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockCommandProcessor);
+};
+
+}  // namespace wifilogd
+}  // namespace android
+
+#endif  // TESTS_MOCK_COMMAND_PROCESSOR_H_