This is an automated email from the ASF dual-hosted git repository.
xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git
The following commit(s) were added to refs/heads/main by this push:
new 5d890603 feat(bindings/C): support BDD tests using GTest (#2254)
5d890603 is described below
commit 5d890603a48b1f51c85012fcd22388643d860104
Author: xyJi <[email protected]>
AuthorDate: Thu May 11 20:56:18 2023 +0800
feat(bindings/C): support BDD tests using GTest (#2254)
* basic framework for BDD tests in Gtest
Signed-off-by: Ji-Xinyou <[email protected]>
* remove basicio.c, replace with bdd test equivalent GTest
Signed-off-by: Ji-Xinyou <[email protected]>
* some comments
Signed-off-by: Ji-Xinyou <[email protected]>
* makefile minor change
Signed-off-by: Ji-Xinyou <[email protected]>
* header
Signed-off-by: Ji-Xinyou <[email protected]>
* remove gtest headers
Signed-off-by: Ji-Xinyou <[email protected]>
* minor
Signed-off-by: Ji-Xinyou <[email protected]>
* minor
Signed-off-by: Ji-Xinyou <[email protected]>
* header
Signed-off-by: Ji-Xinyou <[email protected]>
* gha
Signed-off-by: Ji-Xinyou <[email protected]>
* gha
Signed-off-by: Ji-Xinyou <[email protected]>
* manually setup c/cpp
Signed-off-by: Ji-Xinyou <[email protected]>
* run test and fix build
Signed-off-by: Ji-Xinyou <[email protected]>
* remove cpp setup, run test on make test
Signed-off-by: Ji-Xinyou <[email protected]>
* minor
Signed-off-by: Ji-Xinyou <[email protected]>
---------
Signed-off-by: Ji-Xinyou <[email protected]>
---
.github/workflows/bindings_c.yml | 63 ++++++++++++++++++++
bindings/c/Makefile | 9 +--
bindings/c/tests/basicio.c | 89 ----------------------------
bindings/c/tests/bdd.cpp | 122 +++++++++++++++++++++++++++++++++++++++
4 files changed, 190 insertions(+), 93 deletions(-)
diff --git a/.github/workflows/bindings_c.yml b/.github/workflows/bindings_c.yml
new file mode 100644
index 00000000..3c6f725f
--- /dev/null
+++ b/.github/workflows/bindings_c.yml
@@ -0,0 +1,63 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+name: Bindings C CI
+
+on:
+ push:
+ branches:
+ - main
+ tags:
+ - '*'
+ pull_request:
+ branches:
+ - main
+ paths:
+ - "bindings/c/**"
+ - ".github/workflows/bindings_c.yml"
+ workflow_dispatch:
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
+ cancel-in-progress: true
+
+permissions:
+ contents: read
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Install gtest manually
+ run: |
+ sudo apt-get install libgtest-dev
+ cd /usr/src/gtest
+ sudo cmake CMakeLists.txt
+ sudo make
+ sudo cp lib/*.a /usr/lib
+ sudo ln -s /usr/lib/libgtest.a /usr/local/lib/libgtest.a
+ sudo ln -s /usr/lib/libgtest_main.a /usr/local/lib/libgtest_main.a
+ - name: Setup Rust toolchain
+ uses: ./.github/actions/setup
+ - name: Build C binding
+ working-directory: "bindings/c"
+ run: make build
+ - name: Build and Run BDD tests
+ working-directory: "bindings/c"
+ run: make test
+
diff --git a/bindings/c/Makefile b/bindings/c/Makefile
index 870da02b..a98899cb 100644
--- a/bindings/c/Makefile
+++ b/bindings/c/Makefile
@@ -16,9 +16,9 @@
# under the License.
RPATH=$(PWD)/../../target/debug
-CFLAGS=-I./include
+CXXFLAGS=-I./include -std=c++14
LDFLAGS=-L$(RPATH) -Wl,-rpath,$(RPATH)
-LIBS=-lopendal_c
+LIBS=-lopendal_c -lgtest
OBJ_DIR=./build
.PHONY: all
@@ -26,7 +26,7 @@ all: build test
.PHONY: format
format:
- find . -name '*.c' -exec clang-format -i --style=WebKit --verbose {} \;
+ find . -name '*.cpp' -exec clang-format -i --style=WebKit --verbose {}
\;
.PHONY: build
build:
@@ -35,7 +35,8 @@ build:
.PHONY: test
test:
- $(CC) tests/basicio.c -o $(OBJ_DIR)/basicio $(CFLAGS) $(LDFLAGS) $(LIBS)
+ $(CXX) tests/bdd.cpp -o $(OBJ_DIR)/bdd $(CXXFLAGS) $(LDFLAGS) $(LIBS)
+ $(OBJ_DIR)/bdd
.PHONY: clean
clean:
diff --git a/bindings/c/tests/basicio.c b/bindings/c/tests/basicio.c
deleted file mode 100644
index 36524594..00000000
--- a/bindings/c/tests/basicio.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 "assert.h"
-#include "opendal.h"
-#include "stdio.h"
-
-// Tests the basic IO operations work as expected
-//
-// Asserts:
-// * A valid ptr is given
-// * The blocking write operation is successful
-// * The blocking read operation is successful and works as expected
-void test_operator_rw(opendal_operator_ptr ptr, char* path)
-{
- // have to be valid ptr
- assert(ptr);
-
- // write some contents by the operator, must be successful
- char content[] = "Hello World";
- const opendal_bytes data = {
- .len = sizeof(content) - 1,
- .data = (uint8_t*)content,
- };
- opendal_code code = opendal_operator_blocking_write(ptr, path, data);
- assert(code == OPENDAL_OK);
-
- // reads the data out from the bytes, must be successful
- struct opendal_result_read r = opendal_operator_blocking_read(ptr, path);
- assert(r.code == OPENDAL_OK);
- assert(r.data->len == (sizeof(content) - 1));
-
- for (int i = 0; i < r.data->len; i++) {
- printf("%c", (char)(r.data->data[i]));
- }
-
- // free the bytes's heap memory
- opendal_bytes_free(r.data);
-}
-
-void test_operator_stat(opendal_operator_ptr ptr, char* path)
-{
- assert(ptr);
- opendal_result_stat r = opendal_operator_stat(ptr, path);
- assert(r.code == OPENDAL_OK);
-
- opendal_metadata meta = r.meta;
- assert(meta);
-
- assert(opendal_metadata_is_file(&meta));
-
- uint64_t content_length = opendal_metadata_content_length(&meta);
- assert(content_length == 11);
-
- opendal_metadata_free(&meta);
-}
-
-int main(int argc, char* argv[])
-{
- // construct the memory operator
- char scheme1[] = "memory";
- char path[] = "test";
- opendal_operator_ptr p1 = opendal_operator_new(scheme1);
- assert(p1);
-
- test_operator_rw(p1, path);
- test_operator_stat(p1, path);
-
- // free the operator
- opendal_operator_free(&p1);
-
- return 0;
-}
diff --git a/bindings/c/tests/bdd.cpp b/bindings/c/tests/bdd.cpp
new file mode 100644
index 00000000..27bcea54
--- /dev/null
+++ b/bindings/c/tests/bdd.cpp
@@ -0,0 +1,122 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 "gtest/gtest.h"
+
+extern "C" {
+#include "opendal.h"
+}
+
+class OpendalBddTest : public ::testing::Test {
+protected:
+ // Setup code for the fixture
+ opendal_operator_ptr p;
+ std::string scheme;
+ std::string path;
+ std::string content;
+
+ // the fixture setup is an operator write, which will be
+ // run at the beginning of every tests
+ void SetUp() override
+ {
+ // construct the memory operator
+ this->scheme = std::string("memory");
+ this->path = std::string("test");
+ this->content = std::string("Hello, World!");
+
+ this->p = opendal_operator_new(scheme.c_str());
+
+ EXPECT_TRUE(this->p);
+
+ const opendal_bytes data = {
+ .data = (uint8_t*)this->content.c_str(),
+ .len = this->content.length(),
+ };
+
+ opendal_code code = opendal_operator_blocking_write(this->p,
this->path.c_str(), data);
+
+ EXPECT_EQ(code, OPENDAL_OK);
+ }
+
+ // Teardown code for the fixture, free the operator
+ void TearDown() override
+ {
+ opendal_operator_free(&this->p);
+ }
+};
+
+// do nothing, the fixture does the Write Test
+TEST_F(OpendalBddTest, Write)
+{
+}
+
+// The path must exist
+TEST_F(OpendalBddTest, Exist)
+{
+ opendal_result_is_exist r = opendal_operator_is_exist(this->p,
this->path.c_str());
+
+ EXPECT_EQ(r.code, OPENDAL_OK);
+ EXPECT_TRUE(r.is_exist);
+}
+
+// The entry mode must be file
+TEST_F(OpendalBddTest, EntryMode)
+{
+ opendal_result_stat r = opendal_operator_stat(this->p, this->path.c_str());
+ EXPECT_EQ(r.code, OPENDAL_OK);
+
+ opendal_metadata meta = r.meta;
+ EXPECT_TRUE(opendal_metadata_is_file(&meta));
+
+ opendal_metadata_free(&meta);
+}
+
+// The content length must be consistent
+TEST_F(OpendalBddTest, ContentLength)
+{
+ opendal_result_stat r = opendal_operator_stat(this->p, this->path.c_str());
+ EXPECT_EQ(r.code, OPENDAL_OK);
+
+ opendal_metadata meta = r.meta;
+ EXPECT_EQ(opendal_metadata_content_length(&meta), 13);
+
+ opendal_metadata_free(&meta);
+}
+
+// We must read the correct content
+TEST_F(OpendalBddTest, Read)
+{
+ struct opendal_result_read r = opendal_operator_blocking_read(this->p,
this->path.c_str());
+
+ EXPECT_EQ(r.code, OPENDAL_OK);
+ EXPECT_EQ(r.data->len, this->content.length());
+
+ for (int i = 0; i < r.data->len; i++) {
+ EXPECT_EQ(this->content[i], (char)(r.data->data[i]));
+ }
+
+ // free the bytes's heap memory
+ opendal_bytes_free(r.data);
+}
+
+int main(int argc, char** argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}