You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opendal.apache.org by xu...@apache.org on 2023/03/17 07:43:33 UTC
[incubator-opendal] branch main updated: feat(tests): Introducing BDD tests for all bindings (#1654)
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 9b77d960 feat(tests): Introducing BDD tests for all bindings (#1654)
9b77d960 is described below
commit 9b77d9608ea333383b4a962d75c8ef313f82e372
Author: Xuanwo <gi...@xuanwo.io>
AuthorDate: Fri Mar 17 15:43:28 2023 +0800
feat(tests): Introducing BDD tests for all bindings (#1654)
* feat(tests): Introducing BDD tests for all bindings
Signed-off-by: Xuanwo <gi...@xuanwo.io>
* Address comments
Signed-off-by: Xuanwo <gi...@xuanwo.io>
---------
Signed-off-by: Xuanwo <gi...@xuanwo.io>
---
.github/workflows/bindings_python.yml | 4 +-
bindings/python/README.md | 2 +-
bindings/python/pyproject.toml | 2 +-
bindings/python/tests/binding.feature | 1 +
bindings/python/tests/steps/binding.py | 78 ++++++++++++++++++++++
bindings/python/tests/test_core.py | 114 --------------------------------
bindings/tests/README.md | 3 +
bindings/tests/features/binding.feature | 34 ++++++++++
licenserc.toml | 1 +
9 files changed, 121 insertions(+), 118 deletions(-)
diff --git a/.github/workflows/bindings_python.yml b/.github/workflows/bindings_python.yml
index 610cea3a..c75197fb 100644
--- a/.github/workflows/bindings_python.yml
+++ b/.github/workflows/bindings_python.yml
@@ -51,10 +51,10 @@ jobs:
working-directory: "bindings/python"
run: |
python -m pip install -e .[test]
- - name: Run pytest
+ - name: Run behave
working-directory: "bindings/python"
run: |
- python -m pytest
+ python -m behave tests
linux:
runs-on: ubuntu-latest
diff --git a/bindings/python/README.md b/bindings/python/README.md
index 473668e4..03a4bcb1 100644
--- a/bindings/python/README.md
+++ b/bindings/python/README.md
@@ -62,5 +62,5 @@ Running some tests:
```shell
maturin develop -E test
-pytest
+behave tests
```
diff --git a/bindings/python/pyproject.toml b/bindings/python/pyproject.toml
index 356b6f63..052b9187 100644
--- a/bindings/python/pyproject.toml
+++ b/bindings/python/pyproject.toml
@@ -32,7 +32,7 @@ readme = "README.md"
requires-python = ">=3.7"
[project.optional-dependencies]
-test = ["pytest", "pytest-asyncio"]
+test = ["behave"]
[project.urls]
Documentation = "https://docs.rs/opendal/"
diff --git a/bindings/python/tests/binding.feature b/bindings/python/tests/binding.feature
new file mode 120000
index 00000000..fcb71d38
--- /dev/null
+++ b/bindings/python/tests/binding.feature
@@ -0,0 +1 @@
+../../tests/features/binding.feature
\ No newline at end of file
diff --git a/bindings/python/tests/steps/binding.py b/bindings/python/tests/steps/binding.py
new file mode 100644
index 00000000..49aa45a9
--- /dev/null
+++ b/bindings/python/tests/steps/binding.py
@@ -0,0 +1,78 @@
+# 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.
+
+from behave import given, when, then
+from behave.api.async_step import async_run_until_complete
+import opendal
+
+@given('A new OpenDAL Blocking Operator')
+def step_impl(context):
+ context.op = opendal.Operator("memory")
+
+@when('Blocking write path "{filename}" with content "{content}"')
+def step_impl(context, filename, content):
+ context.op.write(filename, content.encode())
+
+@then('The blocking file "{filename}" should exist')
+def step_impl(context, filename):
+ context.op.stat(filename)
+
+@then('The blocking file "{filename}" entry mode must be file')
+def step_impl(context, filename):
+ assert context.op.stat(filename).mode.is_file()
+
+@then('The blocking file "{filename}" content length must be "{size:d}"')
+def step_impl(context, filename, size):
+ assert context.op.stat(filename).content_length == size
+
+@then('The blocking file "{filename}" must have content "{content}"')
+def step_impl(context, filename, content):
+ bs = context.op.read(filename)
+ assert bs == content.encode()
+
+@given('A new OpenDAL Async Operator')
+@async_run_until_complete
+async def step_impl(context):
+ context.op = opendal.AsyncOperator("memory")
+
+@when('Async write path "{filename}" with content "{content}"')
+@async_run_until_complete
+async def step_impl(context, filename, content):
+ await context.op.write(filename, content.encode())
+
+@then('The async file "{filename}" should exist')
+@async_run_until_complete
+async def step_impl(context, filename):
+ await context.op.stat(filename)
+
+@then('The async file "{filename}" entry mode must be file')
+@async_run_until_complete
+async def step_impl(context, filename):
+ meta = await context.op.stat(filename)
+ assert meta.mode.is_file()
+
+@then('The async file "{filename}" content length must be "{size:d}"')
+@async_run_until_complete
+async def step_impl(context, filename, size):
+ meta = await context.op.stat(filename)
+ assert meta.content_length == size
+
+@then('The async file "{filename}" must have content "{content}"')
+@async_run_until_complete
+async def step_impl(context, filename, content):
+ bs = await context.op.read(filename)
+ assert bs == content.encode()
diff --git a/bindings/python/tests/test_core.py b/bindings/python/tests/test_core.py
deleted file mode 100644
index 6322e26a..00000000
--- a/bindings/python/tests/test_core.py
+++ /dev/null
@@ -1,114 +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.
-
-import os
-import opendal
-import pytest
-from opendal import layers
-
-
-def test_blocking():
- op = opendal.Operator("memory", layers=[layers.RetryLayer()])
- op.write("test", b"Hello, World!")
- bs = op.read("test")
- assert bs == b"Hello, World!", bs
- meta = op.stat("test")
- assert meta.content_length == 13, meta.content_length
- assert meta.mode.is_file()
- assert [str(entry) for entry in op.list("/")] == ["test"]
- assert [str(entry) for entry in op.scan("/")] == ["test"]
-
- reader = op.open_reader("test")
- bs = reader.read(5)
- assert bs == b"Hello", bs
- bs = reader.read()
- assert bs == b", World!", bs
- reader.seek(0, os.SEEK_SET)
- bs = reader.read()
- assert bs == b"Hello, World!", bs
- with op.open_reader("test") as f:
- bs = f.read()
- assert bs == b"Hello, World!", bs
-
- op.delete("test")
-
- op.create_dir("test/")
-
-
-@pytest.mark.asyncio
-async def test_async():
- op = opendal.AsyncOperator(
- "memory", layers=[layers.RetryLayer(), layers.ConcurrentLimitLayer(10)]
- )
- await op.write("test", b"Hello, World!")
- bs = await op.read("test")
- assert bs == b"Hello, World!", bs
- meta = await op.stat("test")
- assert meta.content_length == 13, meta.content_length
- assert meta.mode.is_file()
- assert [str(entry) async for entry in await op.list("/")] == ["test"]
- assert [str(entry) async for entry in await op.scan("/")] == ["test"]
-
- reader = op.open_reader("test")
- bs = await reader.read(5)
- assert bs == b"Hello", bs
- bs = await reader.read()
- assert bs == b", World!", bs
- await reader.seek(0, os.SEEK_SET)
- bs = await reader.read()
- assert bs == b"Hello, World!", bs
- async with op.open_reader("test") as f:
- bs = await f.read()
- assert bs == b"Hello, World!", bs
-
- await op.delete("test")
-
- await op.create_dir("test/")
-
-
-def test_blocking_fs(tmp_path):
- op = opendal.Operator("fs", root=str(tmp_path))
- op.write("test.txt", b"Hello, World!")
- bs = op.read("test.txt")
- assert bs == b"Hello, World!", bs
- meta = op.stat("test.txt")
- assert meta.content_length == 13, meta.content_length
- assert [str(entry) for entry in op.list("/")] == ["test.txt"]
- assert [str(entry) for entry in op.scan("/")] == ["test.txt", "/"]
-
- op.create_dir("test/")
-
-
-@pytest.mark.asyncio
-async def test_async_fs(tmp_path):
- op = opendal.AsyncOperator("fs", root=str(tmp_path))
- await op.write("test.txt", b"Hello, World!")
- bs = await op.read("test.txt")
- assert bs == b"Hello, World!", bs
- meta = await op.stat("test.txt")
- assert meta.content_length == 13, meta.content_length
-
- await op.create_dir("test/")
-
-
-def test_error():
- op = opendal.Operator("memory")
- with pytest.raises(FileNotFoundError):
- op.read("test")
-
- with pytest.raises(NotImplementedError):
- opendal.Operator("foobar")
diff --git a/bindings/tests/README.md b/bindings/tests/README.md
new file mode 100644
index 00000000..5c49d3f6
--- /dev/null
+++ b/bindings/tests/README.md
@@ -0,0 +1,3 @@
+# OpenDAL Binding Tests
+
+OpenDAL will use [Cucumber](https://github.com/cucumber) for [BDD](Behaviour-Driven Development) tests. This module will provide [Gherkin](https://cucumber.io/docs/gherkin/) files and all bindings should implement againest them.
diff --git a/bindings/tests/features/binding.feature b/bindings/tests/features/binding.feature
new file mode 100644
index 00000000..22c08ab1
--- /dev/null
+++ b/bindings/tests/features/binding.feature
@@ -0,0 +1,34 @@
+# 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.
+
+Feature: OpenDAL Binding
+
+ Scenario: OpenDAL Blocking Operations
+ Given A new OpenDAL Blocking Operator
+ When Blocking write path "test" with content "Hello, World!"
+ Then The blocking file "test" should exist
+ Then The blocking file "test" entry mode must be file
+ Then The blocking file "test" content length must be "13"
+ Then The blocking file "test" must have content "Hello, World!"
+
+ Scenario: OpenDAL Async Operations
+ Given A new OpenDAL Async Operator
+ When Async write path "test" with content "Hello, World!"
+ Then The async file "test" should exist
+ Then The async file "test" entry mode must be file
+ Then The async file "test" content length must be "13"
+ Then The async file "test" must have content "Hello, World!"
diff --git a/licenserc.toml b/licenserc.toml
index 645fbf31..d4a7f6c3 100644
--- a/licenserc.toml
+++ b/licenserc.toml
@@ -36,6 +36,7 @@ excludes = [
"bindings/python/opendal.pyi",
"**/__pycache__",
"**/.pytest_cache",
+ "**/venv/**",
"website/build/**",
"website/static/.nojekyll",
"website/.docusaurus",