Allow aos::Sha256() to take a file path

This enables writing some tests where we want to conveniently compare
that the contents of two files are identical or haven't changed from
some known-good baseline.

Change-Id: I7f62fb1b3fffb7feafd34dd776e8a4981820b7d6
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/BUILD b/aos/BUILD
index f1cb6ba..acef762 100644
--- a/aos/BUILD
+++ b/aos/BUILD
@@ -809,7 +809,18 @@
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
     deps = [
+        "//aos/util:file",
         "@boringssl//:crypto",
         "@com_google_absl//absl/types:span",
     ],
 )
+
+cc_test(
+    name = "sha256_test",
+    srcs = ["sha256_test.cc"],
+    deps = [
+        ":sha256",
+        "//aos/testing:googletest",
+        "//aos/testing:tmpdir",
+    ],
+)
diff --git a/aos/sha256.cc b/aos/sha256.cc
index ae83792..cfeccde 100644
--- a/aos/sha256.cc
+++ b/aos/sha256.cc
@@ -7,6 +7,8 @@
 #include "absl/types/span.h"
 #include "openssl/sha.h"
 
+#include "aos/util/file.h"
+
 namespace aos {
 
 std::string Sha256(const absl::Span<const uint8_t> str) {
@@ -23,4 +25,13 @@
   return ss.str();
 }
 
+std::string Sha256(std::string_view str) {
+  return Sha256({reinterpret_cast<const uint8_t *>(str.data()), str.size()});
+}
+
+std::string Sha256OfFile(std::filesystem::path file) {
+  const std::string contents = aos::util::ReadFileToStringOrDie(file.string());
+  return Sha256(contents);
+}
+
 }  // namespace aos
diff --git a/aos/sha256.h b/aos/sha256.h
index 7fb9b2f..117bc14 100644
--- a/aos/sha256.h
+++ b/aos/sha256.h
@@ -1,6 +1,7 @@
 #ifndef AOS_SHA256_H_
 #define AOS_SHA256_H_
 
+#include <filesystem>
 #include <string>
 
 #include "absl/types/span.h"
@@ -9,6 +10,10 @@
 
 // Returns the sha256 of a span.
 std::string Sha256(const absl::Span<const uint8_t> str);
+std::string Sha256(std::string_view str);
+
+// Returns the Sha256 of the specified file. Dies on failure to read the file.
+std::string Sha256OfFile(std::filesystem::path file);
 
 }  // namespace aos
 
diff --git a/aos/sha256_test.cc b/aos/sha256_test.cc
new file mode 100644
index 0000000..33ab5ec
--- /dev/null
+++ b/aos/sha256_test.cc
@@ -0,0 +1,27 @@
+#include "aos/sha256.h"
+
+#include "gtest/gtest.h"
+
+#include "aos/testing/tmpdir.h"
+#include "aos/util/file.h"
+
+namespace aos::testing {
+
+constexpr const char *kTestString = "Test String";
+constexpr const char *kTestStringSha =
+    "30c6ff7a44f7035af933babaea771bf177fc38f06482ad06434cbcc04de7ac14";
+
+TEST(Sha256Test, ChecksumString) {
+  EXPECT_EQ(kTestStringSha, Sha256(kTestString));
+  EXPECT_EQ("2b4da12a4bfe66a061c24440521a9e5b994e4f0bcc47a17436275f5283bb6852",
+            Sha256("Test String 2"));
+}
+
+TEST(Sha256Test, ChecksumFile) {
+  const std::filesystem::path test_file =
+      aos::testing::TestTmpDir() + "/test.txt";
+  util::WriteStringToFileOrDie(test_file.string(), kTestString);
+  EXPECT_EQ(kTestStringSha, Sha256OfFile(test_file));
+}
+
+}  // namespace aos::testing