diff --git a/Makefile b/Makefile index b45226d..db27cf6 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,10 @@ CPPFLAGS += -D_GNU_SOURCE=1 CFLAGS += -std=c99 -Wall -Wsign-compare -Wpointer-arith -Wcast-qual \ -Wcast-align -D_GNU_SOURCE=1 -D_FILE_OFFSET_BITS=64 +# Dependencies that all gtest based unittests should have. +UNITTEST_LIBS := -lcap -lgtest -lgmock +UNITTEST_DEPS := gbm_unittest.o testrunner.o gbm.o dri.o drv_array_helpers.o drv_helpers.o drv.o backend_mock.o virtgpu_cross_domain.o virtgpu_virgl.o virtgpu.o msm.o vc4.o amdgpu.o i915.o mediatek.o dumb_driver.o + ifdef DRV_AMDGPU CFLAGS += $(shell $(PKG_CONFIG) --cflags libdrm_amdgpu) LDLIBS += -ldrm_amdgpu -ldl @@ -52,6 +56,13 @@ all: CC_LIBRARY($(MINIGBM_FILENAME)) clean: CLEAN($(MINIGBM_FILENAME)) +CXX_BINARY(gbm_unittest): CXXFLAGS += -Wno-write-strings \ + $(GTEST_CXXFLAGS) +CXX_BINARY(gbm_unittest): LDLIBS += $(UNITTEST_LIBS) +CXX_BINARY(gbm_unittest): $(UNITTEST_DEPS) +clean: CLEAN(gbm_unittest) +tests: TEST(CXX_BINARY(gbm_unittest)) + install: all mkdir -p $(DESTDIR)/$(LIBDIR) install -D -m 755 $(OUT)/$(MINIGBM_FILENAME) $(DESTDIR)/$(LIBDIR) diff --git a/backend_mock.c b/backend_mock.c new file mode 100644 index 0000000..ae0d758 --- /dev/null +++ b/backend_mock.c @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "drv_priv.h" + +static int backend_mock_init(struct driver *drv) { + return 0; +} + +const struct backend backend_mock = { + .name = "Mock Backend", + .init = backend_mock_init, +}; diff --git a/drv.c b/drv.c index d238122..2d33ff7 100644 --- a/drv.c +++ b/drv.c @@ -56,6 +56,8 @@ extern const struct backend backend_virtgpu; extern const struct backend backend_udl; extern const struct backend backend_vkms; +extern const struct backend backend_mock; + static const struct backend *drv_backend_list[] = { #ifdef DRV_AMDGPU &backend_amdgpu, @@ -72,7 +74,7 @@ static const struct backend *drv_backend_list[] = { &backend_evdi, &backend_komeda, &backend_marvell, &backend_mediatek, &backend_meson, &backend_nouveau, &backend_radeon, &backend_rockchip, &backend_sun4i_drm, &backend_synaptics, &backend_udl, &backend_virtgpu, - &backend_vkms + &backend_vkms, &backend_mock }; void drv_preload(bool load) diff --git a/gbm_unittest.cc b/gbm_unittest.cc new file mode 100644 index 0000000..9f2a46f --- /dev/null +++ b/gbm_unittest.cc @@ -0,0 +1,82 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Test gbm.h module code using gtest. + */ + +#include +#include +#include +#include + +#include "gbm.h" + +class MockDrm +{ + public: + MOCK_METHOD(drmVersionPtr, drmGetVersion, (int fd)); + MOCK_METHOD(void, drmFreeVersion, (drmVersionPtr v)); +}; + +// Define a mock version of drmGetVersion +drmVersionPtr drmGetVersion(int fd) +{ + drmVersionPtr mock_version = new drmVersion(); + mock_version->name = "Mock Backend"; + return mock_version; +} + +// Define a mock version of drmFreeVersion +void drmFreeVersion(drmVersionPtr v) +{ + delete(v); +} + +/* TODO : This is a protocol to add unit tests for the public APIs in minigbm. + * + * The ultimate goal would be cover more APIs and the input combinations. + * Set fd to 0 for now, it doesn't have any particular meaning + */ + +TEST(gbm_unit_test, create_device) +{ + MockDrm mock_drm; // Create a mock object + + EXPECT_CALL(mock_drm, drmGetVersion(testing::_)) + .WillRepeatedly(testing::Invoke(&mock_drm, &MockDrm::drmGetVersion)); + + struct gbm_device *gbm_device = gbm_create_device(0); + + ASSERT_TRUE(gbm_device); + + gbm_device_destroy(gbm_device); +} + +TEST(gbm_unit_test, valid_fd) +{ + MockDrm mock_drm; // Create a mock object + + EXPECT_CALL(mock_drm, drmGetVersion(testing::_)) + .WillRepeatedly(testing::Invoke(&mock_drm, &MockDrm::drmGetVersion)); + struct gbm_device *gbm_device = gbm_create_device(99); + int fd = gbm_device_get_fd(gbm_device); + + ASSERT_EQ(fd, 99); + + gbm_device_destroy(gbm_device); +} + +TEST(gbm_unit_test, valid_backend_name) +{ + MockDrm mock_drm; // Create a mock object + + EXPECT_CALL(mock_drm, drmGetVersion(testing::_)) + .WillRepeatedly(testing::Invoke(&mock_drm, &MockDrm::drmGetVersion)); + struct gbm_device *gbm_device = gbm_create_device(0); + const char *backend_name = gbm_device_get_backend_name(gbm_device); + + ASSERT_STREQ(backend_name, "Mock Backend"); + + gbm_device_destroy(gbm_device); +} diff --git a/testrunner.cc b/testrunner.cc new file mode 100644 index 0000000..37a858f --- /dev/null +++ b/testrunner.cc @@ -0,0 +1,15 @@ +/* Copyright 2023 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Main entrypoint for gtest. + */ + +#include + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +}