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

Commit 6ae468c1 authored by Yu Shan's avatar Yu Shan
Browse files

Improve test coverage for FakeValueGenerator.

Bug: None
Test: atest FakeVehicleHalValueGeneratorsTest
Change-Id: I6df508e148ff0348fc28b467b4e5a70cf5727a27
parent 67534538
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -41,6 +41,7 @@ filegroup {
    name: "FakeVehicleHalValueGeneratorsTestFiles",
    name: "FakeVehicleHalValueGeneratorsTestFiles",
    srcs: [
    srcs: [
        "prop.json",
        "prop.json",
        "prop_different_types.json",
        "prop_invalid.json",
        "prop_invalid.json",
    ],
    ],
}
}
+114 −51
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@
#include <utils/SystemClock.h>
#include <utils/SystemClock.h>


#include <chrono>
#include <chrono>
#include <condition_variable>
#include <memory>
#include <memory>
#include <mutex>
#include <mutex>
#include <optional>
#include <optional>
@@ -38,6 +39,9 @@ namespace fake {


using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
using ::android::base::ScopedLockAssertion;

using std::literals::chrono_literals::operator""s;


class FakeVehicleHalValueGeneratorsTest : public ::testing::Test {
class FakeVehicleHalValueGeneratorsTest : public ::testing::Test {
  protected:
  protected:
@@ -58,6 +62,16 @@ class FakeVehicleHalValueGeneratorsTest : public ::testing::Test {
        mEvents.clear();
        mEvents.clear();
    }
    }


    void waitForEvents(size_t count) {
        std::unique_lock<std::mutex> uniqueLock(mEventsLock);
        bool result = mCv.wait_for(uniqueLock, 10s, [this, count] {
            ScopedLockAssertion lockAssertion(mEventsLock);
            return mEvents.size() == count;
        });

        ASSERT_TRUE(result) << "didn't receive enough events";
    }

    void TearDown() override {
    void TearDown() override {
        // Generator callback uses mEvents, must stop generator before destroying mEvents.
        // Generator callback uses mEvents, must stop generator before destroying mEvents.
        mHub.reset();
        mHub.reset();
@@ -71,12 +85,16 @@ class FakeVehicleHalValueGeneratorsTest : public ::testing::Test {
  private:
  private:
    void onHalEvent(const VehiclePropValue& event) {
    void onHalEvent(const VehiclePropValue& event) {
        VehiclePropValue eventCopy = event;
        VehiclePropValue eventCopy = event;
        {
            std::scoped_lock<std::mutex> lockGuard(mEventsLock);
            std::scoped_lock<std::mutex> lockGuard(mEventsLock);
            mEvents.push_back(std::move(eventCopy));
            mEvents.push_back(std::move(eventCopy));
        }
        }
        mCv.notify_all();
    }


    std::unique_ptr<GeneratorHub> mHub;
    std::unique_ptr<GeneratorHub> mHub;
    std::mutex mEventsLock;
    std::mutex mEventsLock;
    std::condition_variable mCv;
    std::vector<VehiclePropValue> mEvents GUARDED_BY(mEventsLock);
    std::vector<VehiclePropValue> mEvents GUARDED_BY(mEventsLock);
};
};


@@ -115,8 +133,7 @@ TEST_F(FakeVehicleHalValueGeneratorsTest, testRegisterTestFakeValueGenerator) {


    getHub()->registerGenerator(0, std::move(generator));
    getHub()->registerGenerator(0, std::move(generator));


    // All the events require 500ms to generate, so waiting for 1000ms should be enough.
    waitForEvents(events.size());
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));


    ASSERT_EQ(getEvents(), events);
    ASSERT_EQ(getEvents(), events);


@@ -137,11 +154,12 @@ TEST_F(FakeVehicleHalValueGeneratorsTest, testUnregisterGeneratorStopGeneration)
    generator->setEvents(events);
    generator->setEvents(events);


    getHub()->registerGenerator(0, std::move(generator));
    getHub()->registerGenerator(0, std::move(generator));
    getHub()->unregisterGenerator(0);


    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    waitForEvents(1);

    getHub()->unregisterGenerator(0);


    ASSERT_LT(getEvents().size(), static_cast<size_t>(10))
    ASSERT_LE(getEvents().size(), 2u)
            << "Must stop generating event after generator is unregistered";
            << "Must stop generating event after generator is unregistered";
}
}


