--- /dev/null
+##### Build Instruction #####
+
+
+Build libtpl-egl:
+ gbs build -A armv7l --spec=libtpl-egl.spec
+
+Build tpl-test:
+ gbs build -A armv7l --spec=tpl-test.spec
+
+Build all:
+ gbs build -A armv7l
+
--- /dev/null
+Name: tpl-test
+Version: 0.2.1
+Release: 1
+Summary: TPL Test Module
+
+Group: Graphics & UI Framework/GL
+
+# The entire source code is MIT except tc/libs/gtest/ which is BSD-3-Clause
+License: MIT and BSD-3-Clause
+Source0: %{name}-%{version}.tar.gz
+
+BuildRequires: pkgconfig(libtbm)
+BuildRequires: pkgconfig(gbm)
+BuildRequires: pkgconfig(wayland-client)
+BuildRequires: pkgconfig(tpl-egl)
+BuildRequires: cmake
+
+%global TZ_SYS_RO_SHARE %{?TZ_SYS_RO_SHARE:%TZ_SYS_RO_SHARE}%{!?TZ_SYS_RO_SHARE:/usr/share}
+
+
+%description
+Test module for testing libtpl-egl frontend APIs
+
+
+%prep
+%setup -q
+
+
+%build
+###### Setup variables for build ######
+export BUILD_DIR="%{_builddir}/%{buildsubdir}"
+export GTEST_DIR="${BUILD_DIR}/tc/libs/gtest"
+
+export GTEST_INCLUDE="-I${GTEST_DIR}/googletest -I${GTEST_DIR}/googletest/include \
+ -I${GTEST_DIR}/googlemock -I${GTEST_DIR}/googlemock/include"
+export GTEST_FLAGS="-g -Wall -Wextra -pthread"
+
+export GTEST_LIB_TEST="${GTEST_DIR}/build/gtest/libgtest.a" # googletest output path
+export GTEST_LIB_MOCK="${GTEST_DIR}/build/libgmock.a" # googlemock output path
+
+export BIN_NAME="tpl-test"
+
+
+##### Build Google Test Framework #####
+mkdir ${GTEST_DIR}/build
+cd ${GTEST_DIR}/build
+cmake ../googlemock
+make
+
+##### Build tpl-test using libgtest.a ######
+cd ${BUILD_DIR}/tc/
+make
+
+
+%pre
+if [ "$1" -eq 1 ]; then
+echo "Initial installation"
+ # Perform tasks to prepare for the initial installation
+elif [ "$1" -eq 2 ]; then
+ # Perform whatever maintenance must occur before the upgrade begins
+rm -rf /opt/usr/tpl-test
+fi
+
+
+%install
+##### Install Binary #####
+mkdir -p %{buildroot}/opt/usr/tpl-test
+cp -arp ./tc/tpl-test %{buildroot}/opt/usr/tpl-test
+
+##### Licenses #####
+mkdir -p %{buildroot}/%{TZ_SYS_RO_SHARE}/license
+# MIT
+cp -a %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/%{TZ_SYS_RO_SHARE}/license/%{name}
+# BSD-3-Clause
+cp -a %{_builddir}/%{buildsubdir}/tc/libs/gtest/googletest/LICENSE %{buildroot}/%{TZ_SYS_RO_SHARE}/license/googletest
+
+
+%post
+/opt/usr/tpl-test/tpl-test --gtest_filter=TPL*
+if [ "$?" -eq 0 ]; then
+echo "Verification of libtpl-egl has been successfully done."
+else
+echo "Verification of libtpl-egl has been failed."
+fi
+
+
+%clean
+rm -rf %{buildroot}
+
+
+%files
+%defattr(-,root,root,-)
+##### Binary Files #####
+%dir /opt/usr/tpl-test/
+/opt/usr/tpl-test/*
+
+##### Licenses ######
+# MIT
+%{TZ_SYS_RO_SHARE}/license/%{name}
+# BSD-3-Clause
+%{TZ_SYS_RO_SHARE}/license/googletest
--- /dev/null
+#######################################################
+##### Makefile to build tpl-test using libgtest.a #####
+#######################################################
+
+# Following variables will be exported from spec file
+#
+# GTEST_LIB_TEST
+# GTEST_LIB_MOCK
+# GTEST_INCLUDE
+# GTEST_FLAGS
+# BIN_NAME
+
+##### Libraries #####
+LD_FLAGS = -lm -lrt -lpthread -ltpl-egl -lwayland-client -lwayland-egl
+CPPFLAGS += -I./
+
+##### tpl-test srcs #####
+SRCS = $(wildcard src/*.cpp)
+SRCS += $(wildcard mocked/*.cpp)
+HEADERS = $(wildcard src/*.h)
+HEADERS += $(wildcard mocked/*.h)
+
+##### tpl-test test cases srcs #####
+TESTS = $(wildcard test/*.cpp)
+
+
+OBJS = $(SRCS:%.cpp=%.o) \
+ $(TESTS:%.cpp=%.o) \
+ $(NULL)
+
+all : $(BIN_NAME)
+
+clean :
+ rm -f $(BIN_NAME)
+
+%.o: %.cpp
+ $(CXX) -c -o $@ $< $(GTEST_INCLUDE) $(GTEST_FLAGS) $(CPPFLAGS) $(LD_FLAGS)
+
+$(BIN_NAME) : $(OBJS) $(GTEST_LIB_TEST) $(GTEST_LIB_MOCK)
+ $(CXX) -lpthread $^ -o $@ $(GTEST_FLAGS) $(CPPFLAGS) $(LD_FLAGS)
+
--- /dev/null
+tpl-test - Test module for testing libtpl-egl frontend APIs
+
+
+1. Build Instruction
+
+ - Build libtpl-egl
+ $ gbs build -A armv7l --spec=libtpl-egl.spec
+
+ - Build tpl-test:
+ $ gbs build -A armv7l --spec=tpl-test.spec
+
+ - Build all:
+ $ gbs build -A armv7l
+
+
+
+2. Install Instruction
+
+ 1) Install
+ $ rpm -ivh tpl-test-0.2.0-1.armv7l.rpm
+ (file name can be different with version change)
+
+ then tpl-test binary file will be installed on
+ /opt/usr/tpl-test
+
+
+ 2) Uninstall
+ $ rpm -e tpl-test
+
+
+
+3. Run Tests
+
+ 1) Run
+ $ cd /opt/usr/tpl-test
+ $ ./tpl-test
+
+
+ 2) Run with configuration
+ $ ./tpl-test --config.width=720 --config.height=1280 --config.depth=24
+
--- /dev/null
+/**
+ * @file main.cpp
+ * @brief TPL Test main entry point
+ *
+ * In main() function, test configurations are set from command line arguments.
+ * Then, all tests will be run.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include "gtest/gtest.h"
+#include "tpl-test_base.h"
+#include "tpl-test_wayland.h"
+
+void
+tpl_test_print_help()
+{
+ printf("\n\n=== How to setup test configurations ===\n\n");
+ printf("--config.width=WIDTH (default: 720)\n");
+ printf("--config.height=HEIGHT (default: 1280)\n");
+ printf("--config.depth=DEPTH (default: 24)\n");
+ printf("\n\n");
+}
+
+Config
+tpl_test_parse_arguments(int argc, char **argv)
+{
+ Config config;
+
+ // Default configurations
+ config.width = 720;
+ config.height = 1280;
+ config.depth = 24;
+
+ // Check option
+ int opt_width = 0;
+ int opt_height = 0;
+ int opt_depth = 0;
+
+ struct option longopts[] = {
+ {"help", no_argument, NULL, 'h'},
+ {"config.width", required_argument, &opt_width, 1},
+ {"config.height", required_argument, &opt_height, 1},
+ {"config.depth", optional_argument, &opt_depth, 1},
+ {NULL, 0, NULL, 0}
+ };
+
+ opterr = 0; // Disable argument error message
+
+ // Parse arguments
+ int opt;
+ do {
+ opt = getopt_long_only(argc, argv, "", longopts, NULL);
+
+ if (opt == 'h') {
+ tpl_test_print_help();
+ return config;
+ }
+ } while (opt != -1 && opt != '?');
+
+ // Set Config
+ if (opt_width == 1) {
+ printf("width set: %s\n", optarg);
+ config.width = atoi(optarg);
+ }
+ if (opt_height == 1) {
+ printf("height set: %s\n", optarg);
+ config.height = atoi(optarg);
+ }
+ if (opt_depth == 1) {
+ printf("depth set: %s\n", optarg);
+ config.depth = atoi(optarg);
+ }
+
+ return config;
+}
+
+
+int
+main(int argc, char **argv)
+{
+ // Setup configurations
+ TPLTestBase::config = tpl_test_parse_arguments(argc, argv);
+
+ // Initialize backend
+ TPLTestBase::backend = new TPLWayland();
+
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+
--- /dev/null
+/**
+ * @file tpl-test_base.cpp
+ * @brief TPLTestBase class functions are defined in this file
+ */
+
+#include "tpl-test_base.h"
+
+
+TPLBackendBase *TPLTestBase::backend = (TPLBackendBase *)NULL;
+Config TPLTestBase::config;
+
+
+void
+TPLTestBase::SetUpTestCase()
+{
+ backend->tpl_backend_initialize(&config);
+}
+
+
+void
+TPLTestBase::TearDownTestCase()
+{
+ backend->tpl_backend_finalize(&config);
+}
+
--- /dev/null
+#ifndef TPL_TEST_BASE_H
+#define TPL_TEST_BASE_H
+
+/**
+ * @file tpl-test_base.h
+ * @brief TPLBackendBase class and TPLTestBase class declared in this file
+ *
+ */
+
+
+#include <wayland-client.h>
+#include <wayland-egl.h>
+#include <wayland-cursor.h>
+
+#include <gbm.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <tpl.h>
+#ifdef __cplusplus
+}
+#endif
+
+#include "gtest/gtest.h"
+
+/**
+ * A structure for test configurations
+ */
+typedef struct {
+ int width;
+ int height;
+ int depth;
+} Config;
+
+
+/**
+ * A base class containing struct for tpl APIs.
+ *
+ * Member variables in this class are used as argument of tpl APIs.
+ * However, these variables are initialized in different ways up to backends.
+ * Therefore, this class must be inherited and init and fini functions must be
+ * fulfilled with backend implementation.
+ */
+class TPLBackendBase {
+public:
+ tpl_display_t *tpl_display;
+ tpl_surface_t *tpl_surface;
+
+ tpl_handle_t display_handle;
+ tpl_handle_t surface_handle;
+
+ virtual void tpl_backend_initialize(Config *config) = 0;
+ virtual void tpl_backend_finalize(Config *config) = 0;
+};
+
+
+/**
+ * A base class which sets up and controls tests belongs to test case.
+ */
+class TPLTestBase : public testing::Test {
+public:
+ static TPLBackendBase *backend;
+ static Config config;
+
+protected:
+ // Called before first test in test case
+ // Calls backend initialize function
+ static void SetUpTestCase();
+
+ // Called before every test
+ virtual void SetUp() { /* */ };
+
+ // Called after every test
+ virtual void TearDown() { /* */ };
+
+ // Called after last test in test case
+ // Calls backend finalize function
+ static void TearDownTestCase();
+};
+
+
+#endif
--- /dev/null
+/**
+ * @file tpl-test_wayland.cpp
+ * @brief TPL Wayland Backend class functions are defined in this file
+ *
+ */
+
+#include "gtest/gtest.h"
+
+#include "tpl-test_wayland.h"
+
+// Wayland related
+static void
+registry_handle_global(void *data, struct wl_registry *registry, uint32_t name,
+ const char *interface, uint32_t version)
+{
+ struct Display *d = (struct Display *) data;
+
+ if (strcmp(interface, "wl_compositor") == 0) {
+ d->compositor = (struct wl_compositor *) wl_registry_bind(registry,
+ name, &wl_compositor_interface, 1);
+ }
+ if (strcmp(interface, "wl_shell") == 0) {
+ d->shell = (struct wl_shell *) wl_registry_bind(registry, name,
+ &wl_shell_interface, 1);
+ }
+}
+
+static void
+registry_handle_global_remove(void *data, struct wl_registry *registry,
+ uint32_t name)
+{
+}
+
+static const struct wl_registry_listener registry_listener = {
+ registry_handle_global,
+ registry_handle_global_remove
+};
+
+
+static void
+shell_ping(void *data, struct wl_shell_surface *shell_surface,
+ uint32_t serial)
+{
+ wl_shell_surface_pong(shell_surface, serial);
+}
+
+static void
+shell_configure(void *data, struct wl_shell_surface *shell_surface,
+ uint32_t edges, int32_t width, int32_t height)
+{
+}
+
+static void
+shell_popup_done(void *data, struct wl_shell_surface *shell_surface)
+{
+}
+
+static const struct wl_shell_surface_listener shell_surface_listener = {
+ shell_ping,
+ shell_configure,
+ shell_popup_done
+};
+
+
+void
+TPLWayland::tpl_backend_initialize(Config *config)
+{
+ wl_disp.display = wl_display_connect(NULL);
+ wl_disp.registry = wl_display_get_registry(wl_disp.display);
+
+ wl_registry_add_listener(wl_disp.registry, ®istry_listener, &wl_disp);
+
+ wl_display_roundtrip(wl_disp.display);
+
+ wl_win.surface = wl_compositor_create_surface(wl_disp.compositor);
+ wl_win.shell_surface =
+ wl_shell_get_shell_surface(wl_disp.shell, wl_win.surface);
+
+ wl_shell_surface_add_listener(wl_win.shell_surface,
+ &shell_surface_listener, &wl_win);
+ wl_shell_surface_set_title(wl_win.shell_surface, "TPL Test");
+ wl_shell_surface_set_toplevel(wl_win.shell_surface);
+
+ wl_win.native = wl_egl_window_create(wl_win.surface, config->width,
+ config->height);
+
+ tpl_display = tpl_display_create(TPL_BACKEND_WAYLAND,
+ (tpl_handle_t)wl_disp.display);
+
+ tpl_surface = tpl_surface_create(tpl_display, (tpl_handle_t)wl_win.native,
+ TPL_SURFACE_TYPE_WINDOW, TBM_FORMAT_ARGB8888);
+
+ display_handle = (tpl_handle_t) wl_disp.display;
+ surface_handle = (tpl_handle_t) wl_win.native;
+}
+
+void
+TPLWayland::tpl_backend_finalize(Config *config)
+{
+ if (tpl_surface != NULL)
+ tpl_object_unreference((tpl_object_t *) tpl_surface);
+ if (tpl_display != NULL)
+ tpl_object_unreference((tpl_object_t *) tpl_display);
+
+ wl_egl_window_destroy(wl_win.native);
+ if (wl_win.shell_surface)
+ wl_shell_surface_destroy(wl_win.shell_surface);
+ if (wl_win.surface)
+ wl_surface_destroy(wl_win.surface);
+ if (wl_disp.shell)
+ wl_shell_destroy(wl_disp.shell);
+ if (wl_disp.compositor)
+ wl_compositor_destroy(wl_disp.compositor);
+
+ wl_registry_destroy(wl_disp.registry);
+ wl_display_flush(wl_disp.display);
+ wl_display_disconnect(wl_disp.display);
+}
+
--- /dev/null
+#ifndef TPL_TEST_WAYLAND_H
+#define TPL_TEST_WAYLAND_H
+
+/**
+ * @file tpl-test_wayland.h
+ * @brief TPL Wayland Backend class declared in this file
+ *
+ */
+
+#include "gtest/gtest.h"
+
+#include "tpl-test_base.h"
+
+
+struct Display {
+ struct wl_display *display;
+ struct wl_registry *registry;
+ struct wl_compositor *compositor;
+ struct wl_shell *shell;
+};
+
+struct Window {
+ struct Display *display;
+ struct wl_egl_window *native;
+ struct wl_surface *surface;
+ struct wl_shell_surface *shell_surface;
+};
+
+
+class TPLWayland : public TPLBackendBase {
+public:
+ void tpl_backend_initialize(Config *config);
+ void tpl_backend_finalize(Config *config);
+
+private:
+ struct Display wl_disp;
+ struct Window wl_win;
+};
+
+
+#endif
--- /dev/null
+/**
+ * @file tpl-test_sample_test.cpp
+ * @brief TPL Test Sample test cases
+ *
+ */
+
+#include "gtest/gtest.h"
+
+#include "src/tpl-test_base.h"
+
+// Declare test case with the name as TestCaseName
+// Remove 'DISABLED_' to run this test case
+class DISABLED_TestCaseName : public TPLTestBase {};
+
+// Declare test with declared TestCaseName and TestName
+// Remove 'DISABLED_' to run this test
+TEST_F(DISABLED_TestCaseName, TestName)
+{
+ int answer = 1;
+ ASSERT_EQ(answer, 2 - 1);
+}
+