Coverage for /Syzygy/trace/logger/logger_app_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%1081080.C++test

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  
  15    :  #include "syzygy/trace/logger/logger_app.h"
  16    :  
  17    :  #include <psapi.h>
  18    :  #include <userenv.h>
  19    :  
  20    :  #include "base/command_line.h"
  21    :  #include "base/environment.h"
  22    :  #include "base/file_util.h"
  23    :  #include "base/process_util.h"
  24    :  #include "base/scoped_temp_dir.h"
  25    :  #include "base/string_util.h"
  26    :  #include "base/stringprintf.h"
  27    :  #include "base/utf_string_conversions.h"
  28    :  #include "base/memory/scoped_ptr.h"
  29    :  #include "gmock/gmock.h"
  30    :  #include "gtest/gtest.h"
  31    :  #include "syzygy/common/align.h"
  32    :  #include "syzygy/common/unittest_util.h"
  33    :  #include "syzygy/core/unittest_util.h"
  34    :  #include "syzygy/trace/client/client_utils.h"
  35    :  #include "syzygy/trace/parse/parse_utils.h"
  36    :  #include "syzygy/trace/protocol/call_trace_defs.h"
  37    :  #include "syzygy/trace/rpc/rpc_helpers.h"
  38    :  #include "syzygy/trace/service/service_rpc_impl.h"
  39    :  #include "syzygy/trace/service/trace_file_writer_factory.h"
  40    :  
  41    :  using namespace trace::client;
  42    :  
  43    :  namespace trace {
  44    :  namespace logger {
  45    :  
  46    :  namespace {
  47    :  
  48    :  class TestLoggerApp : public LoggerApp {
  49    :   public:
  50    :    using LoggerApp::FindActionHandler;
  51    :    using LoggerApp::OpenOutputFile;
  52    :    using LoggerApp::kStart;
  53    :    using LoggerApp::kSpawn;
  54    :    using LoggerApp::kStatus;
  55    :    using LoggerApp::kStop;
  56    :    using LoggerApp::kInstanceId;
  57    :    using LoggerApp::kOutputFile;
  58    :    using LoggerApp::kStdOut;
  59    :    using LoggerApp::kStdErr;
  60    :    using LoggerApp::logger_command_line_;
  61    :    using LoggerApp::app_command_line_;
  62    :    using LoggerApp::instance_id_;
  63    :    using LoggerApp::action_;
  64    :    using LoggerApp::action_handler_;
  65    :    using LoggerApp::output_file_path_;
  66    :    using LoggerApp::append_;
  67    :  };
  68    :  
  69    :  typedef common::Application<TestLoggerApp> TestApp;
  70    :  
  71    :  class LoggerAppTest : public testing::ApplicationTestBase {
  72    :   public:
  73    :    typedef testing::ApplicationTestBase Super;
  74    :  
  75    :    LoggerAppTest()
  76    :        : cmd_line_(FilePath(L"logger.exe")),
  77  E :          test_impl_(test_app_.implementation()) {
  78  E :    }
  79    :  
  80  E :    void SetUp() {
  81  E :      Super::SetUp();
  82    :  
  83    :      // Several of the tests generate progress and (deliberate) error messages
  84    :      // that would otherwise clutter the unit-test output.
  85  E :      logging::SetMinLogLevel(logging::LOG_FATAL);
  86    :  
  87    :      // Setup the IO streams.
  88  E :      CreateTemporaryDir(&temp_dir_);
  89  E :      stdin_path_ = temp_dir_.Append(L"NUL");
  90  E :      stdout_path_ = temp_dir_.Append(L"stdout.txt");
  91  E :      stderr_path_ = temp_dir_.Append(L"stderr.txt");
  92  E :      InitStreams(stdin_path_, stdout_path_, stderr_path_);
  93    :  
  94    :      // Initialize the (potential) input and output path values.
  95  E :      instance_id_ = base::StringPrintf(L"%d", ::GetCurrentProcessId());
  96  E :      output_file_path_ = temp_dir_.Append(L"output.txt");
  97    :  
  98    :      // Point the application at the test's command-line and IO streams.
  99  E :      test_app_.set_command_line(&cmd_line_);
 100  E :      test_app_.set_in(in());
 101  E :      test_app_.set_out(out());
 102  E :      test_app_.set_err(err());
 103  E :    }
 104    :  
 105    :   protected:
 106    :    // Stashes the current log-level before each test instance and restores it
 107    :    // after each test completes.
 108    :    testing::ScopedLogLevelSaver log_level_saver;
 109    :  
 110    :    // @name The application under test.
 111    :    // @{
 112    :    TestApp test_app_;
 113    :    TestApp::Implementation& test_impl_;
 114    :    FilePath temp_dir_;
 115    :    FilePath stdin_path_;
 116    :    FilePath stdout_path_;
 117    :    FilePath stderr_path_;
 118    :    // @}
 119    :  
 120    :    // @name Command-line and parameters.
 121    :    // @{
 122    :    CommandLine cmd_line_;
 123    :    std::wstring instance_id_;
 124    :    FilePath output_file_path_;
 125    :    // @}
 126    :  };
 127    :  
 128    :  }  // namespace
 129    :  
 130  E :  TEST_F(LoggerAppTest, GetHelp) {
 131  E :    cmd_line_.AppendSwitch("help");
 132  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 133  E :  }
 134    :  
 135  E :  TEST_F(LoggerAppTest, EmptyCommandLineFails) {
 136  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 137  E :  }
 138    :  
 139  E :  TEST_F(LoggerAppTest, ParseBasicStart) {
 140    :    cmd_line_.AppendSwitchPath(
 141  E :        TestLoggerApp::kOutputFile, output_file_path_);
 142    :    cmd_line_.AppendSwitchNative(
 143  E :        TestLoggerApp::kInstanceId, instance_id_);
 144  E :    cmd_line_.AppendArgNative(TestLoggerApp::kStart);
 145  E :    ASSERT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 146  E :    EXPECT_EQ(output_file_path_, test_impl_.output_file_path_);
 147  E :    EXPECT_EQ(instance_id_, test_impl_.instance_id_);
 148  E :    EXPECT_EQ(std::wstring(TestLoggerApp::kStart), test_impl_.action_);
 149  E :    EXPECT_TRUE(test_impl_.app_command_line_.get() == NULL);
 150  E :    EXPECT_EQ(&TestLoggerApp::Start, test_impl_.action_handler_);
 151  E :  }
 152    :  
 153  E :  TEST_F(LoggerAppTest, ParseStartWithCommand) {
 154  E :    const FilePath kFooExe(L"foo.exe");
 155  E :    const std::wstring kSwitchName(L"switch");
 156  E :    const std::wstring kSwitchValue(L"value");
 157  E :    const std::wstring kDash(L"--");
 158    :  
 159    :    cmd_line_.AppendSwitchPath(
 160  E :        TestLoggerApp::kOutputFile, output_file_path_);
 161    :    cmd_line_.AppendSwitchNative(
 162  E :        TestLoggerApp::kInstanceId, instance_id_);
 163  E :    cmd_line_.AppendArgNative(TestLoggerApp::kStart);
 164  E :    cmd_line_.AppendArgNative(kDash);
 165  E :    cmd_line_.AppendArgNative(kFooExe.value());
 166  E :    cmd_line_.AppendArgNative(kDash + kSwitchName + L"=" + kSwitchValue);
 167  E :    ASSERT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 168  E :    EXPECT_EQ(output_file_path_, test_impl_.output_file_path_);
 169  E :    EXPECT_EQ(instance_id_, test_impl_.instance_id_);
 170  E :    EXPECT_EQ(std::wstring(TestLoggerApp::kStart), test_impl_.action_);
 171  E :    const CommandLine* app_cmd_line = test_impl_.app_command_line_.get();
 172  E :    ASSERT_TRUE(app_cmd_line != NULL);
 173  E :    EXPECT_EQ(kFooExe, app_cmd_line->GetProgram());
 174    :    EXPECT_EQ(kSwitchValue,
 175  E :              app_cmd_line->GetSwitchValueNative(WideToASCII(kSwitchName)));
 176  E :    EXPECT_EQ(&TestLoggerApp::Start, test_impl_.action_handler_);
 177  E :  }
 178    :  
 179  E :  TEST_F(LoggerAppTest, ParseSpawn) {
 180    :    cmd_line_.AppendSwitchNative(
 181  E :        TestLoggerApp::kInstanceId, instance_id_);
 182  E :    cmd_line_.AppendArgNative(TestLoggerApp::kSpawn);
 183  E :    ASSERT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 184  E :    EXPECT_TRUE(test_impl_.output_file_path_.empty());
 185  E :    EXPECT_EQ(instance_id_, test_impl_.instance_id_);
 186  E :    EXPECT_EQ(std::wstring(TestLoggerApp::kSpawn), test_impl_.action_);
 187  E :    EXPECT_EQ(NULL, test_impl_.app_command_line_.get());
 188  E :    EXPECT_EQ(&TestLoggerApp::Spawn, test_impl_.action_handler_);
 189  E :  }
 190    :  
 191  E :  TEST_F(LoggerAppTest, ParseStop) {
 192    :    cmd_line_.AppendSwitchNative(
 193  E :        TestLoggerApp::kInstanceId, instance_id_);
 194  E :    cmd_line_.AppendArgNative(TestLoggerApp::kStop);
 195  E :    ASSERT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 196  E :    EXPECT_TRUE(test_impl_.output_file_path_.empty());
 197  E :    EXPECT_EQ(instance_id_, test_impl_.instance_id_);
 198  E :    EXPECT_EQ(std::wstring(TestLoggerApp::kStop), test_impl_.action_);
 199  E :    EXPECT_EQ(NULL, test_impl_.app_command_line_.get());
 200  E :    EXPECT_EQ(&TestLoggerApp::Stop, test_impl_.action_handler_);
 201  E :  }
 202    :  
 203  E :  TEST_F(LoggerAppTest, ParseStatus) {
 204    :    cmd_line_.AppendSwitchNative(
 205  E :        TestLoggerApp::kInstanceId, instance_id_);
 206  E :    cmd_line_.AppendArgNative(TestLoggerApp::kStatus);
 207  E :    ASSERT_TRUE(test_impl_.ParseCommandLine(&cmd_line_));
 208  E :    EXPECT_TRUE(test_impl_.output_file_path_.empty());
 209  E :    EXPECT_EQ(instance_id_, test_impl_.instance_id_);
 210  E :    EXPECT_EQ(std::wstring(TestLoggerApp::kStatus), test_impl_.action_);
 211  E :    EXPECT_EQ(NULL, test_impl_.app_command_line_.get());
 212  E :    EXPECT_EQ(&TestLoggerApp::Status, test_impl_.action_handler_);
 213  E :  }
 214    :  
 215  E :  TEST_F(LoggerAppTest, ParseUnknown) {
 216  E :    const std::wstring kUnknown(L"unknown");
 217    :    cmd_line_.AppendSwitchNative(
 218  E :        TestLoggerApp::kInstanceId, instance_id_);
 219  E :    cmd_line_.AppendArgNative(kUnknown);
 220  E :    ASSERT_FALSE(test_impl_.ParseCommandLine(&cmd_line_));
 221  E :    EXPECT_TRUE(test_impl_.output_file_path_.empty());
 222  E :    EXPECT_EQ(instance_id_, test_impl_.instance_id_);
 223  E :    EXPECT_EQ(kUnknown, test_impl_.action_);
 224  E :    EXPECT_EQ(NULL, test_impl_.app_command_line_.get());
 225  E :    EXPECT_TRUE(test_impl_.action_handler_ == NULL);
 226  E :  }
 227    :  
 228  E :  TEST_F(LoggerAppTest, StartEndToEnd) {
 229    :    cmd_line_.AppendSwitchNative(
 230  E :        TestLoggerApp::kInstanceId, instance_id_);
 231  E :    cmd_line_.AppendArgNative(TestLoggerApp::kStart);
 232  E :    cmd_line_.AppendArgNative(L"--");
 233  E :    cmd_line_.AppendArgNative(L"cmd.exe");
 234  E :    cmd_line_.AppendArgNative(L"/C");
 235  E :    cmd_line_.AppendArgNative(L"date /t");
 236    :  
 237  E :    ASSERT_EQ(0, test_app_.Run());
 238  E :  }
 239    :  
 240  E :  TEST_F(LoggerAppTest, SpawnStatusAndStop) {
 241    :    // TODO(rogerm): Write me!
 242  E :  }
 243    :  
 244    :  }  // namespace logger
 245    :  }  // namespace trace

Coverage information generated Thu Mar 14 11:53:36 2013.