@@ -155,13 +173,12 @@ TEST_F(FakeVehicleHalValueGeneratorsTest, testLinerFakeValueGeneratorFloat) {
                                                       /*interval=*/10000000);
                                                       /*interval=*/10000000);
    getHub()->registerGenerator(0, std::move(generator));
    getHub()->registerGenerator(0, std::move(generator));


    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    waitForEvents(10);

    auto events = getEvents();
    auto events = getEvents();
    // We should get 10 events ideally, but let's be safe here.

    ASSERT_LE((size_t)5, events.size());
    ASSERT_EQ(events.size(), 10u);
    int value = 30;
    int value = 30;
    for (size_t i = 0; i < 5; i++) {
    for (size_t i = 0; i < 10; i++) {
        EXPECT_EQ(std::vector<float>({static_cast<float>(value)}), events[i].value.floatValues);
        EXPECT_EQ(std::vector<float>({static_cast<float>(value)}), events[i].value.floatValues);
        value = (value + 20) % 100;
        value = (value + 20) % 100;
    }
    }
@@ -177,13 +194,11 @@ TEST_F(FakeVehicleHalValueGeneratorsTest, testLinerFakeValueGeneratorInt32) {
                                                       /*interval=*/10000000);
                                                       /*interval=*/10000000);
    getHub()->registerGenerator(0, std::move(generator));
    getHub()->registerGenerator(0, std::move(generator));


    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    waitForEvents(10);

    auto events = getEvents();
    auto events = getEvents();
    // We should get 10 events ideally, but let's be safe here.
    ASSERT_EQ(events.size(), 10u);
    ASSERT_LE((size_t)5, events.size());
    int value = 30;
    int value = 30;
    for (size_t i = 0; i < 5; i++) {
    for (size_t i = 0; i < 10; i++) {
        EXPECT_EQ(std::vector<int32_t>({value}), events[i].value.int32Values);
        EXPECT_EQ(std::vector<int32_t>({value}), events[i].value.int32Values);
        value = (value + 20) % 100;
        value = (value + 20) % 100;
    }
    }
@@ -199,13 +214,12 @@ TEST_F(FakeVehicleHalValueGeneratorsTest, testLinerFakeValueGeneratorInt64) {
                                                       /*interval=*/10000000);
                                                       /*interval=*/10000000);
    getHub()->registerGenerator(0, std::move(generator));
    getHub()->registerGenerator(0, std::move(generator));


    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    waitForEvents(10);

    auto events = getEvents();
    auto events = getEvents();
    // We should get 10 events ideally, but let's be safe here.
    // We should get 10 events ideally, but let's be safe here.
    ASSERT_LE((size_t)5, events.size());
    ASSERT_EQ(events.size(), 10u);
    int value = 30;
    int value = 30;
    for (size_t i = 0; i < 5; i++) {
    for (size_t i = 0; i < 10; i++) {
        EXPECT_EQ(std::vector<int64_t>({value}), events[i].value.int64Values);
        EXPECT_EQ(std::vector<int64_t>({value}), events[i].value.int64Values);
        value = (value + 20) % 100;
        value = (value + 20) % 100;
    }
    }
@@ -221,13 +235,11 @@ TEST_F(FakeVehicleHalValueGeneratorsTest, testLinerFakeValueGeneratorUsingReques
            std::make_unique<LinearFakeValueGenerator>(request);
            std::make_unique<LinearFakeValueGenerator>(request);
    getHub()->registerGenerator(0, std::move(generator));
    getHub()->registerGenerator(0, std::move(generator));


    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    waitForEvents(10);

    auto events = getEvents();
    auto events = getEvents();
    // We should get 10 events ideally, but let's be safe here.
    ASSERT_EQ(events.size(), 10u);
    ASSERT_LE((size_t)5, events.size());
    int value = 50;
    int value = 50;
    for (size_t i = 0; i < 5; i++) {
    for (size_t i = 0; i < 10; i++) {
        EXPECT_EQ(std::vector<float>({static_cast<float>(value)}), events[i].value.floatValues);
        EXPECT_EQ(std::vector<float>({static_cast<float>(value)}), events[i].value.floatValues);
        value = (value + 20) % 100;
        value = (value + 20) % 100;
    }
    }
@@ -244,15 +256,13 @@ TEST_F(FakeVehicleHalValueGeneratorsTest, testLinerFakeValueGeneratorInvalidInit
                                                       /*interval=*/10000000);
                                                       /*interval=*/10000000);
    getHub()->registerGenerator(0, std::move(generator));
    getHub()->registerGenerator(0, std::move(generator));


    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    waitForEvents(10);

    auto events = getEvents();
    auto events = getEvents();
    // We should get 10 events ideally, but let's be safe here.
    ASSERT_EQ(events.size(), 10u);
    ASSERT_LE((size_t)5, events.size());


    // Init value would be set to middleValue if given initValue is not valid.
    // Init value would be set to middleValue if given initValue is not valid.
    int value = 50;
    int value = 50;
    for (size_t i = 0; i < 5; i++) {
    for (size_t i = 0; i < 10; i++) {
        EXPECT_EQ(std::vector<float>({static_cast<float>(value)}), events[i].value.floatValues);
        EXPECT_EQ(std::vector<float>({static_cast<float>(value)}), events[i].value.floatValues);
        value = (value + 20) % 100;
        value = (value + 20) % 100;
    }
    }
