Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0dc139b authored by James Hawkins's avatar James Hawkins
Browse files

Revert "Revert "bootstat: Handle v1 record files which do not contain file contents.""

This reverts commit 756b6a53.

The change is updated to use utimes (instead of futimens) since only
support for seconds resolution is required.

Bug: 27836969
Change-Id: I7134f759fb643e1a149158fcf6e20f76538b57d3
parent 5d47ab5a
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -55,8 +55,11 @@ bool ParseRecordEventTime(const std::string& path, int32_t* uptime) {
    return false;
  }

  // Ignore existing bootstat records (which do not contain file content).
  if (!content.empty()) {
    int32_t value = std::stoi(content);
    bootstat::LogHistogram("bootstat_mtime_matches_content", value == *uptime);
  }

  return true;
}
+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ class BootEventRecordStore {
  FRIEND_TEST(BootEventRecordStoreTest, AddMultipleBootEvents);
  FRIEND_TEST(BootEventRecordStoreTest, AddBootEventWithValue);
  FRIEND_TEST(BootEventRecordStoreTest, GetBootEvent);
  FRIEND_TEST(BootEventRecordStoreTest, GetBootEventNoFileContent);

  // Sets the filesystem path of the record store.
  void SetStorePath(const std::string& path);
+50 −1
Original line number Diff line number Diff line
@@ -17,12 +17,16 @@
#include "boot_event_record_store.h"

#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <cstdint>
#include <cstdlib>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/test_utils.h>
#include <android-base/unique_fd.h>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "uptime_parser.h"
@@ -31,6 +35,36 @@ using testing::UnorderedElementsAreArray;

namespace {

// Creates a fake boot event record file at |record_path| containing the boot
// record |value|. This method is necessary as truncating a
// BootEventRecordStore-created file would modify the mtime, which would alter
// the value of the record.
bool CreateEmptyBootEventRecord(const std::string& record_path, int32_t value) {
  android::base::unique_fd record_fd(creat(record_path.c_str(), S_IRUSR | S_IWUSR));
  if (record_fd.get() == -1) {
    return false;
  }

  // Writing the value as content in the record file is a debug measure to
  // ensure the validity of the file mtime value, i.e., to check that the record
  // file mtime values are not changed once set.
  // TODO(jhawkins): Remove this block.
  if (!android::base::WriteStringToFd(std::to_string(value), record_fd.get())) {
    return false;
  }

  // Set the |mtime| of the file to store the value of the boot event while
  // preserving the |atime|.
  struct timeval atime = {/* tv_sec */ 0, /* tv_usec */ 0};
  struct timeval mtime = {/* tv_sec */ value, /* tv_usec */ 0};
  const struct timeval times[] = {atime, mtime};
  if (utimes(record_path.c_str(), times) != 0) {
    return false;
  }

  return true;
}

// Returns true if the time difference between |a| and |b| is no larger
// than 10 seconds.  This allow for a relatively large fuzz when comparing
// two timestamps taken back-to-back.
@@ -179,3 +213,18 @@ TEST_F(BootEventRecordStoreTest, GetBootEvent) {
  // Null |record|.
  EXPECT_DEATH(store.GetBootEvent("carboniferous", nullptr), std::string());
}

// Tests that the BootEventRecordStore is capable of handling an older record
// protocol which does not contain file contents.
TEST_F(BootEventRecordStoreTest, GetBootEventNoFileContent) {
  BootEventRecordStore store;
  store.SetStorePath(GetStorePathForTesting());

  EXPECT_TRUE(CreateEmptyBootEventRecord(store.GetBootEventPath("devonian"), 2718));

  BootEventRecordStore::BootEventRecord record;
  bool result = store.GetBootEvent("devonian", &record);
  EXPECT_EQ(true, result);
  EXPECT_EQ("devonian", record.first);
  EXPECT_EQ(2718, record.second);
}