AU: fix bug in GPIO handler that caused failed discovery to be ignored

This solves two issues:

* The GPIO handler will attempt to use GPIO devices even when discovery
  via udev has failed. Not any more.

* GPIO discovery would return success even when it failed on a previous
  attempt. Now it'll reflect the actual result of the discovery attempt.

* Reporting of file descriptor open errors is obscured due to
  intermittent operations that reset errno, now fixed.

* Added test case to ensure that repeat GPIO discovery is not attempted,
  and that test mode check will automatically fail if a previous
  initialization/discovery had failed.

BUG=None
TEST=Passes unit tests
TEST=All symptoms gone on real update attempt w/ x86-alex

Change-Id: I01a7b1e316dbb5b94487a5aad1560d994feae9ff
Reviewed-on: https://gerrit.chromium.org/gerrit/40946
Commit-Queue: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
diff --git a/gpio_handler_unittest.cc b/gpio_handler_unittest.cc
index 53ffb61..3aaae5c 100644
--- a/gpio_handler_unittest.cc
+++ b/gpio_handler_unittest.cc
@@ -23,6 +23,7 @@
                                   false, false);
   mock_udev.ExpectAllResourcesDeallocated();
   mock_udev.ExpectDiscoverySuccess();
+  mock_file_descriptor.ExpectNumOpenAttempted(0);
 }
 
 TEST(StandardGpioHandlerTest, MultiGpioChipInitTest) {
@@ -35,6 +36,24 @@
                                    false, false);
   mock_udev.ExpectAllResourcesDeallocated();
   mock_udev.ExpectDiscoveryFail();
+  mock_file_descriptor.ExpectNumOpenAttempted(0);
+}
+
+TEST(StandardGpioHandlerTest, FailedFirstGpioInitTest) {
+  // Attempt GPIO discovery with a udev mock that fails the initialization on
+  // the first attempt, then check for test mode. Ensure that (a) discovery is
+  // not attempted a second time, and (b) test mode check returns false (the
+  // default) without attempting to use GPIO signals.
+  FailInitGpioMockUdevInterface mock_udev;
+  TestModeGpioMockFileDescriptor
+      mock_file_descriptor(base::TimeDelta::FromSeconds(1));
+  StandardGpioHandler gpio_handler(&mock_udev, &mock_file_descriptor,
+                                   false, false);
+  EXPECT_FALSE(gpio_handler.IsTestModeSignaled());
+  mock_udev.ExpectAllResourcesDeallocated();
+  mock_udev.ExpectDiscoveryFail();
+  mock_udev.ExpectNumInitAttempts(1);
+  mock_file_descriptor.ExpectNumOpenAttempted(0);
 }
 
 TEST(StandardGpioHandlerTest, TestModeGpioSignalingTest) {