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

Commit b196e223 authored by Jack He's avatar Jack He
Browse files

Osi: Implement Has/Get/Set methods for section_t and config_t

* Implement convenience methods so that users don't have to loop
  through them manually

Bug: 143515989
Test: atest --host net_test_osi:ConfigTest
Change-Id: I570a49bec9496409ba60f8223c58c9e642b41c1a
parent 4ab4065b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ cc_test {
        "libbt-protos-lite",
        "libgmock",
        "libosi",
        "libc++fs",
    ],
    target: {
        linux_glibc: {
+5 −0
Original line number Diff line number Diff line
@@ -33,10 +33,15 @@ struct entry_t {
struct section_t {
  std::string name;
  std::list<entry_t> entries;
  void Set(std::string key, std::string value);
  std::list<entry_t>::iterator Find(const std::string& key);
  bool Has(const std::string& key);
};

struct config_t {
  std::list<section_t> sections;
  std::list<section_t>::iterator Find(const std::string& section);
  bool Has(const std::string& section);
};

// Creates a new config object with no entries (i.e. not backed by a file).
+32 −2
Original line number Diff line number Diff line
@@ -30,11 +30,41 @@
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include <sstream>
#include <type_traits>

// Empty definition; this type is aliased to list_node_t.
struct config_section_iter_t {};
void section_t::Set(std::string key, std::string value) {
  for (entry_t& entry : entries) {
    if (entry.key == key) {
      entry.value = value;
      return;
    }
  }
  // add a new key to the section
  entries.emplace_back(
      entry_t{.key = std::move(key), .value = std::move(value)});
}

std::list<entry_t>::iterator section_t::Find(const std::string& key) {
  return std::find_if(
      entries.begin(), entries.end(),
      [&key](const entry_t& entry) { return entry.key == key; });
}

bool section_t::Has(const std::string& key) {
  return Find(key) != entries.end();
}

std::list<section_t>::iterator config_t::Find(const std::string& section) {
  return std::find_if(
      sections.begin(), sections.end(),
      [&section](const section_t& sec) { return sec.name == section; });
}

bool config_t::Has(const std::string& key) {
  return Find(key) != sections.end();
}

static bool config_parse(FILE* fp, config_t* config);

+90 −10
Original line number Diff line number Diff line
/*
 *  Copyright 2020 The Android Open Source Project
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include "osi/include/config.h"

#include <base/files/file_util.h>
#include <gtest/gtest.h>

#include "AllocationTestHarness.h"
#include <filesystem>

#include "osi/include/config.h"
#include "AllocationTestHarness.h"

static const char CONFIG_FILE[] = "/data/local/tmp/config_test.conf";
static const std::filesystem::path kConfigFile =
    std::filesystem::temp_directory_path() / "config_test.conf";
static const char* CONFIG_FILE = kConfigFile.c_str();
static const char CONFIG_FILE_CONTENT[] =
    "                                                                                \n\
first_key=value                                                                      \n\
@@ -55,11 +75,65 @@ class ConfigTest : public AllocationTestHarness {
  void SetUp() override {
    AllocationTestHarness::SetUp();
    FILE* fp = fopen(CONFIG_FILE, "wt");
    fwrite(CONFIG_FILE_CONTENT, 1, sizeof(CONFIG_FILE_CONTENT), fp);
    fclose(fp);
    ASSERT_NE(fp, nullptr);
    ASSERT_EQ(fwrite(CONFIG_FILE_CONTENT, 1, sizeof(CONFIG_FILE_CONTENT), fp),
              sizeof(CONFIG_FILE_CONTENT));
    ASSERT_EQ(fclose(fp), 0);
  }

  void TearDown() override {
    EXPECT_TRUE(std::filesystem::remove(kConfigFile));
    AllocationTestHarness::TearDown();
  }
};

TEST_F(ConfigTest, config_find) {
  std::unique_ptr<config_t> config = config_new(CONFIG_FILE);
  ASSERT_NE(config, nullptr);
  EXPECT_TRUE(config->Has("DID"));
  auto section_iter = config->Find("DID");
  ASSERT_NE(section_iter, config->sections.end());
  EXPECT_FALSE(config->Has("random"));
  EXPECT_EQ(config->Find("random"), config->sections.end());
}

TEST_F(ConfigTest, section_find) {
  std::unique_ptr<config_t> config = config_new(CONFIG_FILE);
  ASSERT_NE(config, nullptr);
  EXPECT_TRUE(config->Has("DID"));
  auto section_iter = config->Find("DID");
  ASSERT_NE(section_iter, config->sections.end());
  EXPECT_EQ(section_iter->name, "DID");
  EXPECT_TRUE(section_iter->Has("version"));
  auto entry_iter = section_iter->Find("version");
  ASSERT_NE(entry_iter, section_iter->entries.end());
  EXPECT_EQ(entry_iter->key, "version");
  EXPECT_EQ(entry_iter->value, "0x1436");
  EXPECT_EQ(section_iter->Find("random"), section_iter->entries.end());
  EXPECT_FALSE(section_iter->Has("random"));
}

TEST_F(ConfigTest, section_set) {
  std::unique_ptr<config_t> config = config_new(CONFIG_FILE);
  ASSERT_NE(config, nullptr);
  EXPECT_TRUE(config->Has("DID"));
  auto section_iter = config->Find("DID");
  ASSERT_NE(section_iter, config->sections.end());
  EXPECT_EQ(section_iter->name, "DID");
  EXPECT_FALSE(section_iter->Has("random"));
  section_iter->Set("random", "foo");
  EXPECT_TRUE(section_iter->Has("random"));
  auto entry_iter = section_iter->Find("random");
  ASSERT_NE(entry_iter, section_iter->entries.end());
  EXPECT_EQ(entry_iter->key, "random");
  EXPECT_EQ(entry_iter->value, "foo");
  section_iter->Set("random", "bar");
  EXPECT_EQ(entry_iter->value, "bar");
  entry_iter = section_iter->Find("random");
  ASSERT_NE(entry_iter, section_iter->entries.end());
  EXPECT_EQ(entry_iter->value, "bar");
}

TEST_F(ConfigTest, config_new_empty) {
  std::unique_ptr<config_t> config = config_new_empty();
  EXPECT_TRUE(config.get() != NULL);
@@ -176,22 +250,28 @@ TEST_F(ConfigTest, config_save_basic) {
}

TEST_F(ConfigTest, checksum_read) {
  std::string filename = "/data/misc/bluedroid/test.checksum";
  auto tmp_dir = std::filesystem::temp_directory_path();
  auto filename = tmp_dir / "test.checksum";
  std::string checksum = "0x1234";
  base::FilePath file_path(filename);
  base::FilePath file_path(filename.string());

  EXPECT_EQ(base::WriteFile(file_path, checksum.data(), checksum.size()),
            (int)checksum.size());

  EXPECT_EQ(checksum_read(filename.c_str()), checksum.c_str());

  EXPECT_TRUE(std::filesystem::remove(filename));
}

TEST_F(ConfigTest, checksum_save) {
  std::string filename = "/data/misc/bluedroid/test.checksum";
  auto tmp_dir = std::filesystem::temp_directory_path();
  auto filename = tmp_dir / "test.checksum";
  std::string checksum = "0x1234";
  base::FilePath file_path(filename);
  base::FilePath file_path(filename.string());

  EXPECT_TRUE(checksum_save(checksum, filename));

  EXPECT_TRUE(base::PathExists(file_path));

  EXPECT_TRUE(std::filesystem::remove(filename));
}