@@ -265,9 +275,6 @@ TEST_F(FakeVehicleHalValueGeneratorsTest, testJsonFakeValueGenerator) {
            std::make_unique<JsonFakeValueGenerator>(getTestFilePath("prop.json"), 2);
            std::make_unique<JsonFakeValueGenerator>(getTestFilePath("prop.json"), 2);
    getHub()->registerGenerator(0, std::move(generator));
    getHub()->registerGenerator(0, std::move(generator));


    // wait for some time.
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    std::vector<VehiclePropValue> expectedValues = {
    std::vector<VehiclePropValue> expectedValues = {
            VehiclePropValue{
            VehiclePropValue{
                    .areaId = 0,
                    .areaId = 0,
@@ -296,6 +303,7 @@ TEST_F(FakeVehicleHalValueGeneratorsTest, testJsonFakeValueGenerator) {
        expectedValues.push_back(expectedValues[i]);
        expectedValues.push_back(expectedValues[i]);
    }
    }


    waitForEvents(expectedValues.size());
    auto events = getEvents();
    auto events = getEvents();


    long lastEventTime = currentTime;
    long lastEventTime = currentTime;
@@ -313,14 +321,7 @@ TEST_F(FakeVehicleHalValueGeneratorsTest, testJsonFakeValueGeneratorIterateIndef
            std::make_unique<JsonFakeValueGenerator>(getTestFilePath("prop.json"), -1);
            std::make_unique<JsonFakeValueGenerator>(getTestFilePath("prop.json"), -1);
    getHub()->registerGenerator(0, std::move(generator));
    getHub()->registerGenerator(0, std::move(generator));


    // wait for some time.
    waitForEvents(40);
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    auto events = getEvents();

    // Send 1 iteration takes 4ms + 1ms interval between iteration, so for 100ms we should get about
    // 20 iteration, which is 80 events.
    EXPECT_GT(events.size(), static_cast<size_t>(50));
}
}


TEST_F(FakeVehicleHalValueGeneratorsTest, testJsonFakeValueGeneratorUsingRequest) {
TEST_F(FakeVehicleHalValueGeneratorsTest, testJsonFakeValueGeneratorUsingRequest) {
@@ -335,9 +336,6 @@ TEST_F(FakeVehicleHalValueGeneratorsTest, testJsonFakeValueGeneratorUsingRequest
            std::make_unique<JsonFakeValueGenerator>(request);
            std::make_unique<JsonFakeValueGenerator>(request);
    getHub()->registerGenerator(0, std::move(generator));
    getHub()->registerGenerator(0, std::move(generator));


    // wait for some time.
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    std::vector<VehiclePropValue> expectedValues = {
    std::vector<VehiclePropValue> expectedValues = {
            VehiclePropValue{
            VehiclePropValue{
                    .areaId = 0,
                    .areaId = 0,
@@ -366,6 +364,7 @@ TEST_F(FakeVehicleHalValueGeneratorsTest, testJsonFakeValueGeneratorUsingRequest
        expectedValues.push_back(expectedValues[i]);
        expectedValues.push_back(expectedValues[i]);
    }
    }


    waitForEvents(expectedValues.size());
    auto events = getEvents();
    auto events = getEvents();


    long lastEventTime = currentTime;
    long lastEventTime = currentTime;
@@ -388,9 +387,6 @@ TEST_F(FakeVehicleHalValueGeneratorsTest, testJsonFakeValueGeneratorInvalidFile)
            std::make_unique<JsonFakeValueGenerator>(request);
            std::make_unique<JsonFakeValueGenerator>(request);
    getHub()->registerGenerator(0, std::move(generator));
    getHub()->registerGenerator(0, std::move(generator));


    // wait for some time.
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    ASSERT_TRUE(getEvents().empty());
    ASSERT_TRUE(getEvents().empty());
}
}


@@ -404,12 +400,79 @@ TEST_F(FakeVehicleHalValueGeneratorsTest, testJsonFakeValueGeneratorNonExistingF
            std::make_unique<JsonFakeValueGenerator>(request);
            std::make_unique<JsonFakeValueGenerator>(request);
    getHub()->registerGenerator(0, std::move(generator));
    getHub()->registerGenerator(0, std::move(generator));


    // wait for some time.
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    ASSERT_TRUE(getEvents().empty());
    ASSERT_TRUE(getEvents().empty());
}
}


TEST_F(FakeVehicleHalValueGeneratorsTest, testJsonFakeValueGeneratorDifferentTypes) {
    std::unique_ptr<JsonFakeValueGenerator> generator = std::make_unique<JsonFakeValueGenerator>(
            getTestFilePath("prop_different_types.json"), 1);
    getHub()->registerGenerator(0, std::move(generator));

    std::vector<VehiclePropValue> expectedValues = {
            VehiclePropValue{
                    .areaId = 0,
                    .value.int32Values = {1},
                    .prop = 287310600,
            },
            VehiclePropValue{
                    .areaId = 0,
                    .value.int32Values = {2},
                    .prop = 289408000,
            },
            VehiclePropValue{
                    .areaId = 0,
                    .value.floatValues = {3.3},
                    .prop = 291504905,
            },
            VehiclePropValue{
                    .areaId = 0,
                    .value.int64Values = {4},
                    .prop = 290457096,
            },
            VehiclePropValue{
                    .areaId = 0,
                    .value.stringValue = "test",
                    .prop = 286265094,
            },
            VehiclePropValue{
                    .areaId = 0,
                    .value.int32Values = {1, 2},
                    .prop = 289476368,
            },
            VehiclePropValue{
                    .areaId = 0,
                    .value =
                            {
                                    .int32Values = {1, 2},
                                    .int64Values = {3, 4},
                                    .floatValues = {5.5, 6.6},
                                    .stringValue = "test",
                            },
                    .prop = 299896626,
            },
            VehiclePropValue{
                    .areaId = 0,
                    .value =
                            {
                                    .int32Values = {1},
                                    .floatValues = {1.0},
                                    .byteValues = {0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
                                                   0x00, 0x00, 0x00, 0x00, 0x00},
                            },
                    .prop = 299896064,
            },
    };

    waitForEvents(expectedValues.size());
    auto events = getEvents();

    for (auto& event : events) {
        event.timestamp = 0;
    }

    EXPECT_EQ(events, expectedValues);
}

}  // namespace fake
}  // namespace fake
}  // namespace vehicle
}  // namespace vehicle
}  // namespace automotive
}  // namespace automotive
+58 −0
Original line number Original line Diff line number Diff line
[
  {
    "timestamp": 1000000,
    "areaId": 0,
    "value": 1,
    "prop": 287310600
  },
  {
    "timestamp": 1000000,
    "areaId": 0,
    "value": 2,
    "prop": 289408000
  },
  {
    "timestamp": 1000000,
    "areaId": 0,
    "value": 3.3,
    "prop": 291504905
  },
  {
    "timestamp": 1000000,
    "areaId": 0,
    "value": 4,
    "prop": 290457096
  },
  {
    "timestamp": 1000000,
    "areaId": 0,
    "value": "test",
    "prop": 286265094
  },
  {
    "timestamp": 1000000,
    "areaId": 0,
    "value": [1, 2],
    "prop": 289476368
  },
  {
    "timestamp": 1000000,
    "areaId": 0,
    "value": {
      "int32Values": [1, 2],
      "int64Values": [3, 4],
      "floatValues": [5.5, 6.6],
      "stringValue": "test"
    },
    "prop": 299896626
  },
  {
    "timestamp": 1000000,
    "areaId": 0,
    "value": {
      "int32Values": [1],
      "floatValues": [1]
    },
    "prop": 299896064
  }
]
 No newline at end of file
+1 −1
Original line number Original line Diff line number Diff line
@@ -19,7 +19,7 @@ package {
}
}


cc_test {
cc_test {
    name: "VehicleHalVehicleUtilsVendorTest",
    name: "VehicleHalVehicleUtilsTest",
    srcs: ["*.cpp"],
    srcs: ["*.cpp"],
    vendor: true,
    vendor: true,
    static_libs: [
    static_libs: [