runner: Make -expect-selected-credential's default more convenient

Right now, if you don't pass -expect-selected-credential in a test, it
implicitly asserts that you selected the default credential. This means
that every credential-based test must pass this flag, which is a bit
tedious when the test is not about credential dispatch.

Instead, default it not expressing a opinion about this either way.

Change-Id: I42591cee71df1e4db8c8b902efba3b646b65d4e5
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/75630
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index de556da..143a705 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -674,9 +674,10 @@
     return false;
   }
 
-  if (config->expect_selected_credential != state->selected_credential) {
+  if (config->expect_selected_credential.has_value() &&
+      *config->expect_selected_credential != state->selected_credential) {
     fprintf(stderr, "Credential %d was used, wanted %d\n",
-            state->selected_credential, config->expect_selected_credential);
+            state->selected_credential, *config->expect_selected_credential);
     return false;
   }
 
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index d34c1a8..ea0c4f7 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -113,6 +113,20 @@
 }
 
 template <typename Config, typename T>
+Flag<Config> OptionalIntFlag(const char *name, std::optional<T> Config::*field,
+                             bool skip_handshaker = false) {
+  return Flag<Config>{name, true, skip_handshaker,
+                      [=](Config *config, const char *param) -> bool {
+                        T value;
+                        if (!StringToInt(&value, param)) {
+                          return false;
+                        }
+                        config->*field = value;
+                        return true;
+                      }};
+}
+
+template <typename Config, typename T>
 Flag<Config> IntVectorFlag(const char *name, std::vector<T> Config::*field,
                            bool skip_handshaker = false) {
   return Flag<Config>{name, true, skip_handshaker,
@@ -486,8 +500,8 @@
         BoolFlag("-no-check-client-certificate-type",
                  &TestConfig::no_check_client_certificate_type),
         BoolFlag("-no-check-ecdsa-curve", &TestConfig::no_check_ecdsa_curve),
-        IntFlag("-expect-selected-credential",
-                &TestConfig::expect_selected_credential),
+        OptionalIntFlag("-expect-selected-credential",
+                        &TestConfig::expect_selected_credential),
         // Credential flags are stateful. First, use one of the
         // -new-*-credential flags to introduce a new credential. Then the flags
         // below switch from acting on the legacy credential to the newly-added
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index 6a1d0d9..84dce1b 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -221,7 +221,7 @@
   bool cnsa_202407 = false;
   bool no_check_client_certificate_type = false;
   bool no_check_ecdsa_curve = false;
-  int expect_selected_credential = -1;
+  std::optional<int> expect_selected_credential;
   std::vector<CredentialConfig> credentials;
   int private_key_delay_ms = 0;