Skip to content

Provide an easy way to edit the googletest arguments in integration tests #425

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 19, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions testing/test_framework/src/firebase_test_framework.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
#include "firebase_test_framework.h" // NOLINT

#include <cstdio>
#include <cstring>
#include <string>
#include <vector>

#include "firebase/future.h"

Expand Down Expand Up @@ -294,7 +297,57 @@ std::ostream& operator<<(std::ostream& os, const Variant& v) {
}
} // namespace firebase

namespace {

/**
* Makes changes to argc and argv before passing them to `InitGoogleTest`.
*
* This function is a convenience function for developers to edit during
* development/debugging to customize the the arguments specified to googletest
* when directly specifying command-line arguments is not available, such as on
* Android and iOS. For example, to debug a specific test, add the
* --gtest_filter argument, and to list all tests add the --gtest_list_tests
* argument.
*
* @param argc A pointer to the `argc` that will be specified to
* `InitGoogleTest`; the integer to which this pointer points will be updated
* with the new length of `argv`.
* @param argv The `argv` that contains the arguments that would have otherwise
* been specified to `InitGoogleTest()`; they will not be modified.
*
* @return The new `argv` to be specified to `InitGoogleTest()`.
*/
char** EditMainArgsForGoogleTest(int* argc, char* argv[]) {
// Put the args into a vector of strings because modifying string objects in
// a vector is far easier than modifying a char** array.
std::vector<std::string> args_vector;
for (int i = 0; i < *argc; ++i) {
args_vector.push_back(argv[i]);
}

// This is where you can add elements to the `args_vector` vector that will be
// specified to googletest.
// e.g. args_vector.push_back("--gtest_list_tests");

// Write the elements of the vector back into argv and modify argc.
// The memory leaks produced below are acceptable because they would last the
// entire lifetime of the application anyways.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More importantly, I would say they are acceptable because this may only be used during development / debugging.

We could alter the code slightly so that it doesn't leak memory except for when someone is adding new flags during dev/debugging process. Meaning, we could add an early exit here:

if (args_vector.size() == argc) {
  return argv;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. I've implemented this suggestion and refactored the code a bit. PTAL.

char** new_argv = new char*[args_vector.size()];
for (int i = 0; i < args_vector.size(); ++i) {
const char* arg = args_vector[i].c_str();
char* arg_copy = new char[std::strlen(arg) + 1];
std::strcpy(arg_copy, arg);
new_argv[i] = arg_copy;
}

*argc = static_cast<int>(args_vector.size());
return new_argv;
}

} // namespace

extern "C" int common_main(int argc, char* argv[]) {
argv = EditMainArgsForGoogleTest(&argc, argv);
::testing::InitGoogleTest(&argc, argv);
firebase_test_framework::FirebaseTest::SetArgs(argc, argv);
app_framework::SetLogLevel(app_framework::kDebug);
Expand Down