1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <getopt.h>
6 
7 #include <iostream>
8 #include <string>
9 
10 #include "gtest/gtest.h"
11 
12 // The test main must toggle logging and trace logging features because
13 // tests will be run in environments that support them (in which case we
14 // want as much debugging information as possible), and environments that
15 // don't, so they must be disabled. If ENABLE_PLATFORM_IMPL and
16 // ENABLE_TRACE_LOGGING are both false, then we should no Open Screen
17 // dependencies.
18 #ifdef ENABLE_PLATFORM_IMPL
19 #include "platform/impl/logging.h"
20 #endif
21 #ifdef ENABLE_TRACE_LOGGING
22 #include "platform/impl/text_trace_logging_platform.h"
23 #endif
24 
25 namespace {
LogUsage(const char * argv0)26 void LogUsage(const char* argv0) {
27   std::cerr << R"(
28 usage: )" << argv0
29             << R"( <options>
30 
31 options:
32   -t, --tracing: Enable performance tracing logging.
33 
34   -v, --verbose: Enable verbose logging.
35 
36   -h, --help: Show this help message.
37 )";
38 }
39 
40 struct GlobalTestState {
41 #ifdef ENABLE_TRACE_LOGGING
42   std::unique_ptr<openscreen::TextTraceLoggingPlatform> trace_logger;
43 #endif
44   bool args_are_valid = false;
45 };
46 
InitFromArgs(int argc,char ** argv)47 GlobalTestState InitFromArgs(int argc, char** argv) {
48   // A note about modifying command line arguments: consider uniformity
49   // between all Open Screen executables. If it is a platform feature
50   // being exposed, consider if it applies to the standalone receiver,
51   // standalone sender, osp demo, and test_main argument options.
52   const struct option kArgumentOptions[] = {
53       {"tracing", no_argument, nullptr, 't'},
54       {"verbose", no_argument, nullptr, 'v'},
55       {"help", no_argument, nullptr, 'h'},
56       {nullptr, 0, nullptr, 0}};
57 
58   GlobalTestState state;
59   int ch = -1;
60   while ((ch = getopt_long(argc, argv, "tvh", kArgumentOptions, nullptr)) !=
61          -1) {
62     switch (ch) {
63 #ifdef ENABLE_TRACE_LOGGING
64       case 't':
65         state.trace_logger =
66             std::make_unique<openscreen::TextTraceLoggingPlatform>();
67         break;
68 #endif
69 // When not built with Chrome, log level default is warning. When we are built
70 // with Chrome, we have no way of knowing or setting log level.
71 #ifdef ENABLE_PLATFORM_IMPL
72       case 'v':
73         openscreen::SetLogLevel(openscreen::LogLevel::kVerbose);
74         break;
75 #endif
76       case 'h':
77         LogUsage(argv[0]);
78         return state;
79     }
80   }
81 
82   state.args_are_valid = true;
83   return state;
84 }
85 }  // namespace
86 
87 // Googletest strongly recommends that we roll our own main
88 // function if we want to do global test environment setup.
89 // See the below link for more info;
90 // https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#sharing-resources-between-tests-in-the-same-test-case
91 //
92 // This main method is a drop-in replacement for anywhere that currently
93 // depends on gtest_main, meaning it can be linked into any test-only binary
94 // to provide a main implementation that supports setting flags and other
95 // state that we want shared between all tests.
main(int argc,char ** argv)96 int main(int argc, char** argv) {
97   auto state = InitFromArgs(argc, argv);
98   if (!state.args_are_valid) {
99     return 1;
100   }
101 
102   testing::InitGoogleTest(&argc, argv);
103   return RUN_ALL_TESTS();
104 }
105